Web Dev Solutions

Catalin Mititiuc

aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCatalin Mititiuc <webdevcat@proton.me>2024-04-12 10:57:15 -0700
committerCatalin Mititiuc <webdevcat@proton.me>2024-04-15 09:48:00 -0700
commit263201d869956b94660d4efa8297e89dadbe36a8 (patch)
tree8fa47922163548dda0739aaa5ff0612de96c9fd1 /src/modules/zoom.js
Initial commit
Diffstat (limited to 'src/modules/zoom.js')
-rw-r--r--src/modules/zoom.js57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/modules/zoom.js b/src/modules/zoom.js
new file mode 100644
index 0000000..24ddb79
--- /dev/null
+++ b/src/modules/zoom.js
@@ -0,0 +1,57 @@
+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());
+}
+
+function zoomIn(deltaY) {
+ return deltaY < 0;
+}
+
+function calcSizeChangeAmounts(width, height) {
+ return {
+ width: width * zoomStepRatio,
+ height: height * zoomStepRatio
+ };
+}
+
+function calcValChangeRatios(focusPoint, x, y, width, height) {
+ return {
+ x: (focusPoint.x - x) / width,
+ y: (focusPoint.y - y) / height,
+ width: (width + x - focusPoint.x) / width,
+ height: (height + y - focusPoint.y) / height
+ };
+}
+
+function calcValChangeAmounts(focusPoint, x, y, width, height) {
+ const changeAmount = calcSizeChangeAmounts(width, height),
+ valChangeRatio = calcValChangeRatios(focusPoint, x, y, width, height);
+
+ return {
+ x: valChangeRatio.x * changeAmount.width,
+ y: valChangeRatio.y * changeAmount.height,
+ width: valChangeRatio.width * changeAmount.width,
+ height: valChangeRatio.height * changeAmount.height
+ };
+}
+
+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),
+
+ 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)
+ };
+
+ return `${attr.x} ${attr.y} ${attr.width} ${attr.height}`;
+}