d3 / d3-zoom

Pan and zoom SVG, HTML or Canvas using mouse or touch input.
https://d3js.org/d3-zoom
ISC License
507 stars 143 forks source link

Made constrain about viewport center (experiment!) #118

Closed Herst closed 7 years ago

Herst commented 7 years ago

Not really a serious PR but more of food for thought (please feel free to close it).

My fork here is the result of an experiment of my project where users can do remote collaborative work with visualizations in real-time.

In this project it is possible to share views but because the viewports of users can differ a lot I decided to make everything about the view center, e.g. the coordinates shared are the values of the SVG transform in the current view center (subtracting half of map width/height). Also when resizing the viewport the centered content stays centered.

This fork here is then about making the constrains also all about the center, so that e.g. .translateExtent() only restricts panning insofar as to make sure that the center of the view is restricted making it independent of the viewport (otherwise users with different viewports would have different restriction for which coordinate positions [representing the viewport center] they can reach). I guess I could have alternatively set .translateExtent dynamically but I doubt that this would have been a nicer solution.

Now I have no idea whether this would be worth allowing in d3.zoom and if yes then how; maybe constrain() could be made replaceable altough this would mean four additional parameters. So this is why this here is not a serious PR (and again please feel free to close it) and I would just like to have some input.

(On a side node, in my project I tried using separate transforms for d3.zoom and the centering stuff, see https://stackoverflow.com/q/46533546/2261442, but in the end I wasn't able to come up with a useful solution, my own answer which I accepted also has severe drawbacks)

Herst commented 7 years ago

I just came up with an alternative idea in which this could be achieved. Simply make the extent which constrain() uses separate from the one used elsewhere. This way someone could set this new constrainExtent to [[center, center], [center, center]] and achieve the same goal. What do you think?

mbostock commented 7 years ago

My preference would be to add a zoom.constrain method which lets you override the definition of constrain, with the default implementation being today’s implementation. We employ a similar strategy for zoom.filter and zoom.extent.

Please review #119. Thank you!