Web Dev Solutions

Catalin Mititiuc

aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/pan.js37
-rw-r--r--src/modules/zoom.js30
2 files changed, 38 insertions, 29 deletions
diff --git a/src/modules/pan.js b/src/modules/pan.js
index 201c2f1..6f2cacf 100644
--- a/src/modules/pan.js
+++ b/src/modules/pan.js
@@ -2,13 +2,6 @@ import getComputedTransformMatrix from './utils.js';
const minDistanceThreshold = 5;
-function setToCurrentPointerCoords(point, e) {
- point.x = e.clientX;
- point.y = e.clientY;
-
- return point;
-}
-
function distanceBetween({ x: x1, y: y1 }, { x: x2, y: y2 }) {
return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
}
@@ -27,35 +20,45 @@ function getTranslateMatrix(startPt, movePt) {
return translateMatrix.translate(movePt.x - startPt.x, movePt.y - startPt.y);
}
-export default function (el, e) {
+export default function (svg, el, e) {
e.preventDefault();
const mtx = getComputedTransformMatrix(el),
- startPt = new DOMPoint(e.clientX, e.clientY),
- movePt = new DOMPoint();
+ inverseScreenCTM = el.getScreenCTM().inverse();
- let isPanning = false;
+ let startPt = new DOMPoint(e.clientX, e.clientY),
+ movePt = new DOMPoint(),
+ isPanning = false;
function pointerMove(e) {
- setToCurrentPointerCoords(movePt, e);
+ movePt.x = e.clientX;
+ movePt.y = e.clientY;
if (!isPanning && minDistanceThresholdIsMet(startPt, movePt)) {
isPanning = true;
e.target.setPointerCapture(e.pointerId);
- setToCurrentPointerCoords(startPt, e);
+
+ startPt.x = e.clientX;
+ startPt.y = e.clientY;
+ startPt = startPt.matrixTransform(inverseScreenCTM);
+
stopEventPropagationToChildren(el, 'click');
}
if (isPanning) {
- el.style.transform = getTranslateMatrix(startPt, movePt).multiply(mtx);
+ movePt.x = e.clientX;
+ movePt.y = e.clientY;
+ movePt = movePt.matrixTransform(inverseScreenCTM);
+
+ el.style.transform = mtx.multiply(getTranslateMatrix(startPt, movePt));
}
}
- el.addEventListener('pointermove', pointerMove);
+ svg.addEventListener('pointermove', pointerMove);
- el.addEventListener(
+ svg.addEventListener(
'pointerup',
- () => el.removeEventListener('pointermove', pointerMove),
+ () => svg.removeEventListener('pointermove', pointerMove),
{ once: true }
);
}
diff --git a/src/modules/zoom.js b/src/modules/zoom.js
index 97a23e1..fc0540b 100644
--- a/src/modules/zoom.js
+++ b/src/modules/zoom.js
@@ -8,35 +8,41 @@ function getScale(e, factor) {
return zoomIn(e.deltaY) ? 1 + factor : 1 - factor;
}
-function getFocalPointBeforeTransform(el, e) {
- const { x, y, width, height } = el.getBoundingClientRect();
+function getFocalPointBeforeTransform(el, e, inverseScreenCTM) {
+ const { x, y, width, height } = el.getBoundingClientRect(),
+ pointer = (new DOMPoint(e.clientX, e.clientY)).matrixTransform(inverseScreenCTM),
+ origin = (new DOMPoint(x, y)).matrixTransform(inverseScreenCTM),
+ terminus = (new DOMPoint(x + width, y + height)).matrixTransform(inverseScreenCTM);
return {
- x: e.clientX,
- y: e.clientY,
+ x: pointer.x,
+ y: pointer.y,
relativeToImageSize: {
- x: (e.clientX - x) / width,
- y: (e.clientY - y) / height
+ x: (pointer.x - origin.x) / (terminus.x - origin.x),
+ y: (pointer.y - origin.y) / (terminus.y - origin.y)
}
};
}
-function getFocalPointAfterTransform(el, fpBeforeTrans) {
+function getFocalPointAfterTransform(el, fpBeforeTrans, inverseScreenCTM) {
const { x, y, width, height } = el.getBoundingClientRect(),
+ origin = (new DOMPoint(x, y)).matrixTransform(inverseScreenCTM),
+ terminus = (new DOMPoint(x + width, y + height)).matrixTransform(inverseScreenCTM),
relativeFocalPoint = fpBeforeTrans.relativeToImageSize;
return {
- x: x + width * relativeFocalPoint.x,
- y: y + height * relativeFocalPoint.y
+ x: origin.x + (terminus.x - origin.x) * relativeFocalPoint.x,
+ y: origin.y + (terminus.y - origin.y) * relativeFocalPoint.y
};
}
function getTranslateMatrix(el, e, scaleMatrix) {
- const fpBeforeTrans = getFocalPointBeforeTransform(el, e);
+ const inverseScreenCTM = el.getScreenCTM().inverse(),
+ fpBeforeTrans = getFocalPointBeforeTransform(el, e, inverseScreenCTM);
el.style.transform = scaleMatrix;
- const fpAfterTrans = getFocalPointAfterTransform(el, fpBeforeTrans),
+ const fpAfterTrans = getFocalPointAfterTransform(el, fpBeforeTrans, inverseScreenCTM),
translateMatrix = new DOMMatrix();
return translateMatrix.translate(
@@ -52,5 +58,5 @@ export default function (el, e, factor = 0.1) {
scale = getScale(e, factor),
transMtx = getTranslateMatrix(el, e, mtx.scale(scale));
- el.style.transform = transMtx.multiply(mtx).scale(scale);
+ el.style.transform = mtx.multiply(transMtx).scale(scale);
}