放大光标时如何防止图像跳动

时间:2019-07-16 21:06:40

标签: javascript css reactjs zoom react-spring

将鼠标光标移到图像上并滚动。图像平滑放大或缩小。现在,再次执行相同的操作,但是在动画即将完成之前,尝试放大其他点。图像跳动。另请参见this gif。向鼠标滚轮发送垃圾邮件时,即使光标在滚轮事件之间移动,也不会出现问题 。似乎只有在上一个动画的末尾发生连续的车轮事件时才会发生。

我尝试了两件事:

  • useSpring钩子中读取当前应用的转换(请参见存储库中的3597d2c36cf2ff63266e07a5dabe714d8bb7c233)
  • 直接从图像中读取当前应用的转换(最新提交)。

放大和缩小光标有效。如果让动画结束,则动画将起作用。我只是在试图解决最后一个怪胎。

可以在this repository中找到该代码。我已经建立了最小的失败案例。只需npm install,后跟npm run start,它就会打开浏览器。要求node可用。

核心部分是这个

  // props contains the current values we can use for interpolation
  const [props, set] = useSpring(() => ({
    translateX: 0,
    translateY: 0,
    scale: 1
  }));

  // Store a reference to the DOM node holding the actual iamge
  const imgRef = React.useRef(null);

  const handleOnWheel = ({
    deltaY,
    clientX,
    clientY,
    target,
    currentTarget
  }) => {
    // The handleOnWheel function is attached to the *container*
    // of the image. We therefore need to translate the coordinates
    // of the mouse into the coordinates of the image *within the
    // container*. That's done by the getBoundingClientRect() call
    // together with the calculation for nextCoords
    const { left, top } = target.getBoundingClientRect();

    const nextCoords = {
      x: clientX - left,
      y: clientY - top
    };

    // Nothing fancy, just getting the currently applied transforms
    // so that the value is up to date
    const [_, translateStr, scaleStr] = imgRef.current.style.transform.match(
      /translate\((.*)\)\sscale\((.*)\)/
    );

    const [translateX, translateY] = translateStr
      .split(",")
      .map(str => str.replace("px", "").trim())
      .map(Number);

    const scale = Number(scaleStr);

    // Calculate the next transform value to zoom in on cursor. Works
    // just fine, minus the image jump when zooming in at the end of the        
    // animation
    const nextValues = getNextTransformValues({
      scale,
      translateX,
      translateY,
      ...nextCoords,
      getNextScale: deltaY > 0 ? () => 1 / (1 + 0.6) : () => 1 + 0.6
    });

    set(nextValues);
  };

预期结果:图像在光标上平滑放大 实际结果:图像跳动并稍微放错了位置。

0 个答案:

没有答案