Feature (Epic?): Improve Panzoom for nested content use case (list of components, etc.) #642
Labels
feature
votes needed
Feature requests are closed at first, but will be implemented with enough upvotes
What problem does this feature solve?
High-level idea: It would be really cool to be able to use
Panzoom
to enable an interactive "infinite canvas" like Figma/Miro, and use thePanzoom
library to pan/zoom around the content. Same use case as was discussed in #472.The content on said "canvas" should be assumed it will be dynamic, for example binded to a reactive Vue/React array of objects (
[{id:1}, {id:2}, {id:3}
]. When the content changes, Panzoom should re-calculate its initial/reset coordinates based on the new width/height of the contents container. It should be easy to call a method which places the content in the center of the screen, and zooms out so that all the content is visible. It should be easy call a method which pans + zooms to a given DOM Element, so that element is in the center of the screen. Focal zooming andpan()
andzoom()
should still work, but be aware of the contents position instead of just the "Panzoom Child" (aka Panzoom instance) element.Here's an example of the intended interactions:
--
Panzoom
library consumers can already enable moving the content around like shown above using thecanvas
option (#472, Docs), which is a really helpful start!HTML
JS
With just this code^, the result looks like this:
Please see the Problem demo for the code.
The most obvious things missing to achieve the goal mentioned above are:
pan()
andzoom()
, but the calculations are not straightforward, because position is not calculated based on the contents.panzoom.reset()
method could also keep track of what the correct x/y and scale would be so that the content would fit within the viewport. The options forstartX
,startY
,startScale
can be set manually, but would be great if the calculations were handled automatically.transform-origin: 50% 50%
, but the x:0, y:0 coordinates become confusing quickly because when using thecanvas
option and when the "Panzoom Contents" are dynamic and using styles likedisplay: inline-block
orflex
orgrid
.focal
is not easily adjusted to the dynamic contents, instead of the "Panzoom Child" (instance) elementzoomToPoint()
exists... but I wasn't able to figure out how to properly calculate theclientX
andclientY
values to pass to it in this case.contain
maxPanRatio
It's not clear to what extent these features could/should be handled by Panzoom library or should be handled by consumers, so I definitely understand if not all of this makes sense in the scope of the library.
Describe the solution you'd like
Here's an attempt at some specific changes to
Panzoom
which would enable some of the needs, and some idea for how to name things, but probably it needs more iteration/feedback.content
option: override which DOM Element Panzoom will use for calculations of x, y and scale, taking into account the height/width of the element.#panzoom-contents
). Focal zooming, panning, etc. should then be relative to this element.content
DOM Element's height/width and update the Panzoom instance accordingly, to avoid jankiness with Panzoom and coordinates? Perhaps withresizeObserver
?content
DOM Element and adjust the calculations depending on if the element isblock
orinline
? Something similar mentioned here: Focal zoom with flex-centered images #611 (comment)'auto'
option tostartX, startY, startScale
to let Panzoom automatically calculate the appropriate x/y/scale which fits the content within the container when the instance is initialized andreset()
zoomPadding: 0.25
to specify how much padding (%) to add between the contents and the container when auto-calculating the scale (startScale: 'auto'
)zoomToElement()
method to zoom in to a specific DOM Element which exists within the Panzoom element, and let Panzoom visually center it within the container. This can also factor in the optionzoomPadding
.contain
or something likemaxPanRatio
to help keep the user from moving way outside of the container and getting lost. Maybecontain: 'content'
, if we have thiscontent
concept? (Relates to Feature: New contain option for both inside/outside #598, Feature: 3rd contain option (mix of both inside and outside) #504, Feature: contain: 'outside', but allow the image to fit the container? #577, Feature: Limit pan distance outside of canvas, e.g. maxPanRatio #476)Example:
Describe alternatives you've considered
Of course, all these features could somehow be handled somehow by
Panzoom
library consumers. But it would be awesome to not have to hack it in a way that it wasn't meant to be used.Alternative 1: Changing
transform-origin
to0 0
instead of default50% 50%
to make it easier to work with the x/y coordinate system0, 0
coordinate system, but it makes other things like adjusting the zoom to work again difficult.focal
point orzoomToPoint()
for scroll zooming (e.g. scroll wheel zoom in/out towards mouse position)focal
and suggestion of usingzoomToPoint()
:zoomToPoint
: help with zoomToPoint #521 (comment)zoomToPoint()
it is also unclear how to calculate theclientX
andclientY
for the goals described.The text was updated successfully, but these errors were encountered: