在极少数情况下,<canvas>不会重绘</canvas>

时间:2012-10-05 23:07:29

标签: javascript canvas redraw

我使用<canvas>在我的音乐教育网络应用中绘制所有笔记和字形: http://www.musictheory.net/exercises/keysig/bc98yy

Firefox 15.0.1用户报告说,有时练习会继续讨论下一个问题,但画布仍会显示上一个问题。我已经看到这种情况发生在一次测试中(大约500个问题)。

当它出现时,画布已通过canvas.width = canvas.width和上下文调用.clearRect清除,并且已通过.beginPath.quadraticCurveTo在JavaScript中绘制了字形,.closePath等等。但是,似乎画布的后备缓冲区永远不会被刷新/绘制到窗口中。

我在过去看到过有关类似问题的错误报告:

我可以通过执行DOM hack来强制重绘,例如将文本节点作为画布的子项插入,然后在下一个运行循环周期中删除它,或者修改画布的背景颜色或填充。然而,这似乎很苛刻,而且我一直有一种唠叨的感觉,我错过了一些明显的东西。

我的绘图代码很简单:

canvas.width = width;
ctx.clearRect(0, 0, width, height);
ctx.save();
// Lots of drawing code here
ctx.restore()
ctx.clearRect(0, 0, 1, 1); // Helped force a repaint on some older WebKit browsers?

我已确保.save.restore来电的数量达到平衡。

1)我直接调用此代码以响应onclick事件处理程序。我是否应该使用requestAnimationFramesetTimeout在未来的运行循环周期中执行绘图?

2)我没有遗漏一些明显的东西,比如canvas.pleaseRepaintNow() API,对吧?

3)是否有其他人遇到类似问题并使用DOM修改来强制重绘?

2 个答案:

答案 0 :(得分:4)

context.stroke();添加到onLoad函数的最后一行,它修复了Firefox中的错误。否则,在重绘窗口之前,不会渲染对画布的更改。

至少在我的案例中有用。

window.onload = function() {
   canvas = document.getElementById("canvas");
   context = canvas.getContext("2d");
   //Code here...
   context.stroke();
}

答案 1 :(得分:1)

我试图让错误发生,但在疯狂点击Firefox一段时间后,我从未见过它。这就是我如何清除看起来有用的画布,但是因为我无法让错误发生,所以我不能检查是否有任何东西......

// Store the current transformation matrix
ctx.save();

// Use the identity matrix while clearing the canvas
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);

// Restore the transform
ctx.restore();