diff --git a/index.d.ts b/index.d.ts index 6b3ab71..f6eaa72 100644 --- a/index.d.ts +++ b/index.d.ts @@ -56,6 +56,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 9bb1ac6..809001c 100644 --- a/index.js +++ b/index.js @@ -122,6 +122,7 @@ function createPanZoom(domElement, options) { smoothZoom: smoothZoom, smoothZoomAbs: smoothZoomAbs, showRectangle: showRectangle, + zoomToFit: zoomToFit, pause: pause, resume: resume, @@ -418,43 +419,62 @@ function createPanZoom(domElement, options) { zoomByRatio(clientX, clientY, ratio); } - function centerOn(ui) { - var parent = ui.ownerSVGElement; - if (!parent) - throw new Error('ui element is required to be within the scene'); - + function centerOn(smooth) { // TODO: should i use controller's screen CTM? - var clientRect = ui.getBoundingClientRect(); + var clientRect = owner.getBoundingClientRect(); var cx = clientRect.left + clientRect.width / 2; var cy = clientRect.top + clientRect.height / 2; + var parent = owner.parentElement.parentElement; var container = parent.getBoundingClientRect(); var dx = container.width / 2 - cx; var dy = container.height / 2 - cy; - internalMoveBy(dx, dy, true); + internalMoveBy(dx, dy, smooth); } - function internalMoveBy(dx, dy, smooth) { - if (!smooth) { - return moveBy(dx, dy); - } + function zoomToFit(smooth) { + // TODO: should i use controller's screen CTM? + var clientRect = owner.getBoundingClientRect(); + var cx = clientRect.left + clientRect.width/2; + var cy = clientRect.top + clientRect.height/2; - if (moveByAnimation) moveByAnimation.cancel(); + var parent = owner.parentElement.parentElement; + 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, smooth, () => {smoothZoom(wx , wy, fitRatio);}); + } + + function internalMoveBy(dx, dy, smooth, done) { + if (!smooth) { + moveBy(dx, dy); + if (done !== undefined) + 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) {