I'm trying to create a progress bar using an HTML canvas to show the progress of a computationally-intensive loop in javascript. The problem I'm having is that the canvas doesn't actually update until the entire loop is finished.
I know that the calculation loop is working, and by inserting an alert
into the loop, I have determined that the code to update the progress bar works. It seems that the browser simply waits to update the canvas until the entire calculation loop is done (which, of course, defeats the purpose of a progress bar).
I have tried
- Simply calling the progress-bar-updating function in the calculation loop
- Calling the progress-bar-updating function via repeated
window.setTimeout
calls during the loop - Calling the progress-bar-updating function by scheduling a
window.setInterval
event before the loop starts.
But to no effect - the progress bar remains empty until the calculation loop ends, then instantly jumps to full.
Here is a stripped-down version of my code. I've tried to show all three solutions at the same time (of course, I only implemented one of the three at a time):
function calculateStuff(progressCallback) {
var x = 0, y = 0;
var total = N[0]*N[1];
// Solution #3: Schedule repeated calls using setInterval
// var intervalID = window.setInterval(progressCallback, 0, N[0]*y/total);
for (y = 0; y < N[1]; y++) {
for (x = 0; x < N[0]; x++) {
// Do computationally-intensive stuff here
}
// Solution #1 - Just directly call the progress bar updater during the loop
// progressCallback(N[0]*y/total);
// Solution #2 - Schedule a progress bar update using setTimeout
// window.setTimeout(progressCallback, 0, N[0]*y/total);
}
// Solution #1:
// progressCallback(N[0]*y/total);
// Solution #3:
// window.clearInterval(intervalID)
return resultOfComputation;
}
function setProgress(f) {
// Input: f - float between 0 and 1 indicating progress
// Setting off an alert allow me to see that this function does in fact update the progress bar.
// alert("Progress!");
progressCtx.clearRect(0, 0, progressCanvas.width, progressCanvas.height);
progressCtx.fillStyle = "blue";
progressCtx.fillRect(0, 0, progressCanvas.width * f, progressCanvas.height);
}
var result = calculateStuff(setProgress);
For the record, I've read the following questions that seemed like duplicates: this and this and this, but none of those solutions seem to work.
Thanks for any help!