Here is the part of the code that matters:
function drawCircle(i, color1, color2) {
var ctx = canvas.getContext("2d");
if (i % 2 == 1) {
ctx.fillStyle = color1;
}
else {
ctx.fillStyle = color2;
}
ctx.beginPath();
ctx.arc(110, 270, 10, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
}
for (var i = 0; i < 10; i++) {
setTimeout(drawCircle(i, color2, color5), 4000);
}
Note that this is just a snippet I wanted to try out before I use code similar to this on a larger project. This isn't working properly, the image is only drawn once, that is, I only see the last circle that is drawn. I have googled this to death but nothing has helped me so far.
Here is the part of the code that matters:
function drawCircle(i, color1, color2) {
var ctx = canvas.getContext("2d");
if (i % 2 == 1) {
ctx.fillStyle = color1;
}
else {
ctx.fillStyle = color2;
}
ctx.beginPath();
ctx.arc(110, 270, 10, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
}
for (var i = 0; i < 10; i++) {
setTimeout(drawCircle(i, color2, color5), 4000);
}
Note that this is just a snippet I wanted to try out before I use code similar to this on a larger project. This isn't working properly, the image is only drawn once, that is, I only see the last circle that is drawn. I have googled this to death but nothing has helped me so far.
Share Improve this question asked May 1, 2011 at 17:53 AsgeirAsgeir 7573 gold badges9 silver badges21 bronze badges3 Answers
Reset to default 4What you want to use is setInterval
. setTimeout
just fires the event once. They have the same argument list.
Also I don't think the way you use setTimeout
is correct. The way you've written it now, the function is fired before actually passing anything to setTimeout
/setInterval
. So you should write:
setInterval(function() { // GOOD. An actual function is passed
drawCircle(...); // as the first argument.
}, 4000);
or:
setInterval('drawCircle(...)', 4000); // GOOD. the JS statement is supplied as
// a string and later on will be evaluated
// and executed with eval().
and NOT:
setInterval(drawCircle(...), 4000); // BAD! drawCircle() is fired, its result
// evaluated and passed on to setInterval
// that doesn't know what to do with it.
EDIT
You don't have any blocking routines in JavaScript. It's a single threaded, event driven language. If you call something like setInterval
it succeeds immediately. Only after 4 seconds or so your callback function will be invoked. However in the meantime JS will be busy doing all sort of different stuff - like for example reacting to other events generated by the user. What you want to do is to call setTimeout
once and then inside the callback function, just before returning invoke it again with the same function and a different set of arguments of i
. Something along these lines:
function drawCircle(i, ...) {
// ... do stuff ...
if (i < 10) { // Check if the callback has been invoked 10
// times already.
setTimeout(function() { // Schedule the callback for execution
drawCircle(i + 1, ...); // again after anoter 4 seconds.
}, 4000);
}
}
setTimeout(function() { // Invoke the callback the first time
drawCircle(1, ...); // after first 4 seconds.
}, 4000);
There are actually a couple of things that are causing your code to misbehave, and they're all in how your loop is written. The first problem is the call to setTimeout, mainly that you're not passing a function object to it as the first argument, and most people would fix that by doing something like this:
for (var i = 0; i < 10; i++) {
setTimeout(function() {
drawCircle(i, color2, color5);
}, 4000);
}
That will cause the setTimeout to delay as you expected, but it will end up calling drawCircle with 10 as the first argument 10 times, and that is because of every call is using the same reference to the "i" variable. The value for i isn't retrieved until the call is made...4 seconds or so after the loop pleted when i is already 10.
To get around that, you need one more function:
function getDrawer(i, color2, color5) {
return function() {
drawCircle(i, color2, color5);
}
}
for (var i = 0; i < 10; i++) {
setTimeout(getDrawer(i, color2, color5), 4000);
}
The getDrawer (a horrible name, please don't use it) function is called immediately, so the value of i is accessed immediately and remembered by the anonymous function that getDrawer returns. That anonymous function is what will be called by setTimeout.
The issue here is that you're calling setTimeout several times in a row, rather than calling it again from the callback. Try moving the call to setTimeout
to the end of the drawCircle
function to see the animation.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744194734a4562600.html
评论列表(0条)