【问题标题】:Equivalent of canvas quadraticCurveTo in SVGSVG中画布quadraticCurveTo的等价物
【发布时间】:2015-06-23 14:10:45
【问题描述】:

我正在开发一个插件,以允许使用鼠标或触摸来绘制“自然外观”的签名。用户确认后,结果将是一个存储的 SVG,然后可以显示在“点击签名”按钮的位置。

附加的 JSFiddle http://jsfiddle.net/TrueBlueAussie/67haj4nt/3/ 显示了我正在尝试做的事情的测试平台。 SVG 生成的图像应该看起来接近原始画布路径。

第一个 div 包含一个canvas,我在其中绘制了一些多段线(例如路径)。使用quadraticCurveTo 和控制点的中点,我用平滑曲线绘制线条。这工作得很好。

曲线绘制的关键部分是:

$.each(lines, function () {
    if (this.length > 0) {
        var lastPoint = this[0];
        ctx.moveTo(lastPoint[0], lastPoint[1]);
        for (var i = 1; i < this.length; i++) {
            var point = this[i];
            var midPoint = [(lastPoint[0] + point[0]) / 2, (lastPoint[1] + point[1]) / 2];
            ctx.quadraticCurveTo(lastPoint[0], lastPoint[1], midPoint[0], midPoint[1]);
            lastPoint = point;
        }
        // Draw the last line straight
        ctx.lineTo(lastPoint[0], lastPoint[1]);
    }
});

我尝试了多个选项来生成相同输出的 SVG,但我不知道如何将相同的点集转换为等效的曲线。二次贝塞尔曲线需要“适当的”控制点,但如果可能,我更愿意使用更简单的中点

有什么想法吗?这是可能的还是我必须将两者都转换为使用带有计算控制点的贝塞尔曲线。有没有一种简单的方法来计算可以完成相同工作的控制点?

jQuery 或原始 JavaScript 解决方案都可以,但您需要在提供的 JSFiddle 中进行演示 :)

【问题讨论】:

  • 只是好奇。您使用二次曲线的方式(控制点位于直线的中点)只会产生一条直线。它有点违背了使用曲线的意义。
  • 我的观点是正确的。当控制点在两点的精确中点时,二次贝塞尔曲线将是一条直线。请参阅:jsfiddle.net/5bjbu3px 但是我现在看到您在画布版本中使用的坐标与在 SVG 版本中使用的坐标不同。在画布版本中,您正在绘制中点并将数组点用作控制点。

标签: javascript jquery canvas svg bezier


【解决方案1】:

这只是您的代码中的一个错误。您没有在 SVG 版本中更新 lastPoint

http://jsfiddle.net/67haj4nt/4/

如果您更新 SVG 版本以匹配画布版本,您将获得相同的曲线。

http://jsfiddle.net/67haj4nt/5/

【讨论】:

  • 很好看。一定搞砸了剪切/粘贴。谢谢。
  • 我刚刚注意到 SVG 没有画出完整的线条。每条路径的两端都比画布版本短。添加缺失的片段。
  • 添加缺失的结束段后,我注意到线条在结束点之前停止:jsfiddle.net/TrueBlueAussie/67haj4nt/6 这是 SVG 功能(不包括线条的最后一个像素)还是画布版本过度绘制?
  • 我想这将是因为结尾lineTo() 在画布版本中,而不是在 SVG 版本中。
  • 谢谢,但很抱歉,这与我给您的链接有何不同?每条路径的最后一行似乎短了一个像素。那是因为 SVG 线不包括终点/像素吗?
猜你喜欢
  • 2013-08-09
  • 1970-01-01
  • 2020-11-04
  • 1970-01-01
  • 1970-01-01
  • 2019-11-03
  • 1970-01-01
  • 1970-01-01
  • 2020-10-03
相关资源
最近更新 更多