index : pan-zoom | |
SVG pan/zoom library. |
aboutsummaryrefslogtreecommitdiff |
diff options
author | Catalin Mititiuc <webdevcat@proton.me> | 2024-08-08 19:07:03 -0700 |
---|---|---|
committer | Catalin Mititiuc <webdevcat@proton.me> | 2024-08-08 19:07:03 -0700 |
commit | 00c092210ba62aa85ff082bbbc21380bfe5cb976 (patch) | |
tree | cf42de26c7cbb2773bd8ba7604fcb1892fe2b106 | |
parent | 9c34e15c47cf3578adeff41693a62061a25fdcde (diff) |
Add rough programmatic pan; refactor some
-rw-r--r-- | index.js | 2 | ||||
-rw-r--r-- | src/modules/pan.js | 55 | ||||
-rw-r--r-- | src/modules/zoom.js | 43 |
3 files changed, 66 insertions, 34 deletions
@@ -1,2 +1,2 @@ -export { default as pan } from './src/modules/pan.js'; +export { default as pan, manualPan } from './src/modules/pan.js'; export { default as zoom } from './src/modules/zoom.js'; diff --git a/src/modules/pan.js b/src/modules/pan.js index 6f2cacf..4fcb416 100644 --- a/src/modules/pan.js +++ b/src/modules/pan.js @@ -2,6 +2,10 @@ import getComputedTransformMatrix from './utils.js'; const minDistanceThreshold = 5; +function mainButtonPressed(e) { + return e.button === 0; +} + function distanceBetween({ x: x1, y: y1 }, { x: x2, y: y2 }) { return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2); } @@ -20,15 +24,26 @@ function getTranslateMatrix(startPt, movePt) { return translateMatrix.translate(movePt.x - startPt.x, movePt.y - startPt.y); } -export default function (svg, el, e) { - e.preventDefault(); +export function manualPan(gb, counter) { + const mtx = getComputedTransformMatrix(gb); + const inverseScreenCTM = gb.getScreenCTM().inverse(); - const mtx = getComputedTransformMatrix(el), - inverseScreenCTM = el.getScreenCTM().inverse(); + const counterRect = counter.getBoundingClientRect(); + const mapRect = document.querySelector('object').getBoundingClientRect(); - let startPt = new DOMPoint(e.clientX, e.clientY), - movePt = new DOMPoint(), - isPanning = false; + let startPt = new DOMPoint(counterRect.x + counterRect.width / 2, counterRect.y + counterRect.height / 2); + let movePt = new DOMPoint(mapRect.width / 2, mapRect.height / 2); + + startPt = startPt.matrixTransform(inverseScreenCTM); + movePt = movePt.matrixTransform(inverseScreenCTM); + + gb.style.transition = 'transform 0.5s'; + gb.style.transform = mtx.multiply(getTranslateMatrix(startPt, movePt)); + gb.addEventListener('transitionend', () => gb.style.transition = '', { once: true }); +} + +export default function (el) { + let mtx, inverseScreenCTM, startPt, movePt, isPanning; function pointerMove(e) { movePt.x = e.clientX; @@ -36,7 +51,6 @@ export default function (svg, el, e) { if (!isPanning && minDistanceThresholdIsMet(startPt, movePt)) { isPanning = true; - e.target.setPointerCapture(e.pointerId); startPt.x = e.clientX; startPt.y = e.clientY; @@ -54,11 +68,24 @@ export default function (svg, el, e) { } } - svg.addEventListener('pointermove', pointerMove); + return function(e) { + if (!mainButtonPressed(e)) return; + e.preventDefault(); + e.target.setPointerCapture(e.pointerId); + + isPanning = false; + mtx = getComputedTransformMatrix(el); + inverseScreenCTM = el.getScreenCTM().inverse(); - svg.addEventListener( - 'pointerup', - () => svg.removeEventListener('pointermove', pointerMove), - { once: true } - ); + startPt = new DOMPoint(e.clientX, e.clientY); + movePt = new DOMPoint(); + + this.addEventListener('pointermove', pointerMove); + + this.addEventListener( + 'pointerup', + () => this.removeEventListener('pointermove', pointerMove), + { once: true } + ); + } } diff --git a/src/modules/zoom.js b/src/modules/zoom.js index fc0540b..834602b 100644 --- a/src/modules/zoom.js +++ b/src/modules/zoom.js @@ -5,14 +5,17 @@ function zoomIn(deltaY) { } function getScale(e, factor) { - return zoomIn(e.deltaY) ? 1 + factor : 1 - factor; + const outMult = 1 - factor; + const inMult = 1 + factor / outMult + + return zoomIn(e.deltaY) ? inMult : outMult; } 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); + 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, @@ -25,10 +28,10 @@ function getFocalPointBeforeTransform(el, e, inverseScreenCTM) { } 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; + 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, @@ -37,13 +40,13 @@ function getFocalPointAfterTransform(el, fpBeforeTrans, inverseScreenCTM) { } function getTranslateMatrix(el, e, scaleMatrix) { - const inverseScreenCTM = el.getScreenCTM().inverse(), - fpBeforeTrans = getFocalPointBeforeTransform(el, e, inverseScreenCTM); + const inverseScreenCTM = el.getScreenCTM().inverse(); + const fpBeforeTrans = getFocalPointBeforeTransform(el, e, inverseScreenCTM); el.style.transform = scaleMatrix; - const fpAfterTrans = getFocalPointAfterTransform(el, fpBeforeTrans, inverseScreenCTM), - translateMatrix = new DOMMatrix(); + const fpAfterTrans = getFocalPointAfterTransform(el, fpBeforeTrans, inverseScreenCTM); + const translateMatrix = new DOMMatrix(); return translateMatrix.translate( fpBeforeTrans.x - fpAfterTrans.x, @@ -51,12 +54,14 @@ function getTranslateMatrix(el, e, scaleMatrix) { ); } -export default function (el, e, factor = 0.1) { - e.preventDefault(); +export default function (el, factor = 0.1) { + return e => { + e.preventDefault(); - const mtx = getComputedTransformMatrix(el), - scale = getScale(e, factor), - transMtx = getTranslateMatrix(el, e, mtx.scale(scale)); + const mtx = getComputedTransformMatrix(el); + const scale = getScale(e, factor); + const transMtx = getTranslateMatrix(el, e, mtx.scale(scale)); - el.style.transform = mtx.multiply(transMtx).scale(scale); + el.style.transform = mtx.multiply(transMtx).scale(scale); + } } |