Chrome的HTML5画布绘图问题

时间:2013-09-12 20:03:04

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

我正在深入研究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();

应该得到:

Correct

但请看:

Incorrect

我的研究表明,Chrome画布处于不稳定的状态,过去这些电弧都存在问题。但是,在Chrome for Windows的密切版本和另一个Linux桌面上的Chrome 27上似乎没问题。

我查看了我的Chrome://标记,看不到任何明显会影响这一点的内容。

任何指导都将不胜感激。

修改

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

这是一个小提琴:

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

另一个编辑:

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

1 个答案:

答案 0 :(得分:2)

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

因此,正确关闭弧线非常重要。你几乎就在那里,但是通过在关闭它之前抚摸路径,结束没有效果。

尝试切换两条线,使它们看起来像这样:

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();
}