Web Dev Solutions

Catalin Mititiuc

aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCatalin Mititiuc <webdevcat@proton.me>2024-04-20 19:34:06 -0700
committerCatalin Mititiuc <webdevcat@proton.me>2024-04-23 10:09:51 -0700
commit2d3fc1cd22ffcc61ec178eeaf97f3a4d7cba98bf (patch)
treea072ea398ce00b68dd0e5e670b32ac5ee1a812ad /src/modules/zoom.js
parent263201d869956b94660d4efa8297e89dadbe36a8 (diff)
Use CSS transformations instead of manipulating the viewBox
Diffstat (limited to 'src/modules/zoom.js')
-rw-r--r--src/modules/zoom.js75
1 files changed, 37 insertions, 38 deletions
diff --git a/src/modules/zoom.js b/src/modules/zoom.js
index 24ddb79..97a23e1 100644
--- a/src/modules/zoom.js
+++ b/src/modules/zoom.js
@@ -1,57 +1,56 @@
-const zoomStepRatio = 0.25,
- positive = 1,
- negative = -1;
-
-function toLocalCoords(svg, x, y) {
- const clientP = new DOMPoint(x, y);
-
- return clientP.matrixTransform(svg.getScreenCTM().inverse());
-}
+import getComputedTransformMatrix from './utils.js';
function zoomIn(deltaY) {
return deltaY < 0;
}
-function calcSizeChangeAmounts(width, height) {
- return {
- width: width * zoomStepRatio,
- height: height * zoomStepRatio
- };
+function getScale(e, factor) {
+ return zoomIn(e.deltaY) ? 1 + factor : 1 - factor;
}
-function calcValChangeRatios(focusPoint, x, y, width, height) {
+function getFocalPointBeforeTransform(el, e) {
+ const { x, y, width, height } = el.getBoundingClientRect();
+
return {
- x: (focusPoint.x - x) / width,
- y: (focusPoint.y - y) / height,
- width: (width + x - focusPoint.x) / width,
- height: (height + y - focusPoint.y) / height
+ x: e.clientX,
+ y: e.clientY,
+ relativeToImageSize: {
+ x: (e.clientX - x) / width,
+ y: (e.clientY - y) / height
+ }
};
}
-function calcValChangeAmounts(focusPoint, x, y, width, height) {
- const changeAmount = calcSizeChangeAmounts(width, height),
- valChangeRatio = calcValChangeRatios(focusPoint, x, y, width, height);
+function getFocalPointAfterTransform(el, fpBeforeTrans) {
+ const { x, y, width, height } = el.getBoundingClientRect(),
+ relativeFocalPoint = fpBeforeTrans.relativeToImageSize;
return {
- x: valChangeRatio.x * changeAmount.width,
- y: valChangeRatio.y * changeAmount.height,
- width: valChangeRatio.width * changeAmount.width,
- height: valChangeRatio.height * changeAmount.height
+ x: x + width * relativeFocalPoint.x,
+ y: y + height * relativeFocalPoint.y
};
}
-export default function (svg, e) {
- const pointerPosition = toLocalCoords(svg, e.clientX, e.clientY),
- sign = zoomIn(e.deltaY) ? positive : negative,
- { x, y, width, height } = svg.viewBox.baseVal,
- changeAmount = calcValChangeAmounts(pointerPosition, x, y, width, height),
+function getTranslateMatrix(el, e, scaleMatrix) {
+ const fpBeforeTrans = getFocalPointBeforeTransform(el, e);
+
+ el.style.transform = scaleMatrix;
+
+ const fpAfterTrans = getFocalPointAfterTransform(el, fpBeforeTrans),
+ translateMatrix = new DOMMatrix();
+
+ return translateMatrix.translate(
+ fpBeforeTrans.x - fpAfterTrans.x,
+ fpBeforeTrans.y - fpAfterTrans.y
+ );
+}
+
+export default function (el, e, factor = 0.1) {
+ e.preventDefault();
- attr = {
- x: x + sign * changeAmount.x,
- y: y + sign * changeAmount.y,
- width: width + sign * (-changeAmount.x - changeAmount.width),
- height: height + sign * (-changeAmount.y - changeAmount.height)
- };
+ const mtx = getComputedTransformMatrix(el),
+ scale = getScale(e, factor),
+ transMtx = getTranslateMatrix(el, e, mtx.scale(scale));
- return `${attr.x} ${attr.y} ${attr.width} ${attr.height}`;
+ el.style.transform = transMtx.multiply(mtx).scale(scale);
}