【问题标题】:HTML5 canvas drawing problems with Chrome使用 Chrome 的 HTML5 画布绘图问题
【发布时间】:2013-09-17 09:02:09
【问题描述】:

我正在深入研究 HTML5 画布,但在使用本地安装的 Chrome 版本时遇到了一些奇怪的问题。它是 Linux 上的 Chrome 29。

我正在查看以下内容(HTML5 Canvas 中的示例代码,第 2 版):

//draw a big box on the screen
context.fillStyle = "black";
context.fillRect(10, 10, 200, 200);
context.save();

context.beginPath();

context.rect(0, 0, 50, 50);
context.clip();

//red circle
context.beginPath();
context.strokeStyle = "red";
context.lineWidth=5;
context.arc(100, 100, 100, (Math.PI/180)*0, (Math.PI/180)*360, false);

context.stroke();
context.closePath();

context.restore();

//reclip to the entire canvas
context.beginPath();
context.rect(0, 0, 500, 500);
context.clip();

//draw a blue line that is not clipped
context.beginPath();
context.strokeStyle = "blue"; //need list of available colors
context.lineWidth=5;
context.arc(100, 100, 50, (Math.PI/180)*0, (Math.PI/180)*360, false);
context.stroke();
context.closePath();

并且应该得到:

但请参阅:

我的研究表明,Chrome 画布处于不断变化的状态,并且弧线过去曾出现过问题。但是,在 Windows 版 Chrome 的关闭版本和另一个 linux 桌面上的 Chrome 27 上似乎没问题。

我查看了我的 Chrome://flags,没有看到任何明显影响这一点的东西。

任何指导将不胜感激。

编辑:

我在 chrome://flags 中尝试了 #enable-experimental-canvas-features 和 #disable-accelerated-2d-canvas 的变体,但没有任何运气。

这是一个小提琴:

http://jsfiddle.net/QJRHE/4/

另一个编辑:

此代码适用于我机器上的 Chromium 28.0.1500.71。我开始怀疑这是一个 Chrome 错误。

【问题讨论】:

  • 你确定context.stroke()应该被称为之前 context.closePath()吗?
  • 在你抚摸它之后关闭路径是没有意义的:-) 尝试切换这两行,你能提供一个小提琴吗?
  • context.arc(100, 100, 50, 0, 2*Math.PI, false);已经足够好了,或者至少乘以 360,然后再除以 180……或者,是的,只需使用 2*Math.PI :-)
  • 添加了小提琴。发布的代码在 FF 中有效,但在 Chrome 中存在上述问题。
  • 感谢您指出中风/关闭问题。我刚刚从 O'Reilly 的网站上加载了这本书的代码,显然没有给它那么重要的阅读。

标签: javascript html google-chrome canvas html5-canvas


【解决方案1】:

弧线经常被误解为实际上不是的圆。与真正的圆形(或它们自身的封闭路径的矩形,子路径)相反,它们具有开放端,因此可以连接到其他路径。

因此,正确关闭弧线很重要。您快到了,但在关闭路径之前抚摸路径,关闭没有效果。

尝试在这两行之间切换,使它们看起来像这样:

context.closePath();
context.stroke();

当然,您尝试使用的版本可能存在错误(Chrome 过去曾遇到过很多关于弧的问题)。

更新

要提供可能的解决方法,您可以这样做:

A) 手动创建一个像这样的圆圈(我尽我所能优化它):

ONLINE DEMO HERE

function circle(ctx, cx, cy, radius) {

    var x, y, i = 2 * Math.PI, dlt = radius * 0.0005;

    while(i > 0) {
        x = cx + radius * Math.cos(i);
        y = cy + radius * Math.sin(i);
        i === 4 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
        i -= dlt;
    }
    ctx.closePath();
}

B) create a circle using a Bezier(不会是完美的圆,而是非常相似):

function drawEllipse(ctx, x, y, w, h) {

  var kappa = 0.5522848,
      ox = (w * 0.5) * kappa, // control point offset horizontal
      oy = (h * 0.5) * kappa, // control point offset vertical
      xe = x + w,             // x-end
      ye = y + h,             // y-end
      xm = x + w * 0.5,       // x-middle
      ym = y + h * 0.5;       // y-middle

  ctx.beginPath();
  ctx.moveTo(x, ym);
  ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
  ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
  ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
  ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
  ctx.closePath();
  ctx.stroke();
}

【讨论】:

  • 谢谢。我已经把它们换了(见有问题的小提琴)。行为在 Chrome 中仍然不正确,但在其他浏览器中正确。
  • @JohnCarter 我目前无法在 Linux 上进行测试,但尝试使用这一行 context.arc(100, 100, 100, 0, 2.01 * Math.PI , false); 修改您的代码(注意分数 2.01)。 Chrome 在某些版本中存在角度干净数字的问题,并且添加一小部分有时会有所帮助。如果是这样,我会更新我的答案。
  • 不走运。我发现代码确实在这台机器上的 Chromium 中工作,所以我猜这是 Chrome 错误。
  • @JohnCarter 是的,很可能是(我也将这种可能性添加到了答案中)。您应该将其报告给 Chromium。我不知道他们为什么不能把弧线弄好。
猜你喜欢
  • 1970-01-01
  • 2021-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-26
  • 1970-01-01
  • 1970-01-01
  • 2016-09-16
相关资源
最近更新 更多