index : pan-zoom | |
SVG pan/zoom library. |
aboutsummaryrefslogtreecommitdiff |
diff options
-rw-r--r-- | package-lock.json | 4 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/modules/pan.js | 29 | ||||
-rw-r--r-- | src/modules/zoom.js | 61 |
4 files changed, 36 insertions, 60 deletions
diff --git a/package-lock.json b/package-lock.json index 91def04..b1fbfc5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pan-zoom", - "version": "0.3.0", + "version": "0.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pan-zoom", - "version": "0.3.0", + "version": "0.3.1", "license": "ISC", "devDependencies": { "esbuild": "^0.20.2", diff --git a/package.json b/package.json index 670ddbd..e46850c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pan-zoom", - "version": "0.3.0", + "version": "0.3.1", "description": "Pan/zoom SVG images in the browser", "browser": "index.js", "files": [ 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); } } |