2025-10-27 21:33:38 +01:00
|
|
|
class Draggable {
|
|
|
|
|
constructor(element) {
|
|
|
|
|
this.element = element;
|
|
|
|
|
this.offsetX = 0;
|
|
|
|
|
this.offsetY = 0;
|
|
|
|
|
this.isDragging = false;
|
|
|
|
|
this.barSize = '';
|
|
|
|
|
|
|
|
|
|
this.init();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
init() {
|
|
|
|
|
this.element.addEventListener('mousedown', this.onMouseDown.bind(this));
|
|
|
|
|
document.addEventListener('mousemove', this.onMouseMove.bind(this));
|
|
|
|
|
document.addEventListener('mouseup', this.onMouseUp.bind(this));
|
|
|
|
|
this.setPosition('bottom');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMouseDown(event) {
|
|
|
|
|
this.isDragging = true;
|
|
|
|
|
this.offsetX = event.clientX - this.element.getBoundingClientRect().left;
|
|
|
|
|
this.offsetY = event.clientY - this.element.getBoundingClientRect().top;
|
|
|
|
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMouseMove(event) {
|
|
|
|
|
if (!this.isDragging) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let x = event.clientX - this.offsetX;
|
|
|
|
|
let y = event.clientY - this.offsetY;
|
|
|
|
|
|
|
|
|
|
// Update the position of the element
|
|
|
|
|
this.element.style.left = `${x}px`;
|
|
|
|
|
this.element.style.top = `${y}px`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMouseUp() {
|
|
|
|
|
if (!this.isDragging) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
this.isDragging = false;
|
|
|
|
|
|
|
|
|
|
this.snapToEdges();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
snapToEdges() {
|
|
|
|
|
const rect = this.element.getBoundingClientRect();
|
|
|
|
|
const windowWidth = window.innerWidth;
|
|
|
|
|
const windowHeight = window.innerHeight;
|
|
|
|
|
|
|
|
|
|
// Determine the closest edge
|
|
|
|
|
const distances = {
|
|
|
|
|
left: rect.left,
|
|
|
|
|
right: windowWidth - rect.right,
|
|
|
|
|
top: rect.top,
|
|
|
|
|
bottom: windowHeight - rect.bottom
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const closestEdge = Object.keys(distances).reduce((a, b) => distances[a] < distances[b] ? a : b);
|
|
|
|
|
|
2025-10-27 23:24:02 +01:00
|
|
|
/*switch (closestEdge) {
|
|
|
|
|
case 'left':
|
|
|
|
|
this.element.style.left = '0px';
|
|
|
|
|
this.element.style.top = `${rect.top}px`;
|
|
|
|
|
break;
|
|
|
|
|
case 'right':
|
|
|
|
|
this.element.style.left = `${windowWidth - rect.width}px`;
|
|
|
|
|
this.element.style.top = `${rect.top}px`;
|
|
|
|
|
break;
|
|
|
|
|
case 'top':
|
|
|
|
|
this.element.style.top = '0px';
|
|
|
|
|
this.element.style.left = `${rect.left}px`;
|
|
|
|
|
break;
|
|
|
|
|
case 'bottom':
|
|
|
|
|
this.element.style.top = `${windowHeight - rect.height}px`;
|
|
|
|
|
this.element.style.left = `${rect.left}px`;
|
|
|
|
|
break;
|
|
|
|
|
}*/
|
2025-10-27 21:33:38 +01:00
|
|
|
this.setPosition(closestEdge, this.barSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setPosition(side, barSize) {
|
|
|
|
|
switch (side) {
|
|
|
|
|
case 'left':
|
|
|
|
|
// this.element.style.top = `${rect.top}px`; // Optional: keep vertical position
|
|
|
|
|
this.element.style.top = '0px';
|
|
|
|
|
this.element.style.right = '';
|
|
|
|
|
this.element.style.bottom = '0px';
|
|
|
|
|
this.element.style.left = '0px';
|
|
|
|
|
this.element.style.width = barSize;
|
|
|
|
|
this.element.style.height = '';
|
|
|
|
|
break;
|
|
|
|
|
case 'right':
|
|
|
|
|
// this.element.style.left = `${windowWidth - rect.width}px`;
|
|
|
|
|
// this.element.style.top = `${rect.top}px`; // Optional: keep vertical position
|
|
|
|
|
this.element.style.top = '0px';
|
|
|
|
|
this.element.style.right = '0px';
|
|
|
|
|
this.element.style.bottom = '0px';
|
|
|
|
|
this.element.style.left = '';
|
|
|
|
|
this.element.style.width = barSize;
|
|
|
|
|
this.element.style.height = '';
|
|
|
|
|
break;
|
|
|
|
|
case 'top':
|
|
|
|
|
// this.element.style.top = '0px';
|
|
|
|
|
// this.element.style.left = `${rect.left}px`; // Optional: keep horizontal position
|
|
|
|
|
this.element.style.top = '0px';
|
|
|
|
|
this.element.style.right = '0px';
|
|
|
|
|
this.element.style.bottom = '';
|
|
|
|
|
this.element.style.left = '0px';
|
|
|
|
|
this.element.style.width = '';
|
|
|
|
|
this.element.style.height = barSize;
|
|
|
|
|
break;
|
|
|
|
|
case 'bottom':
|
|
|
|
|
// this.element.style.top = `${windowHeight - rect.height}px`;
|
|
|
|
|
// this.element.style.left = `${rect.left}px`; // Optional: keep horizontal position
|
|
|
|
|
this.element.style.top = '';
|
|
|
|
|
this.element.style.right = '0px';
|
|
|
|
|
this.element.style.bottom = '0px';
|
|
|
|
|
this.element.style.left = '0px';
|
|
|
|
|
this.element.style.width = '';
|
|
|
|
|
this.element.style.height = barSize;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class DragAdv {
|
|
|
|
|
constructor(element, placeholder) {
|
|
|
|
|
this.element = element;
|
|
|
|
|
this.placeholder = placeholder;
|
|
|
|
|
this.offsetX = 0;
|
|
|
|
|
this.offsetY = 0;
|
|
|
|
|
this.isDragging = false;
|
|
|
|
|
this.barSize = '';
|
|
|
|
|
|
|
|
|
|
this.init();
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-31 19:47:19 +01:00
|
|
|
// TODO: Ereignisse besser delegieren
|
2025-10-27 21:33:38 +01:00
|
|
|
init() {
|
|
|
|
|
this.element.addEventListener('mousedown', this.onMouseDown.bind(this));
|
|
|
|
|
document.addEventListener('mousemove', this.onMouseMove.bind(this));
|
|
|
|
|
document.addEventListener('mouseup', this.onMouseUp.bind(this));
|
2025-10-27 21:53:57 +01:00
|
|
|
this.setPosition('bottom', this.barSize);
|
2025-10-27 21:33:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMouseDown(event) {
|
2025-10-31 19:47:19 +01:00
|
|
|
if (checkButtonAndTarget(event, this.element, 0)) {
|
|
|
|
|
console.debug('Drag mode enabled');
|
|
|
|
|
|
2025-10-27 23:24:02 +01:00
|
|
|
this.isDragging = true;
|
2025-10-27 21:33:38 +01:00
|
|
|
|
2025-10-31 19:47:19 +01:00
|
|
|
// TODO: Platzhalter anpassen je nach Ziel
|
2025-10-27 23:24:02 +01:00
|
|
|
this.showPlaceholder();
|
2025-10-27 21:53:57 +01:00
|
|
|
|
2025-10-27 23:24:02 +01:00
|
|
|
this.offsetX = this.placeholder.getBoundingClientRect().width / 2;
|
|
|
|
|
this.offsetY = this.placeholder.getBoundingClientRect().height / 2;
|
2025-10-27 21:53:57 +01:00
|
|
|
|
2025-10-27 23:24:02 +01:00
|
|
|
let x = event.clientX - this.offsetX;
|
|
|
|
|
let y = event.clientY - this.offsetY;
|
2025-10-27 21:53:57 +01:00
|
|
|
|
2025-10-27 23:24:02 +01:00
|
|
|
this.placeholder.style.left = `${x}px`;
|
|
|
|
|
this.placeholder.style.top = `${y}px`;
|
|
|
|
|
}
|
2025-10-27 21:53:57 +01:00
|
|
|
|
2025-10-27 21:33:38 +01:00
|
|
|
event.preventDefault();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMouseMove(event) {
|
2025-10-31 19:47:19 +01:00
|
|
|
if (this.isDragging) {
|
|
|
|
|
if (!this.isDragging) return;
|
2025-10-27 21:33:38 +01:00
|
|
|
|
2025-10-31 19:47:19 +01:00
|
|
|
let x = event.clientX - this.offsetX;
|
|
|
|
|
let y = event.clientY - this.offsetY;
|
|
|
|
|
|
|
|
|
|
console.debug('Position: ', x, y);
|
2025-10-27 21:33:38 +01:00
|
|
|
|
2025-10-31 19:47:19 +01:00
|
|
|
this.placeholder.style.left = `${x}px`;
|
|
|
|
|
this.placeholder.style.top = `${y}px`;
|
|
|
|
|
}
|
2025-10-27 21:33:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMouseUp() {
|
2025-10-31 19:47:19 +01:00
|
|
|
if (event.target === this.placeholder) {
|
|
|
|
|
console.debug('Drag mode disabled');
|
2025-10-27 21:33:38 +01:00
|
|
|
|
2025-10-31 19:47:19 +01:00
|
|
|
if (!this.isDragging) return;
|
|
|
|
|
this.isDragging = false;
|
|
|
|
|
|
|
|
|
|
this.snapToEdges();
|
|
|
|
|
this.hidePlaceholder();
|
|
|
|
|
}
|
2025-10-27 21:33:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
showPlaceholder() {
|
2025-10-27 23:24:02 +01:00
|
|
|
this.element.style.display = 'none';
|
2025-10-27 21:33:38 +01:00
|
|
|
this.placeholder.style.display = 'block';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hidePlaceholder() {
|
|
|
|
|
this.placeholder.style.display = 'none';
|
2025-10-27 23:24:02 +01:00
|
|
|
this.element.style.display = '';
|
2025-10-27 21:33:38 +01:00
|
|
|
}
|
|
|
|
|
|
2025-10-31 19:47:19 +01:00
|
|
|
// TODO: Prüfung auf Ziel auslagern und schon bei Mausbewegung verfügbar machen
|
2025-10-27 21:33:38 +01:00
|
|
|
snapToEdges() {
|
|
|
|
|
const rect = this.placeholder.getBoundingClientRect();
|
|
|
|
|
const windowWidth = window.innerWidth;
|
|
|
|
|
const windowHeight = window.innerHeight;
|
|
|
|
|
const distances = {
|
|
|
|
|
top: rect.top,
|
2025-11-02 09:18:12 +01:00
|
|
|
right: windowWidth - rect.right,
|
|
|
|
|
bottom: windowHeight - rect.bottom,
|
|
|
|
|
left: rect.left
|
2025-10-27 21:33:38 +01:00
|
|
|
};
|
|
|
|
|
const closestEdge = Object.keys(distances).reduce((a, b) => distances[a] < distances[b] ? a : b);
|
|
|
|
|
|
|
|
|
|
this.setPosition(closestEdge, this.barSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setPosition(side, barSize) {
|
|
|
|
|
switch (side) {
|
|
|
|
|
case 'left':
|
|
|
|
|
// this.element.style.top = `${rect.top}px`; // Optional: keep vertical position
|
|
|
|
|
this.element.style.top = '0px';
|
|
|
|
|
this.element.style.right = '';
|
|
|
|
|
this.element.style.bottom = '0px';
|
|
|
|
|
this.element.style.left = '0px';
|
|
|
|
|
this.element.style.width = barSize;
|
|
|
|
|
this.element.style.height = '';
|
|
|
|
|
break;
|
|
|
|
|
case 'right':
|
|
|
|
|
// this.element.style.left = `${windowWidth - rect.width}px`;
|
|
|
|
|
// this.element.style.top = `${rect.top}px`; // Optional: keep vertical position
|
|
|
|
|
this.element.style.top = '0px';
|
|
|
|
|
this.element.style.right = '0px';
|
|
|
|
|
this.element.style.bottom = '0px';
|
|
|
|
|
this.element.style.left = '';
|
|
|
|
|
this.element.style.width = barSize;
|
|
|
|
|
this.element.style.height = '';
|
|
|
|
|
break;
|
|
|
|
|
case 'top':
|
|
|
|
|
// this.element.style.top = '0px';
|
|
|
|
|
// this.element.style.left = `${rect.left}px`; // Optional: keep horizontal position
|
|
|
|
|
this.element.style.top = '0px';
|
|
|
|
|
this.element.style.right = '0px';
|
|
|
|
|
this.element.style.bottom = '';
|
|
|
|
|
this.element.style.left = '0px';
|
|
|
|
|
this.element.style.width = '';
|
|
|
|
|
this.element.style.height = barSize;
|
|
|
|
|
break;
|
|
|
|
|
case 'bottom':
|
|
|
|
|
// this.element.style.top = `${windowHeight - rect.height}px`;
|
|
|
|
|
// this.element.style.left = `${rect.left}px`; // Optional: keep horizontal position
|
|
|
|
|
this.element.style.top = '';
|
|
|
|
|
this.element.style.right = '0px';
|
|
|
|
|
this.element.style.bottom = '0px';
|
|
|
|
|
this.element.style.left = '0px';
|
|
|
|
|
this.element.style.width = '';
|
|
|
|
|
this.element.style.height = barSize;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class BestDrag {
|
|
|
|
|
#element;
|
|
|
|
|
|
|
|
|
|
constructor(element) {
|
|
|
|
|
this.#setElement(element);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#setElement(value) {
|
|
|
|
|
if (!value) {
|
|
|
|
|
throw new Error('No element found');
|
|
|
|
|
}
|
|
|
|
|
this.#element = value;
|
|
|
|
|
this.#element.style.background = "hotpink";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get element() {
|
|
|
|
|
return this.#element;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set element(value) {
|
|
|
|
|
this.#setElement(value);
|
|
|
|
|
}
|
|
|
|
|
}
|