将鼠标光标移到图像上并滚动。图像平滑放大或缩小。现在,再次执行相同的操作,但是在动画即将完成之前,尝试放大其他点。图像跳动。另请参见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);
};
预期结果:图像在光标上平滑放大 实际结果:图像跳动并稍微放错了位置。