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); 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(); } 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', this.barSize); } onMouseDown(event) { this.isDragging = true; this.showPlaceholder(); this.offsetX = this.placeholder.getBoundingClientRect().width / 2; this.offsetY = this.placeholder.getBoundingClientRect().height / 2; this.element.style.display = 'none'; let x = event.clientX - this.offsetX; let y = event.clientY - this.offsetY; this.placeholder.style.left = `${x}px`; this.placeholder.style.top = `${y}px`; event.preventDefault(); } onMouseMove(event) { if (!this.isDragging) return; let x = event.clientX - this.offsetX; let y = event.clientY - this.offsetY; this.placeholder.style.left = `${x}px`; this.placeholder.style.top = `${y}px`; } onMouseUp() { if (!this.isDragging) return; this.isDragging = false; this.element.style.display = 'block'; this.snapToEdges(); this.hidePlaceholder(); } showPlaceholder() { this.placeholder.style.display = 'block'; } hidePlaceholder() { this.placeholder.style.display = 'none'; } snapToEdges() { const rect = this.placeholder.getBoundingClientRect(); const windowWidth = window.innerWidth; const windowHeight = window.innerHeight; 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); console.log(rect); console.log(closestEdge); this.setPosition(closestEdge, this.barSize); /*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; }*/ } 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); } }