Mercurial Hosting > dad
view src/dad.js @ 18:881840185730
minor
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 15 Sep 2024 07:41:37 -0600 |
parents | 36c7b187827b |
children |
line wrap: on
line source
'use strict'; let dad = {}; { // override these if needed dad.whatToDrag = function(draggable) { return draggable; }; dad.onStart = function(event) {}; dad.onEnter = function(event) {}; dad.onLeave = function(event) {}; dad.onDrop = function(event) {}; dad.onDropped = function(event) {}; let original = null; let dragging = null; let dropzone = null; let touchX, touchY; function isIn(x,y,rect) { return rect.x <= x && x <= rect.x+rect.width && rect.y <= y && y <= rect.y+rect.height; } function myEvent(mouseEvent) { return { original: original, dragging: dragging, dropzone: dropzone, mouseEvent: mouseEvent, }; } function onMouseMove(event) { { event.preventDefault(); let rect = dragging.getBoundingClientRect(); dragging.style.left = `${rect.x+event.movementX}px`; let y = rect.y + event.movementY; if( y < 0 ) { window.scrollBy( 0, y ); } else if( y + rect.height > window.innerHeight ) { window.scrollBy( 0, y + rect.height - window.innerHeight ); } dragging.style.top = `${y}px`; } { let x = event.clientX; let y = event.clientY; if( !(dropzone && isIn(x,y,dropzone.getBoundingClientRect())) ) { if( dropzone ) { dad.onLeave(myEvent(event)); dropzone = null; } let dropzones = document.querySelectorAll('[dad-dropzone]'); for( let i=0; i<dropzones.length; i++ ) { let dz = dropzones[i]; if( dz === dragging ) continue; if( isIn(x,y,dz.getBoundingClientRect()) ) { dropzone = dz; dad.onEnter(myEvent(event)); break; } } } } } function onTouchMove(event) { let touches = event.touches; if( touches.length !== 1 ) return; let touch = touches[0]; let x = touch.clientX; let y = touch.clientY; event.clientX = x; event.clientY = y; event.movementX = x - touchX; event.movementY = y - touchY; touchX = x; touchY = y; onMouseMove(event); } function onMouseUp(event) { dad.onDrop(myEvent(event)); if( dropzone ) { dad.onLeave(myEvent(event)); } original.removeAttribute('dad-original'); dragging.parentNode.removeChild(dragging); document.removeEventListener('mousemove',onMouseMove); document.removeEventListener('mouseup',onMouseUp); document.removeEventListener('touchmove',onTouchMove); document.removeEventListener('touchend',onMouseUp); original.scrollIntoViewIfNeeded(false); let droppedEvent = { original: original, }; original = null; dragging = null; dropzone = null; dad.onDropped(droppedEvent); } function start(event) { original = dad.whatToDrag(event.target); dragging = original.cloneNode(true); original.setAttribute('dad-original',''); dragging.setAttribute('dad-dragging',''); let rect = original.getBoundingClientRect(); dragging.style.left = `${rect.x}px`; dragging.style.top = `${rect.y}px`; dragging.style.width = `${rect.width}px`; dragging.style.heigh = `${rect.heigh}px`; original.parentNode.appendChild(dragging); dad.onStart(myEvent(event)); } function onMouseDown(event) { start(event); document.addEventListener('mousemove',onMouseMove); document.addEventListener('mouseup',onMouseUp); } function onTouchStart(event) { event.preventDefault(); start(event); let touches = event.touches; if( touches.length !== 1 ) return; let touch = touches[0]; touchX = touch.clientX; touchY = touch.clientY; document.addEventListener('touchmove',onTouchMove); document.addEventListener('touchend',onMouseUp); } dad.setDraggable = function(el) { el.setAttribute('dad-drag',''); el.setAttribute('draggable','false'); el.addEventListener('mousedown',onMouseDown); el.addEventListener('touchstart',onTouchStart); }; dad.setDropzone = function(el) { el.setAttribute('dad-dropzone',''); }; }