From 5761b46c01bbb4cfa93c17328cf04cdf3712a600 Mon Sep 17 00:00:00 2001 From: Yohann Streibel Date: Wed, 13 Nov 2019 17:19:33 +0100 Subject: [PATCH] Add zoomToFit feature --- index.d.ts | 1 + index.js | 57 +++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/index.d.ts b/index.d.ts index 5dba0a5..5ed1c45 100644 --- a/index.d.ts +++ b/index.d.ts @@ -48,6 +48,7 @@ declare module "panzoom" { scale: number; }; showRectangle: (rect: ClientRect) => void; + zoomToFit: (ui: any) => void; pause: () => void; resume: () => void; isPaused: () => boolean; diff --git a/index.js b/index.js index 4ea7222..f212cea 100644 --- a/index.js +++ b/index.js @@ -116,6 +116,7 @@ function createPanZoom(domElement, options) { smoothZoom: smoothZoom, smoothZoomAbs: smoothZoomAbs, showRectangle: showRectangle, + zoomToFit: zoomToFit, pause: pause, resume: resume, @@ -391,26 +392,50 @@ function createPanZoom(domElement, options) { internalMoveBy(dx, dy, true) } - function internalMoveBy(dx, dy, smooth) { - if (!smooth) { - return moveBy(dx, dy) - } + function zoomToFit(ui) { + var parent = ui.ownerSVGElement + if (!parent) throw new Error('ui element is required to be within the scene') - if (moveByAnimation) moveByAnimation.cancel() + // TODO: should i use controller's screen CTM? + var clientRect = ui.getBoundingClientRect() + var cx = clientRect.left + clientRect.width/2 + var cy = clientRect.top + clientRect.height/2 + + var container = parent.getBoundingClientRect() + var dx = container.width/2 - cx + var dy = container.height/2 - cy - var from = { x: 0, y: 0 } - var to = { x: dx, y : dy } - var lastX = 0 - var lastY = 0 + var wx = window.innerWidth / 2; + var wy = window.innerHeight / 2; - moveByAnimation = animate(from, to, { - step: function(v) { - moveBy(v.x - lastX, v.y - lastY) + var fitRatio = Math.min(wx / (clientRect.width / 2), wy / (clientRect.height / 2)); - lastX = v.x - lastY = v.y - } - }) + internalMoveBy(dx, dy, true, () => {smoothZoom(wx , wy, fitRatio)}); + + } + + function internalMoveBy(dx, dy, smooth, done) { + if (!smooth) { + moveBy(dx, dy); + done(); + } else { + if (moveByAnimation) moveByAnimation.cancel() + + var from = { x: 0, y: 0 } + var to = { x: dx, y : dy } + var lastX = 0 + var lastY = 0 + + moveByAnimation = animate(from, to, { + step: function(v) { + moveBy(v.x - lastX, v.y - lastY) + + lastX = v.x + lastY = v.y + }, + done: done + }) + } } function scroll(x, y) {