React画布画笔工具拖动时路径断断续续怎么办?

令狐美美 阅读 32

我在用React做画板功能,鼠标拖动时画笔路径总是出现断点,看起来很不连贯。代码逻辑是这样的:


const [points, setPoints] = useState([]);
const [isDrawing, setIsDrawing] = useState(false);

const handleMouseMove = (e) => {
  if (!isDrawing) return;
  setPoints(prev => [...prev, {x: e.clientX, y: e.clientY}]);
};

useEffect(() => {
  const draw = () => {
    ctx.beginPath();
    points.forEach((p, i) => {
      if(i === 0) ctx.moveTo(p.x, p.y);
      else ctx.lineTo(p.x, p.y);
    });
    ctx.stroke();
  };
  draw();
}, [points]);

我已经尝试给handleMouseMove加了throttle节流,但拖动速度快的时候还是会有断点。是不是因为setState更新太慢?或者ctx的绘制方式有问题?求大佬指点

我来解答 赞 8 收藏
二维码
手机扫码查看
1 条解答
程序猿怡然
问题出在你每次更新points状态时都会触发重新渲染,导致绘制性能跟不上。试试用requestAnimationFrame来优化绘制逻辑:

let animationFrameId;
useEffect(() => {
const draw = () => {
ctx.beginPath();
points.forEach((p, i) => {
if(i === 0) ctx.moveTo(p.x, p.y);
else ctx.lineTo(p.x, p.y);
});
ctx.stroke();
animationFrameId = requestAnimationFrame(draw);
};
return () => cancelAnimationFrame(animationFrameId);
}, [points]);

const handleMouseMove = (e) => {
if (!isDrawing) return;
setPoints(prev => [...prev, {x: e.clientX, y: e.clientY}]);
if (!animationFrameId) requestAnimationFrame(draw);
};


这样可以避免重复绘制,提升流畅度。
点赞 5
2026-02-01 20:01