views:

19

answers:

1

Hi! I am in the middle of writing a JavaScript library and I have hit a problem, I have a function that resizes elements, that all works good but I also have and animated version that resizes them over a specified time frame. The script seems to freeze when ever it is run and it seems to be down to my while loop, here is my code.

// Resize in timeframe
// Work out distance
var widthDiff = width - element.offsetWidth;
var heightDiff = height - element.offsetHeight;

// Work out pixels per milisecond
var widthppm = widthDiff / timeframe;
var heightppm = heightDiff / timeframe;

// Set up times
var d = new Date();
var endtime = d.getTime() + timeframe;

// Get the original width and height
var oldwidth = element.offsetWidth;
var oldheight = element.offsetHeight;

var iteration;

// Loop through until done
while(d.getTime() >= endtime)
{
    iteration = timeframe - (endtime - d.getTime());
    element.style.width = oldwidth + (iteration * widthppm) + 'px';
    element.style.height = oldheight + (iteration * heightppm) + 'px';
}

All I can tell you now are that the arguments (element, width, height, timeframe) are working fine, it is down to my algorithm. Any help will be great, thanks!

+1  A: 

It should be d.getTime() <= endtime.
Emphasis on <= instead of >=.

Additionally you need to get a new timestamp inside the loop, as the d.getTime() will always be the same (the time at the moment it was created)..

so

while(d.getTime() <= endtime)
{
    iteration = timeframe - (endtime - d.getTime());
    element.style.width = oldwidth + (iteration * widthppm) + 'px';
    element.style.height = oldheight + (iteration * heightppm) + 'px';
    d = new Date();
}

But you should use a timeout/interval to animate and not a loop as that would block the rest of the scripts from executing..

Here are a couple of tutorials about animation with setTimeout and setInterval

Gaby
Nope, that didn't get it but thank you for pointing that out. Can't believe I missed that one. It still comes up as an unresponsive script.
Wolfy87
@Wolfy87, added some more info .. the `d.getTime()` returns the same value always.. it is not a running timer.. just a time instance, showing the time when it was created..
Gaby
After recreating the d variable in each iteration of the loop it worked, although it still does not animate, it just sits there until the time is up and then moves. Thanks for your help!
Wolfy87
@wolfy, that is how the DOM works.. a loop in javascript will block anything else from happening while the loop runs. That is why i mentioned that you should really use the `setTimeout` or `setInterval` methods. With those, you can create timed callbacks that move your animation forward, while the rest of the page continues to work ..
Gaby
I see, so will I be needing a 1ms interval?
Wolfy87
@wolfy, the thing with intervals and timeouts is that you cannot be sure of the exact moment they will occur, and you also need to factor in the time they take to complete.. So you need to calculate the time offset between them at runtime, and not assume that it is 1ms just because you set it to 1ms ... 1ms sound a bit extreme but you can experiment.. have a look at https://developer.mozilla.org/en/DOM/window.setTimeout
Gaby
@wolfy, some tutorials at http://www.schillmania.com/content/projects/javascript-animation-1/ and http://www.schillmania.com/content/projects/javascript-animation-2/
Gaby
Thank you very much, you have been a great help.
Wolfy87