简体   繁体   English

Fabric js:单击按钮时画布居中并缩放到对象

[英]Fabric js: when button is clicked center canvas and zoom to object

I'm trying to center the viewport on an object and zoom in/out when i click a button.我试图将视口集中在一个对象上,并在单击按钮时放大/缩小。 I want to have an animation.我想要一个动画。 To do this I'm using setInterval and moving the viewport in increments like so:为此,我使用 setInterval 并像这样以增量方式移动视口:

const objectCenterCoordenates = {
    x: Math.round(rect1.left + rect1.width / 2),
    y: Math.round(rect1.top + rect1.height / 2)
  };
  const centeredCanvasCoordenates = {
    x: objectCenterCoordenates.x - canvas.width / 2,
    y: objectCenterCoordenates.y - canvas.height / 2
  };

  let currentPoint = {
    x: Math.round(canvas.viewportTransform[4]) * -1,
    y: Math.round(canvas.viewportTransform[5]) * -1
  };

  console.log("Start animation");
  let animation = setInterval(() => {
    console.log("New frame");

    if (canvas.getZoom() !== 2) {
      let roundedZoom = Math.round(canvas.getZoom() * 100) / 100;
      let zoomStep = roundedZoom > 2 ? -0.01 : 0.01;
      let newZoom = roundedZoom + zoomStep;
      canvas.zoomToPoint(
        new fabric.Point(currentPoint.x, currentPoint.y),
        newZoom
      );
    }

    let step = 5;

    let vpCenter = {
      x: Math.round(canvas.getVpCenter().x),
      y: Math.round(canvas.getVpCenter().y)
    };
    if (
      vpCenter.x === objectCenterCoordenates.x &&
      vpCenter.y === objectCenterCoordenates.y
    ) {
      console.log("Animation Finish");
      clearInterval(animation);
    }

    let xDif = Math.abs(vpCenter.x - objectCenterCoordenates.x);
    let yDif = Math.abs(vpCenter.y - objectCenterCoordenates.y);

    let stepX =
      Math.round(vpCenter.x) > Math.round(objectCenterCoordenates.x)
        ? -step
        : step;
    if (Math.abs(xDif) < step)
      stepX =
        Math.round(vpCenter.x) > Math.round(objectCenterCoordenates.x)
          ? -xDif
          : xDif;
    let stepY =
      Math.round(vpCenter.y) > Math.round(objectCenterCoordenates.y)
        ? -step
        : step;
    if (Math.abs(yDif) < step)
      stepY =
        Math.round(vpCenter.y) > Math.round(objectCenterCoordenates.y)
          ? -yDif
          : yDif;

    currentPoint = {
      x: currentPoint.x + stepX,
      y: currentPoint.y + stepY
    };

    canvas.absolutePan(new fabric.Point(currentPoint.x, currentPoint.y));
  }, 4);

But sometimes, I haven't been able to determine why, it gets stuck in a loop moving a few pixels one way then going back the other.但有时,我无法确定原因,它卡在一个循环中,一个方向移动几个像素,然后返回另一个方向。 And the zoom is well implemented, since it's possible to get to the object before it finished zooming in/out.并且缩放实现得很好,因为可以在对象完成放大/缩小之前到达对象。

Here is a codepen with my code: https://codepen.io/nilsilva/pen/vYpPrgq这是我的代码的代码笔: https ://codepen.io/nilsilva/pen/vYpPrgq

I would appreciate any advice on making my algorithm better.我将不胜感激有关使我的算法更好的任何建议。

Looks like you have an exact match requirement for your clearInterval ...看起来您对 clearInterval 有完全匹配的要求...

    if (
      vpCenter.x === objectCenterCoordenates.x &&
      vpCenter.y === objectCenterCoordenates.y
    ) {
      console.log("Animation Finish");
      clearInterval(animation);
    }

The case that you describe stuck in a loop moving one way then going back the other is because the exact match it's never done, could be because the step you are taking or it could be a rounding issue您描述stuck in a loop moving one way then going back the other是因为它从未完成的完全匹配,可能是因为您正在采取的步骤,或者它可能是一个舍入问题

You can use Math.hypot to check if the two points are close enough, read more here:您可以使用Math.hypot检查两个点是否足够接近,请在此处阅读更多信息:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot

The condition will look like:条件将如下所示:

    if (Math.hypot(
      vpCenter.x - objectCenterCoordenates.x,
      vpCenter.y - objectCenterCoordenates.y
    ) < step) {
      console.log("Animation Finish");
      clearInterval(animation);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM