Reputation: 12101
I have a script that draws a bunch of lines on canvas, but it's pretty intense so while rendering freezes browser for a few seconds. I added setTimeout() so that the browser wouldn't freeze and it effectively messed up my script. It's difficult to explain how, so I have two examples online:
Without setTimeout() : http://www.modwebsolutions.com/test1
With setTimeout() : http://www.modwebsolutions.com/test2
Note, that I only change a single line in the whole script, that is line 69:
without setTimeout(): vLoop();
with setTimeout(): setTimeout(vLoop,1);
Upvotes: 0
Views: 752
Reputation: 2341
The problem here, as hinted at by others, is that you are drawing the lines a quadrant at a time. As soon as the SetTimeout
method is called and the first vLoop
returns, the code carries on running into the next drawVertical
which changes all the global variables and so on.
What you need to do is synchronise how you're calling vLoop and how you are changing the globals.
This is basically the solution:
Replace ...
drawVertical(c,-1*step,-1*stepInt,-1*bigStep,xStart,xEnd,y/2+50,y);
drawVertical(c,step,stepInt,bigStep,xStart,xEnd,y/2+50,y);
drawVertical(c,-1*step,-1*stepInt,-1*bigStep,xStart,xEnd,y/2-50,0);
drawVertical(c,step,stepInt,bigStep,xStart,xEnd,y/2-50,0);
... with ...
var q = new Array();
q[0] = [c,-1*step,-1*stepInt,-1*bigStep,xStart,xEnd,y/2+50,y];
q[1] = [c,step,stepInt,bigStep,xStart,xEnd,y/2+50,y];
q[2] = [c,-1*step,-1*stepInt,-1*bigStep,xStart,xEnd,y/2-50,0];
q[3] = [c,step,stepInt,bigStep,xStart,xEnd,y/2-50,0];
drawQuadrant(q, 0);
Replace your drawVertical
function with ...
function drawQuadrant(q, i)
{
var r = q[i];
c__ = r[0];
step__ = r[1];
stepInt__ = r[2];
bigStep__ = r[3];
xStart__ = r[4];
xEnd__ = r[5];
yStart__ = r[6];
yEnd__ = r[7];
vLoop(q,i);
}
change the vLoop
function prototype to look like this ...
function vLoop(q,i)
and finally replace your recursive vLoop
call (from within vLoop) with ...
if ((xStart__ > 0) && (xStart__ < window.innerWidth))
{
setTimeout( function(){vLoop(q,i)}, 1 );
}
else if (++i < 4)
{
setTimeout( function(){drawQuadrant(q,i)}, 1 );
}
The last block is where it ensures that the quadrants are not stepping over each other.
Upvotes: 3
Reputation: 630379
What's happening is what setTimeout()
delays all that execution until later. Unfortunately, by that point your global variables have all moved to their ending positions from the initial loop, since it completed before the first line was drawn.
If you moved your timeout further up (so the shared variables you're using aren't affected until draw time) you could achieve what you're after, for example:
setTimeout(function() {
drawVertical(c,-1*step,-1*stepInt,-1*bigStep,xStart,xEnd,y/2+50,y);
drawVertical(c,step,stepInt,bigStep,xStart,xEnd,y/2+50,y);
drawVertical(c,-1*step,-1*stepInt,-1*bigStep,xStart,xEnd,y/2-50,0);
drawVertical(c,step,stepInt,bigStep,xStart,xEnd,y/2-50,0);
});
Then this would work (but it's dangerous, order isn't absolutely garunteed!)
You can see a working example here.
Upvotes: 0
Reputation: 169383
drawVertical(c,-1*step,-1*stepInt,-1*bigStep,xStart,xEnd,y/2+50,y);
drawVertical(c,step,stepInt,bigStep,xStart,xEnd,y/2+50,y);
drawVertical(c,-1*step,-1*stepInt,-1*bigStep,xStart,xEnd,y/2-50,0);
drawVertical(c,step,stepInt,bigStep,xStart,xEnd,y/2-50,0);
Your calling 4 recursive functions of vLoop
at once. The problem here is that setTimeout
is non-blocking where as recursion is blocking. So basically you now have all 4 of these drawVertical functions running in parallel rather then in sequence.
The other problem is that all 4 refer and mess with global state and your entire program breaks.
Upvotes: 0