diff --git a/index.d.ts b/index.d.ts index 84f20a5..b8764be 100644 --- a/index.d.ts +++ b/index.d.ts @@ -66,6 +66,7 @@ declare module "panzoom" { ) => void; getTransform: () => Transform; showRectangle: (rect: ClientRect) => void; + zoomToFit: (ui: any) => void; pause: () => void; resume: () => void; isPaused: () => boolean; diff --git a/index.js b/index.js index e4c59b2..be742c8 100644 --- a/index.js +++ b/index.js @@ -119,6 +119,7 @@ function createPanZoom(domElement, options) { smoothZoom: smoothZoom, smoothZoomAbs: smoothZoomAbs, showRectangle: showRectangle, + zoomToFit: zoomToFit, pause: pause, resume: resume, @@ -444,26 +445,50 @@ function createPanZoom(domElement, options) { internalMoveBy(x - transform.x, y - transform.y, 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 from = { x: 0, y: 0 }; - var to = { x: dx, y: dy }; - var lastX = 0; - var lastY = 0; + var container = parent.getBoundingClientRect() + var dx = container.width/2 - cx + var dy = container.height/2 - cy - moveByAnimation = animate(from, to, { - step: function (v) { - moveBy(v.x - lastX, v.y - lastY); + var wx = window.innerWidth / 2; + var wy = window.innerHeight / 2; - lastX = v.x; - lastY = v.y; - } - }); + var fitRatio = Math.min(wx / (clientRect.width / 2), wy / (clientRect.height / 2)); + + 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) {