3
|
1 'use strict';
|
|
2
|
|
3 let dad = {};
|
|
4
|
|
5 {
|
4
|
6 // override these if needed
|
3
|
7 dad.whatToDrag = function(draggable) {
|
|
8 return draggable;
|
|
9 };
|
4
|
10 dad.onDrop = function(event) {};
|
|
11 dad.onDropped = function(event) {};
|
6
|
12 dad.onEnter = function(event) {};
|
|
13 dad.onLeave = function(event) {};
|
3
|
14
|
|
15
|
|
16 let original = null;
|
|
17 let dragging = null;
|
6
|
18 let dropzone = null;
|
3
|
19 let touchX, touchY;
|
|
20
|
6
|
21 function isIn(x,y,rect) {
|
|
22 return rect.x <= x && x <= rect.x+rect.width && rect.y <= y && y <= rect.y+rect.height;
|
|
23 }
|
|
24
|
3
|
25 function onMouseMove(event) {
|
|
26 //console.log(event);
|
6
|
27 {
|
|
28 event.preventDefault();
|
|
29 let rect = dragging.getBoundingClientRect();
|
|
30 dragging.style.left = `${rect.x+event.movementX}px`;
|
|
31 let y = rect.y + event.movementY;
|
|
32 if( y < 0 ) {
|
|
33 window.scrollBy( 0, y );
|
|
34 } else if( y + rect.height > window.innerHeight ) {
|
|
35 window.scrollBy( 0, y + rect.height - window.innerHeight );
|
|
36 }
|
|
37 dragging.style.top = `${y}px`;
|
3
|
38 }
|
6
|
39 {
|
|
40 let x = event.clientX;
|
|
41 let y = event.clientY;
|
|
42 if( !(dropzone && isIn(x,y,dropzone.getBoundingClientRect())) ) {
|
|
43 if( dropzone ) {
|
|
44 dad.onLeave({
|
|
45 original: original,
|
|
46 dragging: dragging,
|
|
47 dropzone: dropzone,
|
|
48 mouseEvent: event,
|
|
49 });
|
|
50 dropzone = null;
|
|
51 }
|
|
52 let dropzones = document.querySelectorAll('[dad-dropzone]');
|
|
53 for( let i=0; i<dropzones.length; i++ ) {
|
|
54 let dz = dropzones[i];
|
|
55 if( dz === dragging )
|
|
56 continue;
|
|
57 if( isIn(x,y,dz.getBoundingClientRect()) ) {
|
|
58 dropzone = dz;
|
|
59 dad.onEnter({
|
|
60 original: original,
|
|
61 dragging: dragging,
|
|
62 dropzone: dropzone,
|
|
63 mouseEvent: event,
|
|
64 });
|
|
65 break;
|
|
66 }
|
|
67 }
|
|
68 }
|
|
69 }
|
3
|
70 }
|
|
71
|
|
72 function onTouchMove(event) {
|
|
73 let touches = event.touches;
|
|
74 if( touches.length !== 1 )
|
|
75 return;
|
|
76 let touch = touches[0];
|
|
77 let x = touch.clientX;
|
|
78 let y = touch.clientY;
|
6
|
79 event.clientX = x;
|
|
80 event.clientY = y;
|
3
|
81 event.movementX = x - touchX;
|
|
82 event.movementY = y - touchY;
|
|
83 touchX = x;
|
|
84 touchY = y;
|
|
85 onMouseMove(event);
|
|
86 }
|
|
87
|
|
88 function onMouseUp(event) {
|
|
89 //console.log(event);
|
4
|
90 dad.onDrop({
|
5
|
91 original: original,
|
|
92 dragging: dragging,
|
6
|
93 dropzone: dropzone,
|
4
|
94 mouseEvent: event,
|
|
95 });
|
6
|
96 if( dropzone ) {
|
|
97 dad.onLeave({
|
|
98 original: original,
|
|
99 dragging: dragging,
|
|
100 dropzone: dropzone,
|
|
101 mouseEvent: event,
|
|
102 });
|
|
103 }
|
3
|
104 original.removeAttribute('dad-original');
|
4
|
105 dragging.parentNode.removeChild(dragging);
|
3
|
106 document.removeEventListener('mousemove',onMouseMove);
|
|
107 document.removeEventListener('mouseup',onMouseUp);
|
|
108 document.removeEventListener('mousemove',onMouseMove);
|
|
109 document.removeEventListener('touchend',onMouseUp);
|
|
110 original.scrollIntoViewIfNeeded(false);
|
4
|
111 let droppedEvent = {
|
5
|
112 original: original,
|
4
|
113 };
|
3
|
114 original = null;
|
|
115 dragging = null;
|
6
|
116 dropzone = null;
|
4
|
117 dad.onDropped(droppedEvent);
|
3
|
118 }
|
|
119
|
|
120 function start(event) {
|
|
121 //console.log(event);
|
|
122 original = dad.whatToDrag(event.target);
|
|
123 dragging = original.cloneNode(true);
|
|
124 original.setAttribute('dad-original','');
|
|
125 dragging.setAttribute('dad-dragging','');
|
|
126 let rect = original.getBoundingClientRect();
|
|
127 dragging.style.left = `${rect.x}px`;
|
|
128 dragging.style.top = `${rect.y}px`;
|
8
|
129 dragging.style.width = `${rect.width}px`;
|
|
130 dragging.style.heigh = `${rect.heigh}px`;
|
4
|
131 original.parentNode.appendChild(dragging);
|
3
|
132 }
|
|
133
|
|
134 function onMouseDown(event) {
|
|
135 start(event);
|
|
136 document.addEventListener('mousemove',onMouseMove);
|
|
137 document.addEventListener('mouseup',onMouseUp);
|
|
138 }
|
|
139
|
|
140 function onTouchStart(event) {
|
|
141 start(event);
|
|
142 let touches = event.touches;
|
|
143 if( touches.length !== 1 )
|
|
144 return;
|
|
145 let touch = touches[0];
|
|
146 touchX = touch.clientX;
|
|
147 touchY = touch.clientY;
|
|
148 document.addEventListener('touchmove',onTouchMove);
|
|
149 document.addEventListener('touchend',onMouseUp);
|
|
150 }
|
|
151
|
|
152 dad.setDraggable = function(el) {
|
|
153 el.setAttribute('dad-drag','');
|
|
154 el.addEventListener('mousedown',onMouseDown);
|
|
155 el.addEventListener('touchstart',onTouchStart);
|
|
156 };
|
6
|
157
|
|
158 dad.setDropzone = function(el) {
|
|
159 el.setAttribute('dad-dropzone','');
|
|
160 };
|
3
|
161 }
|