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

如何在SVG中实现鼠标移动绘制平滑曲线?

在SVG中替换直线绘制为平滑二次贝塞尔曲线

要把SVG中的直线绘制替换为和Canvas QuadraticCurveTo 效果一致的平滑曲线,需要利用SVG的二次贝塞尔曲线指令Q,配合中点计算来实现。具体修改步骤如下:

1. 完善鼠标按下时的路径初始化

首先在mouseDown函数中,给新建的path元素添加初始路径指令(移动到起始点),否则后续的曲线指令会无效:

function mouseDown(event) {
    isMouseDown = true;
    var shape = document.createElementNS(NS, "path");
    shape.setAttribute("id", "pen" + penCount);
    // 新增:初始化路径,移动到鼠标按下的位置
    lastPoint = { x: event.offsetX, y: event.offsetY };
    shape.setAttribute("d", `M ${lastPoint.x} ${lastPoint.y}`);
    
    stage.append(shape);
    ++penCount;
}

2. 修改鼠标移动时的曲线绘制逻辑

把mouseMove中的直线指令L替换为二次贝塞尔曲线指令Q,利用你已经计算好的中点来实现平滑过渡:

function mouseMove(event) {
    if (isMouseDown) {
        var currentPath = jQuery('#pen' + (penCount - 1));
        var currentD = currentPath.attr("d");
        var currentPoint = { x: event.offsetX, y: event.offsetY };
        
        // 计算上一点与当前点的中点
        var midPoint = [(lastPoint.x + currentPoint.x) / 2, (lastPoint.y + currentPoint.y) / 2];
        
        // 使用SVG Q指令绘制二次贝塞尔曲线:Q 控制点X 控制点Y 终点X 终点Y
        // 这里以上一次的鼠标点作为控制点,中点作为曲线终点,保证平滑过渡
        currentPath.attr("d", currentD + ` Q ${lastPoint.x} ${lastPoint.y} ${midPoint[0]} ${midPoint[1]}`);
        
        // 更新上一点为当前鼠标点,用于下一次计算
        lastPoint = currentPoint;
    }
}

原理说明

  • SVG的Q指令格式为Q [控制点X] [控制点Y] [终点X] [终点Y],对应Canvas的quadraticCurveTo(控制点X, 控制点Y, 终点X, 终点Y)。
  • 通过每次取上一鼠标点与当前鼠标点的中点作为曲线终点,以上一鼠标点作为控制点,能让连续绘制的曲线段自然平滑衔接,避免折线感。

内容的提问来源于stack exchange,提问作者FasterWork

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:05:21