Monday, 11 October 2021

Zoom In Canvas And Then Zooming Out in a different mouse position Breaks Background Display

I'm trying to implement a zoom function on my canvas keeping the mouse position relative to where it was before.

This function accomplishes it almost. And here is a full example: https://codepen.io/PJEstrada006/pen/dyRxVXE?editors=0011

  public zoom_wheel_canvas_translate(event): void {
    // this is the illusionary point on UI that we wish to stay locked on
    let point = this.mouse_position;
    const wheel = event.deltaY < 0 ? 1 : -1;

    // Compute zoom factor.
    let zoomIntensity = 0.2;
    let zoom = Math.exp(wheel * zoomIntensity);
    this.scale = this.scale * zoom;

    if (this.scale <= 1) {
      this.canvas_ctx.setTransform(1, 0, 0, 1, 0, 0);
      this.scale = 1;
      return
    }
    if (this.scale >= 30) {
      this.scale = 30
    }
    this.canvas_ctx.clearRect(
      0,
      0,
      this.canvas_elm.width,
      this.canvas_elm.height
    );

    let transform = this.canvas_ctx.getTransform();
    this.canvas_ctx.resetTransform();
    this.canvas_ctx.translate(point.x, point.y);
    this.canvas_ctx.scale(zoom, zoom);
    this.canvas_ctx.translate(-point.x, -point.y);
    this.canvas_ctx.transform(transform.a, transform.b, transform.c, transform.d, transform.e, transform.f)
    let transform_new = this.canvas_ctx.getTransform();
    console.log('a', transform.a, 'd', transform.d)
    console.log('e', transform.e, 'f', transform.f)



  }

I have an image set as the background of the canvas that gets drawn like this:

    ctx.drawImage(
      this.image,
      0,
      0
    )

The problem is that if I do something like the following:

  1. Place the mouse on center of screen.
  2. Zoom In (Works well)
  3. Move the mouse to another place.
  4. Keep Zooming In
  5. Zoom Out All the way to scale being 1

The zoom out eventually ends up translating the canvas in the wrong way and my canvas image appears "sliced" or incomplete due to incorrect translations or scales. This happens just before the scale becomes 1, then it fixes itself because I have a resetTransform() call when scale = 1.

I'm expecting that no matter how I move the mouse I eventually zoom out and end up with the original transform matrix (identity matrix).

Can anyone help me spot what I'm doing wrong with my transforms. I don't quite get why it works perfect if I don't move the mouse, but stops working if I move the mouse in a zoomed in state and then zoom out.



from Zoom In Canvas And Then Zooming Out in a different mouse position Breaks Background Display

No comments:

Post a Comment