Using shift () and push () variables to compare loop values ​​using a counter variable, what is the best approach?

I am viewing a set of images inside an array of animation frames. There are 7 images, and a loop from 1-7 completes the animation. I need this animation for the loop endlessly, but I was wondering which one is the best approach:

Loop by changing array

/* Pull image from start of array. */ var image = frames.shift(); /* Process image. */ ... /* Add image back to end of array. */ frames.push(image ); 

Loop using a counter variable

 /* Pull image by counter offset. */ var image = frames[counter]; /* Process image. */ ... /* Increment or reset counter value. */ counter + 1 === frames.length ? counter = 0 : counter = counter + 1; 

Is there a reason why I chose one of them? Alternatively, is there a better approach to this?

+4
source share
3 answers

Changing an array will be more expensive than just using a variable to track your position in the array. The best way to do this, if you loop endlessly, it seems to just use a while (and not use a for loop, where you reset the counter inside):

 var i = 0; while (true) { doSomething to array[i]; i = (i+1) % array.length; } 

However, if your goal really has animation, continue indefinitely every time a given interval expires, the loop is not perfect at all. Use setInterval instead.

 var frames = ...; //your images var i = 0; function animate() { do something to frames[i]; i = (i+1) % array.length; } setInterval(animate, time_between_runs); 

where time_between_runs is how much time must elapse before the function is called again.

+5
source

One possibility is to cut out the array and use a linked list.

Make each frame an object that points to the next object. Then the latter points to the first. Then all you have to do is reference the next object.

 var curr = first; // reference to first frame object setInterval(function() { // process image curr.image.doSomething(); // proceed to next curr = curr.next; }, 1000); 

There are no counters to obstruct this path.


Setting up a linked list is usually quite simple and can be done with a little modification of the current code that sets up the array.

 var first = new Frame(); // This is your entry point var current = first; // This holds the current frame during setup for (var i = 0; i < totalFrames; i++) { current.next = new Frame(); // Make the current reference a new frame current = current.next; // Make the new frame current } current.next = first; // circular reference back to the first. function Frame() { // set up this frame } 

Then first is your starting point.


Or the link can be made in the Frame constructor.

 var first = new Frame(null); var current = first; for (var i = 0; i < totalFrames; i++) { current = new Frame(current); } current.next = first; function Frame(currFrame) { // link this frame to the given one if (currFrame) currFrame.next = this; // set up the rest of this frame } 
+2
source

You can also use a circular linked list, I think. To turn an array of objects into a circular linked list:

 frames.forEach(function(elem, index) { elem.next = frames[index + 1] || frames[0]; }); 

And now you can do something like this:

 setInterval(function() { frame = frame.next; .... }, delay); 
+2
source

All Articles