# How to reverse a animation loop that pulls values from an array

**URL:** https://discourse.processing.org/t/how-to-reverse-a-animation-loop-that-pulls-values-from-an-array/36242
**Category:** Beginners
**Created:** [April 10, 2022, 1:08am UTC](https://discourse.processing.org/t/how-to-reverse-a-animation-loop-that-pulls-values-from-an-array/36242 "2022-04-10T01:08:02Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![gary](https://avatars.discourse-cdn.com/v4/letter/g/839c29/32.png) [@gary](https://discourse.processing.org/u/gary)
#### Post date: [April 10, 2022, 1:08am UTC](https://discourse.processing.org/t/how-to-reverse-a-animation-loop-that-pulls-values-from-an-array/36242/1 "2022-04-10T01:08:02Z")

</div>

I’m having difficulty figuring out how to reverse the direction of an animated loop when it reaches the end of an array. I found an example online that creates two “states” with an additive and subtractive loop within each respective state, but I have not been able to implement it.

Below is a simplified example of what I’m attempting. Would be grateful for someone’s advice on how to reverse the direction of the point when the last value within the array (14) is reached and, then, how to reverse it again when it returns to the array’s first value.

```auto
let array1 = [];
let a = 0;
let i = 0;

function setup() {
  createCanvas(400, 200);
  array1 = [2,4,6,8,10,12,14];
}

function draw() {
  background(220);
  frameRate(1);
  strokeWeight(10);
  stroke(255);
  point(array1[i]*20,100);
  i=i+1;
}

```

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [April 10, 2022, 2:22am UTC](https://discourse.processing.org/t/how-to-reverse-a-animation-loop-that-pulls-values-from-an-array/36242/2 "2022-04-10T02:22:42Z")

</div>

> [@gary](#):
>
> Below is a simplified example of what I’m attempting.

- I see you’ve declared a variable named _a_ but you’re not using it.
- Indeed you need 2 variables: 1 for the array’s current index and the other for the current step the index increases or decreases.
- Just invert the 2nd variable’s sign when the index reaches either `0` or the array’s _length_ - 1.

```auto
const arr = Uint8Array.from({ length: 7 }, (_, idx) => idx + 1 << 1);
var idx = 0, dir = -1;

function loop() {
  console.log(idx, dir, arr[idx]);
  if (idx == 0 || idx == arr.length - 1) dir *= -1;
  idx += dir;
}

setInterval(loop, 2000);

```

---

<div class="post-metadata">

### Author: ![gary](https://avatars.discourse-cdn.com/v4/letter/g/839c29/32.png) [@gary](https://discourse.processing.org/u/gary)
#### Post date: [April 10, 2022, 4:49pm UTC](https://discourse.processing.org/t/how-to-reverse-a-animation-loop-that-pulls-values-from-an-array/36242/3 "2022-04-10T16:49:12Z")

</div>

“idx == 0 || idx == arr.length - 1”  
That’s beautiful. Thanks!

---

<div class="post-metadata">

### Author: ![pirela](https://avatars.discourse-cdn.com/v4/letter/p/3e96dc/32.png) [@pirela](https://discourse.processing.org/u/pirela)
#### Post date: [April 13, 2022, 5:09pm UTC](https://discourse.processing.org/t/how-to-reverse-a-animation-loop-that-pulls-values-from-an-array/36242/4 "2022-04-13T17:09:38Z")

</div>

Previous solutions are fine and answer to your question.  
To open up to other solutions, i often prefer to use a generator:

```javascript
function * loopOnArray(someArray){
 while (true) {// infinite loop 
  for (let aPoint of someArray){
    yield aPoint
  }
// once done reverse the array 
  someArray= someArray.reverse();
 } // and loop again (while true)
}

```

Within an infinite loop (while true) this generator distributes points one per one (each yield) from the array and, once done, reverse this array and leaves for a new round.

To use it :  
Instantiate the generator in setup with a global var and give it the array we want to act on as the parameter.

```javascript
let giveAPoint;

function setup() {
  createCanvas(400, 200);
  array1 = [2,4,6,8,10,12,14];
  giveAPoint = loopOnArray(array1); // instantiate the generator with our array 
}

```

Then in draw, ask at each round for a new point :

```javascript
function draw(){
  background(220);
  frameRate(1);
  strokeWeight(10);
  stroke(255);
  point(giveAPoint.next().value*20,100);
}

```

There is many advantages to externalize loops in a generator : no complicated indices or comparison in the draw loop , can easily limit to a fixed or variable number of rounds (by replacing while true) etc.

One more info: you can reuse as many time you want the generator function as long as you create new instances.

HTH

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [April 13, 2022, 5:42pm UTC](https://discourse.processing.org/t/how-to-reverse-a-animation-loop-that-pulls-values-from-an-array/36242/5 "2022-04-13T17:42:33Z")

</div>

> [@pirela](#):
>
> … and, once done, reverse this array and leaves for a new round.

- Your [generator function\*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*) approach is a nice idea.
- Problem is it’s gonna repeat the head or tail elements for each [**reverse()**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse).
- That is, we would see the tail value 14 twice & head value 2 twice in a row.
- Also, method [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)::[**reverse()**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse) mutates the array [in place](https://en.wikipedia.org/wiki/In-place_algorithm).
- Just `someArray.reverse();` is enough. No need to reassign it back to the same array.

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [April 13, 2022, 6:07pm UTC](https://discourse.processing.org/t/how-to-reverse-a-animation-loop-that-pulls-values-from-an-array/36242/6 "2022-04-13T18:07:58Z")

</div>

I’ve converted my original solution to use a [function\* generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*): 🧞‍♂️

```auto
const
  arr = Uint8Array.from({ length: 7 }, (_, idx) => idx + 1 << 1),
  eternalArray = createInfiniteArrayLoop(arr);

function* createInfiniteArrayLoop(arr) {
  var idx = 0, dir = -1;

  while (true) {
    yield arr[idx];
    if (idx == 0 || idx == arr.length - 1) dir *= -1;
    idx += dir;
  }
}

function loop() {
  console.log(eternalArray.next().value);
}

setInterval(loop, 2000);

```

Same as above, but using [`for ( ; ; )`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for) in place of [`while ()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while) for a shorter code:

```auto
const
  arr = Uint8Array.from({ length: 7 }, (_, idx) => idx + 1 << 1),
  eternalArray = createInfiniteArrayLoop(arr);

function* createInfiniteArrayLoop(arr) {
  for (var idx = 0, dir = -1; ; idx += dir) {
    yield arr[idx];
    if (idx == 0 || idx == arr.length - 1) dir *= -1;
  }
}

function loop() {
  console.log(eternalArray.next().value);
}

setInterval(loop, 2000);

```

---

<div class="post-metadata">

### Author: ![pirela](https://avatars.discourse-cdn.com/v4/letter/p/3e96dc/32.png) [@pirela](https://discourse.processing.org/u/pirela)
#### Post date: [April 13, 2022, 6:16pm UTC](https://discourse.processing.org/t/how-to-reverse-a-animation-loop-that-pulls-values-from-an-array/36242/7 "2022-04-13T18:16:21Z")

</div>

You’re right GoToLoop:  
1: no need to reassign the array.  
2: if you don’t want to repeat borders can’t use for … in , must use indices too :

```javascript
function * loopOnArray(someArray){
let i=0;
while (true){
 while (i<someArray.length) { 
  console.log(someArray[i])
    yield someArray[i];
    i+=1;
  }
  someArray.reverse();
  i=1; // skip border
 }
}

```
