chrvadala / react-svg-pan-zoom

:eyes: A React component that adds pan and zoom features to SVG
https://chrvadala.github.io/react-svg-pan-zoom/
MIT License
681 stars 127 forks source link

Allow for easing functions on transform #151

Open TimVanMourik opened 5 years ago

TimVanMourik commented 5 years ago

Feature request

Especially on a 'zoom to fit', it would be pretty neat if you could specificy a transition and a maybe a transition-ease-function.

Specifically, viewer.js would need to be updated: https://github.com/chrvadala/react-svg-pan-zoom/blob/334de3a04ab48f45bd954715f0a3b8feeebe5036/src/viewer.js#L358-L360

One way to support this is with a transition prop in seconds and maybe an easeFunction prop with option as EASE_IN_OUT, EASE_LINEAR, etc.

I can give it a shot, if you want, if you have name a preferred implementation.

chrvadala commented 5 years ago

It seems a good feature, we might introduce a new prop to manually enable this extra feature. I was wondering if using a css transition is enough. Feel free to start with a PR ;)

krnlde commented 4 years ago

CSS transition unfortunately add a huge delay. I didn't quite understand why. You don't see any animation until you stop panning / zooming. Also CSS transitions don't feel very natural since the momentum/inertia is not calculated.

Here's the CSS I used:

.pan-zoom-wrapper > svg > g {
  transition: transform .1s ease-out;
}

A class to determine the transforming <g> element would be helpful to better select that.

kriwi-jtpln commented 4 years ago

I recently ran into the same problem with the css transitions. What worked for me was to disable the transition during manual drag and zoom and use a state to add a class to the pan-zoom-wrapper. Its a hack but does the job.

<ReactSVGPanZoom
              ...
              className={`ReactSVGPanZoom ${renderWithTransition ? 'with-transition' : ''}`}
              onMouseDown={() => setRenderWithTransition(false)}
              onTouchStart={() => setRenderWithTransition(false)}
>

...and enable the class again when using fitToViewer or others

const onFitToViewer = () => {
    setRenderWithTransition(true)
    panZoomRef.current.fitToViewer(ALIGN_CENTER, ALIGN_CENTER)
  }

And big thanks for this great library.

ulo commented 3 years ago

Hi, I would love to get a smooth scrolling by using transitions! However, CSS transitions somehow do not work for me... I guess it is because the transform is an SVG attribute and not CSS. Moving to CSS transformation, i.e. from

<g 
   transform={toSVG(value)} 
   style={blockChildEvents ? {pointerEvents: "none"} : {}}>

to

<g 
   style={blockChildEvents ? {pointerEvents: "none"} : { transform: toSVG(value), transition: "transform ease 0.1s" }}>

works very nice and very smooth for the zoom!

But does not really work for pan...