Web Dev Solutions

Catalin Mititiuc

aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/modules/pan.js29
-rw-r--r--src/modules/zoom.js61
2 files changed, 33 insertions, 57 deletions
diff --git a/src/modules/pan.js b/src/modules/pan.js
index 4e6485c..bf842bd 100644
--- a/src/modules/pan.js
+++ b/src/modules/pan.js
@@ -1,4 +1,4 @@
-import getComputedTransformMatrix from './utils.js';
+import { default as getComputedTransformMatrix } from './utils';
const minDistanceThreshold = 5;
@@ -31,23 +31,26 @@ function getTransformMatrices(el) {
};
}
-function clientToSvgPt({ clientX, clientY }, { inverseScreen }, pt = new DOMPoint()) {
- pt.x = clientX;
- pt.y = clientY;
- return pt.matrixTransform(inverseScreen);
+function clientToSvgPt(e, inverseScreenMtx, pt = new DOMPoint()) {
+ pt.x = e.clientX;
+ pt.y = e.clientY;
+ return pt.matrixTransform(inverseScreenMtx);
}
-function setPanTransform(el, { computed }, startPt, endPt) {
- el.style.transform = computed.multiply(getTranslateMatrix(startPt, endPt));
+function setTransform(el, computedMtx, startPt, endPt) {
+ const translateMtx = getTranslateMatrix(startPt, endPt);
+ const transformMtx = computedMtx.multiply(translateMtx);
+
+ el.style.transform = transformMtx;
}
export function programmaticPan(el, from, to) {
const matrices = getTransformMatrices(el);
- const startPt = clientToSvgPt(from, matrices);
- const endPt = clientToSvgPt(to, matrices);
+ const startPt = clientToSvgPt(from, matrices.inverseScreen);
+ const endPt = clientToSvgPt(to, matrices.inverseScreen);
el.style.transition = 'transform 0.5s';
- setPanTransform(el, matrices, startPt, endPt);
+ setTransform(el, matrices.computed, startPt, endPt);
el.addEventListener('transitionend', () => el.style.transition = '', { once: true });
}
@@ -60,13 +63,13 @@ export default function (el) {
if (!isPanning && exceedsMinDistanceThreshhold(startPt, movePt)) {
isPanning = true;
- startPt = clientToSvgPt(e, matrices, startPt);
+ startPt = clientToSvgPt(e, matrices.inverseScreen, startPt);
stopEventPropagationToChildren(el, 'click');
}
if (isPanning) {
- movePt = clientToSvgPt(e, matrices, movePt);
- setPanTransform(el, matrices, startPt, movePt);
+ movePt = clientToSvgPt(e, matrices.inverseScreen, movePt);
+ setTransform(el, matrices.computed, startPt, movePt);
}
}
diff --git a/src/modules/zoom.js b/src/modules/zoom.js
index 834602b..1455cb4 100644
--- a/src/modules/zoom.js
+++ b/src/modules/zoom.js
@@ -1,67 +1,40 @@
-import getComputedTransformMatrix from './utils.js';
+import { default as getComputedTransformMatrix } from './utils';
function zoomIn(deltaY) {
return deltaY < 0;
}
-function getScale(e, factor) {
+function getScale(deltaY, factor) {
const outMult = 1 - factor;
const inMult = 1 + factor / outMult
- return zoomIn(e.deltaY) ? inMult : outMult;
+ return zoomIn(deltaY) ? inMult : outMult;
}
-function getFocalPointBeforeTransform(el, e, inverseScreenCTM) {
- const { x, y, width, height } = el.getBoundingClientRect();
- const pointer = (new DOMPoint(e.clientX, e.clientY)).matrixTransform(inverseScreenCTM);
- const origin = (new DOMPoint(x, y)).matrixTransform(inverseScreenCTM);
- const terminus = (new DOMPoint(x + width, y + height)).matrixTransform(inverseScreenCTM);
-
- return {
- x: pointer.x,
- y: pointer.y,
- relativeToImageSize: {
- x: (pointer.x - origin.x) / (terminus.x - origin.x),
- y: (pointer.y - origin.y) / (terminus.y - origin.y)
- }
- };
-}
-
-function getFocalPointAfterTransform(el, fpBeforeTrans, inverseScreenCTM) {
- const { x, y, width, height } = el.getBoundingClientRect();
- const origin = (new DOMPoint(x, y)).matrixTransform(inverseScreenCTM);
- const terminus = (new DOMPoint(x + width, y + height)).matrixTransform(inverseScreenCTM);
- const relativeFocalPoint = fpBeforeTrans.relativeToImageSize;
-
- return {
- x: origin.x + (terminus.x - origin.x) * relativeFocalPoint.x,
- y: origin.y + (terminus.y - origin.y) * relativeFocalPoint.y
- };
-}
-
-function getTranslateMatrix(el, e, scaleMatrix) {
+function getTranslateMatrix(el, clientX, clientY) {
const inverseScreenCTM = el.getScreenCTM().inverse();
- const fpBeforeTrans = getFocalPointBeforeTransform(el, e, inverseScreenCTM);
+ const translateMtx = new DOMMatrix();
+ const pointer = new DOMPoint(clientX, clientY)
+ const { x, y } = pointer.matrixTransform(inverseScreenCTM);
- el.style.transform = scaleMatrix;
+ return translateMtx.translate(x, y);
+}
- const fpAfterTrans = getFocalPointAfterTransform(el, fpBeforeTrans, inverseScreenCTM);
- const translateMatrix = new DOMMatrix();
+function setTransform(el, computedMtx, translateMtx, scale) {
+ const transformMtx =
+ computedMtx.multiply(translateMtx).scale(scale).multiply(translateMtx.inverse());
- return translateMatrix.translate(
- fpBeforeTrans.x - fpAfterTrans.x,
- fpBeforeTrans.y - fpAfterTrans.y
- );
+ el.style.transform = transformMtx;
}
export default function (el, factor = 0.1) {
return e => {
e.preventDefault();
- const mtx = getComputedTransformMatrix(el);
- const scale = getScale(e, factor);
- const transMtx = getTranslateMatrix(el, e, mtx.scale(scale));
+ const computedMtx = getComputedTransformMatrix(el);
+ const scale = getScale(e.deltaY, factor);
+ const translateMtx = getTranslateMatrix(el, e.clientX, e.clientY);
- el.style.transform = mtx.multiply(transMtx).scale(scale);
+ setTransform(el, computedMtx, translateMtx, scale);
}
}