如何在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
相关产品推荐
相关产品推荐

