Open enekesabel opened 5 years ago
Without having any context how this lib actually does it: the preventPanOutside
calculation seems to use the opposite corners. The calculation could be "corrected" to match your request if the left corner adds the SVGs width, the right corner substracts the width, top adds the height and bottom substracts it - but it's probably easier to just exchange sides (left<-> right, top <->bottom). I'm not sure how @chrvadala calculates the boundaries but you/he could use the corresponding values provided by .getBoundingClientRect()
/ .getBBox()
with the applied .getScreenCTM().inverse()
/ .getCTM().inverse()
to do that.
I agree and I also need this feature, if I find some time I might implement it and create a PR
It's a bit of a hack, but you catch pan events with onPan
and limit the values to within the SVG and passing your new doctored values to setState
. In the values
object, e
refers to x-axis translation, and f
refers to y-axis translation. It's worth noting that the translations describes the movement of the SVG, so by panning an SVG up (scrolling down the 'page'), f
goes from 0
into negative digits.
I'm using it here to disable left/right pan (I've got the SVG width set to fill the viewer), then by working out the scaling factor, I can get the height of the scaled SVG (and then I take away the viewer height as the number basically refers to the top of the viewer window):
onPan={value=>{
//calculate scaled SVG height minus a single viewer height
const scaledMaxHeight = (value.SVGHeight/(value.SVGWidth/value.viewerWidth))-value.viewerHeight
this.setState({value:{
...value,
// prevents panning left/right
e:0,
// limit up/down panning to within the SVG
f: value.f>0?0
:value.f<0-scaledMaxHeight?0-scaledMaxHeight
:value.f
}})
}}
I started building this feature: https://codesandbox.io/s/react-svg-pan-zoom-testing-wm6ssl (and abandoned it, because it's not really a must-have for our app)
But intercepting the value in onPan
gets quite janky because the UI gets adjusted after the fact. What would probably work very fluidly is using a custom setValue
function that corrects out-of-bounds values.
I'm also looking forward to that feat. As it might be a must have for our app, may have a look if no one else has implemented it and if not requiring to much time to implement . Will let you know if I have a working POC
EDIT: Think I've got basic implementation by listening to value changes and restricting depending on image displayed size This is still of an hack for now with some values tweaked on the fly but to give an idea, relevant piece of code I used:
// image displayed size (after zoom scale applied)
const onScreenWidth = SVGWidth * widthScale;
const onScreenHeight = SVGHeight * heightScale;
// compute max offsets
const maxWidthOffset = viewerWidth - onScreenWidth + 5;
const maxHeightOffset = viewerHeight - onScreenHeight + 5;
// adjusting current pan values to match offset boundaries
widthOffset = Math.min(0, Math.max(widthOffset, maxWidthOffset));
heightOffset = Math.min(0, Math.max(heightOffset, maxHeightOffset));
Link to working POC which may be updated later on: https://l4p4qq.csb.app/
Hi,
Is it possible to restrict the viewer going outside the boundaries of the SVG element? I'd like to achieve a map-like behavior where you can navigate only inside the svg map. I thought preventPanOutside will do exactly that, but it lets the user drag the map till the corners of the viewer.
Could somebody point me in the right direction?
Thanks, Abel