You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Svelte Canvas缩放平移后,修正坐标实现光标处画线

解决Canvas缩放平移后画线光标偏移问题

问题根源是绘制时未将屏幕光标坐标转换为Canvas变换后的逻辑坐标。你的Canvas已经通过trackTransforms实现了坐标变换能力,但绘制代码直接使用原始屏幕坐标,导致线条位置与光标偏离。

修改关键代码

只需要调整handleStart和handleMove函数,利用已有的transformedPoint方法转换坐标:

const handleStart = ({ offsetX: x, offsetY: y }) => {
    isDrawing = true;
    // 将屏幕坐标转换为Canvas变换后的逻辑坐标
    const transformedPt = ctx.transformedPoint(x, y);
    start = { x: transformedPt.x, y: transformedPt.y };
};

const handleMove = (event) => {
    if (!isDrawing) return;

    // 直接使用已声明的ctx,无需重新获取
    const { offsetX: x, offsetY: y } = event;
    // 转换当前光标坐标
    const currentPt = ctx.transformedPoint(x, y);

    const { x: startX, y: startY } = start;

    ctx.beginPath();
    ctx.moveTo(startX, startY);
    ctx.lineTo(currentPt.x, currentPt.y);
    ctx.stroke();

    // 更新起始点为转换后的坐标
    start = { x: currentPt.x, y: currentPt.y };
};

核心修改点说明

  1. 坐标转换:使用ctx.transformedPoint(x, y)将屏幕上的offsetX/offsetY转换为Canvas经过缩放、平移后的逻辑坐标,确保绘制位置与光标匹配。
  2. 复用上下文:直接使用已初始化的ctx变量,避免重复调用getContext造成的性能浪费和潜在问题。
  3. 更新起始点:每次绘制后,将起始点更新为转换后的当前坐标,保证连续绘制的线条连贯。

额外优化建议

  • 移除handleMove中重复获取canvas和context的代码,直接使用组件内已声明的变量。
  • 若需要保留绘制的线条(当前平移/缩放会清空线条),可将线条路径记录在数组中,在redraw函数里循环重绘所有路径。

内容的提问来源于stack exchange,提问作者R.alim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 14:16:47