Animation - only first and last images display

P

Paul LeBlanc

I have some images that move positions fine using onmousedown or
onmousemove to feed a function the coordinates. It doesn't work when I
plug it into conditional loops with setTimeout to set the coordinates.
When I use loops to feed the MoveFunction its coordinates, all that
displays are the images in their initial positions, and then their final
positions (after the timeouts, etc.)

The timeouts are happening, but the screen fails to refresh the new
image positions during the timeouts. It appears that I need to add some
code that forces the browser to refresh so it can display the images as
they change.

Can anybody steer me in the right direction? There are a **ton** of
posts in Usenet about this but no definitive answers that I can find.

Thanks .......
 
L

Lasse Reichstein Nielsen

Paul LeBlanc said:
I have some images that move positions fine using onmousedown or
onmousemove to feed a function the coordinates. It doesn't work when I
plug it into conditional loops with setTimeout to set the coordinates.

Show us code!

Without the code, I have to guess blindly (something I am pretty good
at, but it's still not optimal for any of us).
When I use loops to feed the MoveFunction its coordinates, all that
displays are the images in their initial positions, and then their final
positions (after the timeouts, etc.)

Do you do something similar to:

var coords = [ ... ];
for(var i=0;i<coords.length;i++) {
setTimeout(function(){ setPosition(coords); }, i*100);
}

, i.e., create a loop that makes a bunch of setTimeout's with different
delays, and expect each timeout event to set the coordiantes according
to the value of the index ("i" here)?

If so, then your problem is that all the functions refer to the same
variable "i", and it only have one value at a time. It can be any
variable the you expect to vary between the functions. It won't, there
is only one value, and a closure captures the reference to it, not
the value of it.

/L
 
L

Lee

Paul LeBlanc said:
I have some images that move positions fine using onmousedown or
onmousemove to feed a function the coordinates. It doesn't work when I
plug it into conditional loops with setTimeout to set the coordinates.
When I use loops to feed the MoveFunction its coordinates, all that
displays are the images in their initial positions, and then their final
positions (after the timeouts, etc.)

You're probably using setTimeout() incorrectly.
There are a couple of common errors that could cause these symptoms.
Show us your code.
 
P

Paul LeBlanc

Hi Lasse,
Sorry no code but I thought I was asking about code that I have yet to
write! Here's a sample of what I have written. Again, this code works
when I generate the (x,y) coordinates with a mousedown or mousemove, and
all the timeouts DO WORK. The problem is that when I feed the
coordinates programatically with a loop then I only get the initial
positions and final positions drawn to display.

Here's how I generate the coordinates and call the moveDucks function:

function posGenerator(xaxis, yaxis) {

x=xaxis;
y=yaxis;
x2 = x
y2 = y

var dummy2;

do {
x2+=1;
y2-=1;
setTimeout('dummy2 = moveDucks x2,y2)',500);
clearTimeout;
TextBox4.value=(x2+","+y2)

} while (x2<500);


}




function moveDucks(xPos, yPos) {

mother_xPos = xPos;
mother_yPos = yPos;


setTimeout('mother.left = newDuckPos(mother_yPos, mother_xPos)',100);
clearTimeout;
setTimeout('mother.top = newDuckPos(mother_xPos, mother_yPos)',100);

*****end code snip******

The above calls another function newDuckPos that does the math to figure
out the next positions for each duck image (there is a mother duck and
three ducklings and the duckling follow the mother.)

All of it seems pretty well wrapped in setTimeout statements, and they
do work. My problem is getting the display to refresh the new image
locations real time. Right now it skips to the end after all the
timeouts are done. The end position(s) is correct. I just need the
trick to get the display to show all the steps.

Thanks!
 
L

Lasse Reichstein Nielsen

Paul LeBlanc said:
Hi Lasse,
Sorry no code but I thought I was asking about code that I have yet to
write! Here's a sample of what I have written. Again, this code works
when I generate the (x,y) coordinates with a mousedown or mousemove, and
all the timeouts DO WORK. The problem is that when I feed the
coordinates programatically with a loop then I only get the initial
positions and final positions drawn to display.

Here's how I generate the coordinates and call the moveDucks function:

function posGenerator(xaxis, yaxis) {

x=xaxis;
y=yaxis;
x2 = x
y2 = y

var dummy2;

do {
x2+=1;
y2-=1;
setTimeout('dummy2 = moveDucks x2,y2)',500);

I assume there is a parenthesis missing here:
setTimeout('dummy2 = moveDucks(x2,y2)',500);

Notice that you embed the variable *names* x2 and y2 in the string.
That means that when the code is executed (in 500 milliseconds), the
value of x2 and y2 at that point is used.

I think you have slightly misunderstood how setTimeout and
clearTimeout works (and trust me, you are not the first to do that).

setTimeout schedules some code to be executed after some time.
The call to setTimeout itself return immediately.
clearTimeout;

clearTimeout is a function that can prevent a scheduled timeout.
Here, you don't call the function, so the line does nothing.

The argument to clearTimeout is a timeout identifier returned by
setTimeout.
TextBox4.value=(x2+","+y2)

} while (x2<500);

Since setTimeout returns immediately, you might run through this entire
loop before 500 milliseconds have passed. At that time, x2 and y2
have their final values. Then 500 scheduled calls to moveDucks happens,
all setting the same position.

What you can do to fix this:

1) Embed values in the scheduled code instead of variable names:
setTimeout('moveDucks(' + x2 + ',' + y2 + ')',500);
You might want to schedule later events at a later time, e.g.,
make a counter and multiply the 500 by the counter. Then the steps
will happen with half second intervals.

2) Put the position updating in the scheduled code.
setTimeout('x2+=1;y2-=1;moveDucks(x2,y2)',500);
Again, you don't want all the events to happen at the same time.

3) A completely different approach:
Use setInterval instead of setTimeout. It will automatically call
every <delay> milliseconds, until you stop it.

Use a local function as argument to setInterval, so you have the
xaxis and yaxis variables in scope. It saves you from making too
many global variables.

Update the values in the scheduled code.
---
function posGenerator(xaxis, yaxis) {
var intervalId = setInterval( function () {
xaxis+=1;
yaxis-=1;
moveDucks(xaxis,yaxis);
if (xaxis >= 500) {
clearInterval(intervalId);
}
}, 500);
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top