【问题标题】:HTML5 Canvas - Unexpected effect with Quadratic CurvesHTML5 Canvas - 二次曲线的意外效果
【发布时间】:2012-01-29 09:25:23
【问题描述】:

我最近一直在开发一个涂鸦应用程序,只是为了好玩。在尝试了多种方法用鼠标给出的样本点绘制平滑曲线后,我决定使用二次曲线。

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

演示会更好地理解我在说什么:link to JCanvas sandbox

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

注意:我没有使用 JCanvas,但它也有同样的错误,而且沙箱很方便。我猜它来自我得到的坐标,但我无法解释,也找不到解决方法/黑客让它看起来圆润...

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

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 上,而我正在尝试做一个移动网络应用程序,所以我有点卡住了。

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

【问题讨论】:

  • 您使用的是什么浏览器?可以发截图吗?在 Chrome 17 和 FF 上,这些示例对我来说看起来很正常
  • 我在 Mac OS 10.6 上使用 Chrome 16。这是截图:link。我可以补充一下,在我的 iPad 和 Safari 上是一样的。
  • 好消息是,这是一个浏览器/平台而不是代码问题,在 Windows 和 Android 上的 Chrome 17(开发者 Chrome)、Firefox 8、IE9 和 Opera 上似乎还不错4.0。它在 Windows 上的 Safari 上看起来不太好(看起来像您的屏幕截图)。除了 Safari 之外的所有内容的屏幕截图:i.imgur.com/QTaJf.png
  • 干杯西蒙。它应该看起来像这样。非常感谢您进行广泛的测试。我现在正在寻找一个(肮脏的)黑客来获得完整的圆形效果......如果你有任何想法,我会很高兴听到他们:)

标签: html canvas curvesmoothing


【解决方案1】:

找到了解决方法。这是那些愚蠢的 as-blah-approaches-zero bug 之一,我真的不知道它们的正确名称。如果两点之间的连接是一条很小的垂直线,那么很难绕过一个角落,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)值与最后一点不同。

【讨论】:

  • 非常感谢!这确实是一个愚蠢的错误和一个聪明的修复。我很快就会做一些测试,但我想我已经可以确认 y 值了。干杯!
  • 经过几次测试,答案并不那么简单。虽然“技巧”仍然有效,但您有时必须将其应用于控制点,有时也必须应用于终点。您似乎还必须根据相关点之间的差距来更改添加的数量。最后,添加的条件似乎取决于运动(例如 x1 > x2 和 x3
  • 我会看看我能不能弄清楚这个怪异的正式条件,至少这样我们才能有一个详细的 bug 提交
猜你喜欢
  • 1970-01-01
  • 2019-02-28
  • 2012-09-07
  • 1970-01-01
  • 1970-01-01
  • 2012-09-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-31
相关资源
最近更新 更多