Open cdaringe opened 6 years ago
That would be really helpful. Is there a way to pan the scene to a specific element?
It's not in the README.md, but this library comes with two methods that may help you: smoothZoom and zoomTo. ctrl-F the method names in the src js to find usage.
Hello gentlemen! Has anyone made any progress in implementing FIT?
Can someone briefly explain what clientX
and clientY
are in publicZoomTo
? I followed it in the source as @rbonomo suggested. zoomTo
(aliased to publicZoomTo
) => zoomByRatio
=> transformToScreen
at which point, I have a trouble understanding what's happening. Are those relative to the current x, y or the origin point? Also, what is the origin - top left? Center? Somewhere else?
Thank you in advance.
To create a workaround for zoom to fit feature, I tried to use :
pz.centerOn(myelement);
pz.smoothZoom(window.innerWidth / 2 , window.innerHeight / 2, fit_computed_ratio);
It doesn't work because the smoothZoom
need to wait the end of the centerOn
animation.
Here is a implementation that actually works:
It has a toggle option from zoom-to-fit back to 100% and vice-versa, but you comment that out easily.
const svg = YOUR_SVG_ELEMENT HERE;
const parent = svg.viewportElement!;
const rectParent = parent.getBoundingClientRect();
const rectScene = svg.getBoundingClientRect();
const xys = this.graphPanZoom.getTransform();
const originWidth = rectScene.width / xys.scale;
const originHeight = rectScene.height / xys.scale;
const zoomX = (rectParent.width - 20) / originWidth;
const zoomY = (rectParent.height - 20) / originHeight;
let targetScale = zoomX < zoomY ? zoomX : zoomY;
//when target scale is the same as currently, we reset back to 100%, so it acts as toggle.
if (Math.abs(targetScale - xys.scale) < 0.005) {
//reset to 100%
targetScale = 1;
}
const targetWidth = originWidth * xys.scale;
const targetHeight = originHeight * xys.scale;
const newX = targetWidth > rectParent.width ? -(targetWidth / 2) + rectParent.width / 2 : (rectParent.width / 2) - (targetWidth / 2);
const newY = targetHeight > rectParent.height ? -(targetHeight / 2) + rectParent.height / 2 : (rectParent.height / 2) - (targetHeight / 2);
//we need to cancel current running animations
this.graphPanZoom.pause();
this.graphPanZoom.resume();
const xDiff = Math.abs(newX - xys.x);
const yDiff = Math.abs(newX - xys.x);
if (xDiff > 5 || yDiff > 5) {
//overything over 5px change will be animated
this.graphPanZoom.moveBy(
newX - xys.x,
newY - xys.y,
true
);
await sleep(0.25);
} else {
this.graphPanZoom.moveBy(
newX - xys.x,
newY - xys.y,
false
);
}
//correct way to zoom with center of graph as origin when scaled
this.graphPanZoom.smoothZoomAbs(
xys.x + originWidth * xys.scale / 2,
xys.y + originHeight * xys.scale / 2,
targetScale,
);
Typescript tho.
hi @marcj 👋🏻,
In your case, if your svg element has a previous animation with panzoom before your running code, the svg.getBoundingClientRect(); values could be wrong.
@ystreibel Yes, that's why it's normalized using const originWidth = rectScene.width / xys.scale
and that current animation is stopped.
@marcj, I tried your code in mine and current animation isn't stopped. If you want to reproduce do
this.graphPanZoom = panzoom(inkSvg, { autocenter: true, bounds: true });
just before
const svg = YOUR_SVG_ELEMENT HERE;
in window load event listener
function loaded {
HERE THE CODE
}
window.addEventListener("load", loaded, true);
autocenter: true
doesn't use any animations, so I don't know where your previous animation is coming from that isn't stopped via panZoom.pause()
. Of you use css transitions, then you should probably remove them.
No animations right but transform is processing via autocenter()
call.
I try to made this codepen to explain the fact .
Feel free to contribute.
try this maybe?
const container = document.querySelector('div');
panzoom.showRectangle(container.getBoundingClientRect());
panzoom.moveBy(0,0); //required to set the css transforms, as the last command only sets it internally.
greetings. thx for the great lib. i see that you offer
.zoomAbs(...)
, but my content is unknown ahead of time. how would you feel about offering a.fit()
method that zoomed in/out to fit the panzoom content to the content container?thanks!