retyui/react-quick-pinch-zoom

Calling scaleTo with outside control returns element to start position

maestor opened this issue · 3 comments

Hi! Thanks for great library! I have one issue which can't solve and don't understand why it happens, so write here.

Use case:

  • Draggable and zoomable item should be zoomIn and zoomOut also by keyboard or zoom buttons

Own expectations:

  • Position would stay where it was when press the button

Actually happens:

  • Element scale correctly, but onUpdate will called as long as x and y are back to 0

Codesandbox: https://codesandbox.io/s/sad-dijkstra-x98nd

  • To reproduce: Zoom container for example with wheel, drag it somewhere. Press then - or + button which trigger scaleTo
  • I have much more stuff inside children than one image, but this is simplest example and children div styles are same than mine real implementation. Also QuickPinchZoom component props are same than mine real case.

So, am I doing something wrong here? How I get the position staying to where it have dragged? I can see scaleTo took first correct position and moves there, then start this onUpdate iterating back to initial position.

Hi there! I am trying to implement + and - zoom buttons too and I'm running into the same issues as stated above.
After scaleTo is triggered with the new scale by clicking on the zoom button, onUpdate is called multiple times: first with the original/previous scale and current correct coordinates and then it's called again with the new scale but different x and y values until they are 0.

I'd really appreciate your help! Thanks!

@maestor you can't reuse x,y cords from an onUpdate event, as it ONLY for css translation function!

to make zoom in \ zoom out you need to remember a poison of cursor\touches to continue scaling at that point

You can use internal methods to make this functionality:

import QuickPinchZoom from "react-quick-pinch-zoom";

class MyPinchZoom extends QuickPinchZoom {
  _lastScaleToCenter = { x: 0, y: 0 };

  // owerwrite private method
  _scaleTo = (zoomFactor: number, center: Point) => {
    this._lastScaleToCenter = center; // remember the last center
    this._scale(zoomFactor / this._zoomFactor, center);
  };

  zoomIn() {
    this._stopAnimation();
    this._scaleTo(this._zoomFactor * 1.2, this._lastScaleToCenter);
    this._update();
  }

  zoomOut() {
    this._stopAnimation();
    this._scaleTo(this._zoomFactor / 1.2, this._lastScaleToCenter);
    this._update();
  }
}

// ------------------
// Usage

<>
  <MyPinchZoom ref={ref} />;
  <button onClick={() => ref.current?.zoomIn()}>+</button>
  <button onClick={() => ref.current?.zoomOut()}>+</button>
</>;

Also if you want to implement this functionality out of box, PR your welcome!