HTML5 Canvas - 二次曲线的意外效果

时间:2011-12-28 18:28:28

标签: html5 canvas curvesmoothing

我最近一直在为一个涂鸦应用而努力。在尝试了许多方法用鼠标给出的样本点绘制平滑曲线后,我已经使用二次曲线找到了一些东西。

我必须承认,我对这些曲线的理解不是最佳的,但我想我理解它们是如何工作的。我无法理解的是,当我绘制一条向上然后突然向下的曲线时,曲线的峰值不再呈圆形(它看起来很扁平)。

更好地了解我正在谈论的内容:link to JCanvas sandbox

如果删除曲线的最后部分(从cx11到y15):link to another JCanvas sandbox。它看起来很好,但是当你添加下一个控制点和终点时,你会得到这种奇怪的效果。

注意:我没有使用JCanvas,但它有相同的bug,沙盒很方便。我想它来自我得到的坐标,但我无法解释,也无法找到一个解决方法/黑客让它看起来圆润......

对于那些不喜欢沙盒的人来说,这里是导致问题的坐标的简短版本:

x1:216,y1:98, cx1:216,cy1:97, x2:216,y2:98, cx2:216,cy2:99, x3:215,y2:103,

为什么有任何想法?数学的东西是受欢迎的。我已经做了一些关于这个问题的搜索和阅读,但没有找到类似的东西。

-

更新

正如Simon指出的那样,我正在使用Chrome 16,我已经使用Firefox 4和最新的Safari测试了这个示例,并且存在错误。我试过Opera,它看起来很好。

我对此感到非常沮丧,因为这个错误也出现在iPad上,我试图做一个移动网络应用程序,所以我有点陷入困境。

解决方法/黑客的任何想法?

1 个答案:

答案 0 :(得分:1)

找到了解决方法。这是一个愚蠢的方法 - 零错误之一,我真的不知道它们的正确名称。如果两点之间的连接是非常小的垂直线并且Safari感到困惑,那么很难绕过角落。

在问题所在位置,有一条1像素高的垂直线曲线,需要进行舍入。

如果X目的地在一条二次曲线与下一条曲线之间相同,则safari会给您带来问题。所以这很糟糕:

ctx.beginPath();
ctx.moveTo(161,178);
ctx.quadraticCurveTo(215, 102, 216, 100);
ctx.quadraticCurveTo(216, 98, 216, 98);
ctx.quadraticCurveTo(216, 99, 215, 103); // I have the same X as the previous quadratic
ctx.quadraticCurveTo(213, 107, 211, 120);
ctx.quadraticCurveTo(209, 133, 209, 145);
ctx.stroke();

请在此处查看:http://jsfiddle.net/Ws6UY/

因此,如果我们只是将该值更改为最小的数量:

ctx.beginPath();
ctx.moveTo(161,178);
ctx.quadraticCurveTo(215, 102, 216, 100);
ctx.quadraticCurveTo(216, 98, 216, 98);
ctx.quadraticCurveTo(216.01, 99, 215, 103); // 216.01 is not the same X as 216!
ctx.quadraticCurveTo(213, 107, 211, 120);
ctx.quadraticCurveTo(209, 133, 209, 145);
ctx.stroke();

请在此处查看:http://jsfiddle.net/Ws6UY/1/

多么愚蠢!要使safari / iOS浏览器保持正常工作,您需要做的就是确保x(可能是y)值与最后一点不同。