word/edit: track touch events in crop area
authorMischa POSLAWSKY <perl@shiar.org>
Tue, 11 Jan 2022 01:01:31 +0000 (02:01 +0100)
committerMischa POSLAWSKY <perl@shiar.org>
Mon, 7 Feb 2022 17:42:33 +0000 (18:42 +0100)
Reimplement mobile support lost with croppie.

word/editor.js

index 5fc985446b6f128e8e3859e8061b43fe6237a413..c71faa50b1929153f419e69e7b9144fea69a32e9 100644 (file)
@@ -130,9 +130,21 @@ document.addEventListener('DOMContentLoaded', () => {
                        crop.splice(2); // end coordinates applied to zoom
                        crop = crop.map((rel, axis) => rel * border[axis % 2] * scale);
 
-                       let drag = false;
+                       let drag, pinch;
                        function applydrag(e) {
-                               const pos = [e.pageX, e.pageY];
+                               const touch = e.touches ? e.touches[0] : e;
+                               let pos = [touch.pageX, touch.pageY];
+                               if (e.type === 'touchmove' && e.touches.length > 1) {
+                                       // distance to second point
+                                       pos[0] -= e.touches[1].pageX;
+                                       pos[1] -= e.touches[1].pageY;
+                                       const span = Math.sqrt(pos[0]**2 + pos[1]**2);
+                                       if (pinch) {
+                                               cropzoom(.01 * (span - pinch));
+                                       }
+                                       pinch = span;
+                                       return;
+                               }
                                if (drag) {
                                        // apply drag delta to crop position
                                        crop[0] += drag[0] - pos[0];
@@ -141,6 +153,7 @@ document.addEventListener('DOMContentLoaded', () => {
                                }
                                drag = pos;
                        }
+
                        function recrop() {
                                [0, 1].forEach(axis => {
                                        if (crop[axis] > border[axis] * (scale - 1)) {
@@ -159,34 +172,50 @@ document.addEventListener('DOMContentLoaded', () => {
                                ].map(pos => Math.round(1000 * pos / scale));
                        }
 
+                       function cropzoom(delta) {
+                               if (scale + delta < 1) {
+                                       delta = 1 - scale; // scale = 1
+                               }
+                               [0, 1].forEach(axis => {
+                                       // same area center at altered scale
+                                       crop[axis] += (crop[axis] + border[axis] / 2) / scale * delta;
+                               });
+                               scale += delta;
+                               recrop();
+                       }
+
                        imgselect.src = imgpreview.children[0].src;
+                       imgselect.style.cursor = 'grab';
                        imgselect.style.position = 'absolute';
                        recrop();
 
+                       imgselect.ontouchstart =
                        imgselect.onmousedown = e => {
                                e.preventDefault();
+                               drag = pinch = false;
                                applydrag(e);
+                               imgselect.style.cursor = 'grabbing';
+                               window.ontouchmove =
+                               window.onmousemove = e => {
+                                       e.preventDefault();
+                                       applydrag(e);
+                               };
+                               window.ontouchend =
+                               window.onmouseup = e => {
+                                       e.preventDefault();
+                                       imgselect.style.cursor = 'grab';
+                                       window.ontouchmove = window.ontouchend =
+                                       window.onmousemove = window.onmouseup = null;
+                               };
                        };
-                       imgselect.onmouseup = e => {
-                               e.preventDefault();
-                               drag = false;
-                       };
-                       imgselect.onmousemove = e => {
-                               if (!drag) return;
-                               applydrag(e);
-                       };
+
                        imgselect.onwheel = e => {
                                e.preventDefault();
-                               let zoom = e.deltaY * -.05 * scale;
-                               if (scale + zoom < 1) {
-                                       zoom = 1 - scale; // scale = 1
+                               let delta = (-e.deltaY || e.wheelDelta) * .001 * scale;
+                               if (e.deltaMode == 1) { // DOM_DELTA_LINE
+                                       delta *= 18; // convert number of lines to pixels
                                }
-                               [0, 1].forEach(axis => {
-                                       // same area center at altered scale
-                                       crop[axis] += (crop[axis] + border[axis] / 2) / scale * zoom;
-                               });
-                               scale += zoom;
-                               recrop();
+                               cropzoom(delta);
                        };
                };
        }