I use <canvas>
to draw all notes and glyphs in my music education web apps:
A Firefox 15.0.1 user has reported that sometimes the exercise goes on to the next question, but the canvas still shows the previous question. I have seen this occur in testing one time (out of ~500 questions).
When it occurs, the canvas has been cleared via both canvas.width = canvas.width
and a call to .clearRect
on the context and glyphs have been drawn in JavaScript via .beginPath
, .quadraticCurveTo
, .closePath
, etc. However, it seems like the canvas's backing buffer never gets flushed/drawn into the window.
I have seen bug reports in the past regarding similar issues:
- .cgi?id=787623
- .cgi?id=794337
I can force a redraw by doing a DOM hack such as inserting a text node as a child of the canvas, and then removing it on the next run loop cycle, or modifying the background-color or padding of the canvas. This seems heavy-handed, however, and I keep having the nagging feeling that I'm missing something obvious.
My drawing code is simple enough:
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?
I have ensured that the number of .save
and .restore
calls are balanced.
1) I am calling this code directly in response to an onclick
event handler. Should I instead be using requestAnimationFrame
or setTimeout
to perform the drawing on a future run loop cycle?
2) I'm not missing something obvious, like a canvas.pleaseRepaintNow()
API, right?
3) Have other people encountered similar issues and resorted to DOM modification to force redraws?
I use <canvas>
to draw all notes and glyphs in my music education web apps:
http://www.musictheory/exercises/keysig/bc98yy
A Firefox 15.0.1 user has reported that sometimes the exercise goes on to the next question, but the canvas still shows the previous question. I have seen this occur in testing one time (out of ~500 questions).
When it occurs, the canvas has been cleared via both canvas.width = canvas.width
and a call to .clearRect
on the context and glyphs have been drawn in JavaScript via .beginPath
, .quadraticCurveTo
, .closePath
, etc. However, it seems like the canvas's backing buffer never gets flushed/drawn into the window.
I have seen bug reports in the past regarding similar issues:
- https://bugzilla.mozilla/show_bug.cgi?id=787623
- https://bugzilla.mozilla/show_bug.cgi?id=794337
- http://code.google./p/chromium/issues/detail?id=55339
I can force a redraw by doing a DOM hack such as inserting a text node as a child of the canvas, and then removing it on the next run loop cycle, or modifying the background-color or padding of the canvas. This seems heavy-handed, however, and I keep having the nagging feeling that I'm missing something obvious.
My drawing code is simple enough:
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?
I have ensured that the number of .save
and .restore
calls are balanced.
1) I am calling this code directly in response to an onclick
event handler. Should I instead be using requestAnimationFrame
or setTimeout
to perform the drawing on a future run loop cycle?
2) I'm not missing something obvious, like a canvas.pleaseRepaintNow()
API, right?
3) Have other people encountered similar issues and resorted to DOM modification to force redraws?
Share Improve this question asked Oct 5, 2012 at 23:07 icciriccir 5,1282 gold badges24 silver badges34 bronze badges2 Answers
Reset to default 4 +50Add context.stroke();
to the last line of your onLoad
function, it fixes a bug in Firefox. Otherwise changes to the canvas don't render until the window is redrawn.
It worked in my case at least.
window.onload = function() {
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
//Code here...
context.stroke();
}
I tried to get the bug to happen but after madly clicking in Firefox for awhile, I never saw it. This is how I clear the canvas which seems to work, but take it with a grain of salt since I can't get the bug to occur I also can't check to see if this fixes anything...
// 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();