8

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

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

当它发生时,画布已被清除,并且已通过、、等在 JavaScript 中canvas.width = canvas.width调用.clearRect上下文和字形。但是,画布的后备缓冲区似乎永远不会被刷新/绘制到窗口中。.beginPath.quadraticCurveTo.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事件处理程序。我应该改为使用requestAnimationFrame还是setTimeout在未来的运行循环周期中执行绘图?

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

3)有没有其他人遇到过类似的问题,通过修改DOM来强制重绘?

4

2 回答 2

4

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

至少在我的情况下它有效。

window.onload = function() {
   canvas = document.getElementById("canvas");
   context = canvas.getContext("2d");
   //Code here...
   context.stroke();
}
于 2012-10-15T22:30:11.437 回答
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();
于 2012-10-09T03:30:45.667 回答