Playing with Coroutines in Javascript, or how to pause an animation in a while(true) loop...
Published: 2022-11-08 22:32:37

Coroutines are pausable functions.
You can see a nice introduction here [Coroutine Event Loops in Javascript](https://x.st/javascript-coroutines/)

Here is a demo :

```js
const PAUSE = Symbol()

const {html, m} = MVU

const div = m("div")

function coroutine(f) {
    var o = f(); // instantiate the coroutine
    o.next(); // execute until the first yield
    return function(x) {
        o.next(x);
    }
}

function styleDrop  (pos = 10) {
  
  let style = `
    position: absolute; 
    left: ${pos}px;
    top:  ${(Math.floor(Math.random() * 100) -  200)}px;
    height : 10px;
    width: 3px;
    border-radius: 50%;
    z-index: -1;
  `
  return style
}

let makeDrop = function (pos) {
  let b = div();
  b.style = styleDrop(pos * 2)
  let speed = Math.random() * 20 + Math.random()  * 5;
  b.setAttribute("data-speed", speed);
  return b
}

let Balls =  [...Array(300)].map((_, index) => makeDrop(index))

function moveBall (b, e, speed = 1) {
   let dy = speed
   if (e) dy -= speed
   b.style.top =  `${b.offsetTop + dy }px`;       
   if (b.offsetTop  > 500) {     
      b.style.top = 0
   }
}

function *T () {  
  let ds = 1
  while (true) {
    let e = yield 
    if (e == PAUSE) {
      ds == 1 ? ds = 0 : ds = 1
    }
    for (b of Balls) {
      if (b.dataset.speed < 5) {
        b.style.background = "deeppink"
      }
      else {
         b.style.background = "blue"
      }
      moveBall(b, e,  b.dataset.speed * ds) 
    }
  }  
}

var rain = coroutine(T)
  
setInterval(rain, 33)

document.addEventListener('click',  function (e) {
  rain(PAUSE)
})



```
You can play with it here [CoroRain](https://flems.io/#0=N4IgtglgJlA2CmIBcBWFA6AzARgDQgGcBjAJwHtZZkBtABl1oF18AzCBAm0AOwEMxESEOgAWAFzBV8RMtzHw5yEAB5iJCAAcxAAgIkiAXgA6IcWI0EkAeitEo3dACsCUeLAgA3Eum7wxVgHMRK14SMQBPVw8rMA8AVwABbHRkgCYrKAgCf1i49DiwKHRIB2cTAD5lKzVNMXKjbgblEWx67m0AGT9tCB0AZW4yAHd0UaarFraG6e5lDTbtbQBhdyIAa20xMm0NXjiCeFH0cfmZuYXtMF5XbSHekW1lXl0IhGMQGVgyEiQicN5GiBtH0RCR4Cx3mYLNZAvc4gAjdAyMAhMKReDRXIVACyADUAKpVXhtKqnbggfAHBBEMQQWScITYTBITAoEAAX1wPH4gmEzgpH1k8kUQhk3Gy2gACgBBfF9ACi2gMwPCYHhFAAFABKGZiiXAcSSXCXdlK7R4-G6+k6TIeM1gDUmW0mHWNbgsOLcGl09oychxWm+DUsLXaYANRaLDyhbTbZUsbUAbm0Nh64rEANpvHkmxE8G0frIAYgvgjkbIPngAA8xEmU1ZtNX4EQA-nPbTYLn82wSBLwhA3FAy4swWI4iR2h6vbTZBqq6Hw+1I8uK74a3OtYnh9p2Q1d26p97ZC9wggACLkDSLDUaMgEM3YWgLstlhA6bKn-PKgAG29vBF6H0kG0Xh4QIChW2TbcEBYMRgIAEmAf92Q0KstyXRYtg0YDtEQjVsWzER0BYL5vnwwj0BIAEoDIB1QwAKm0R8n20ABaRZUloJ8ULQ7c8wgIIdGAx9UPQ5c7igMQRGAzBRO3dUSFcEhWKozJ9mAlBaAAUjEyMAC9WJLVwq2A1jsF038l1Hcd2g-BA9xmN9Ll4NZ4AvMgr3jT0j3aG872fJcnPhM1bSTMtETsr8T3PS8-PvRiADZXUWJyCA0eB4CgM0CKkyjqNo7VtEYzjtAAanNCiqO4Gi6MWRiUF0iK-GlMQxHUeFW0dEAoGzXhWLSjKhwpXR0syzcy2sidtHhBy3ScgAhXhKHvZVtGoI5pRIKjwg1TAuK1Rhil4DQNQ1AB9Y0jOrUMDHKZzXPck6rvnV0GkPGd2jAMgPHgRbKG0DV4WNeBjQGzKHwCyMnKgcIzTBocMIgFgAfgUMYbY5V4eHCLXkOLCzW0b9EMRMgWBYA4xAAFQ8srtHRnjv2TZdFmHJGAZJsmKepq9tDuzSWOAZnt0WHHP3QfHlVoYd933N7vI+orKYBhcWcC7ooBWpiyyGER2HzDU2riVGw2g7oov7QdtG3NmNS-ZUZTleVIeZjWlWVbBtAAfjpzXaG0YDXfd7d92XFhvnZ2Nkb+2ACGd5cbcRHqMwp9B4cebQUDj5nRYQdB4V4dYAn9aqzSdDKNA0Es1hMYWd1rtwDhNjDmem1Pcbzgu1iLosS+VEx4VgI2a+bxYQ+Zr6fujwHgeNVuk94FO08YjXQ2DstTSt7hZe4aMSG0KiSzNQtiyDSnks3imAEk5HgEho1gDUD+4Y1MEwV7qrIFsBDkdBrigeUfpyA6FkYUt8NQAHIiCrDWOA2e70fQo2dk-DUDsFSunZO-AUVJmwfQZCAPaSBUgAE4ORchAHwAQSgkQEE4NIIUCgxBKHVOjRcItO7d09FAJAA9O66U+N8YCOtejwF0mHOQ-UIB6XgDJVIcklzyBrKxJaAluC-AYbfdC28sFuBwT6PBAB2JAtAOTMHITyJQSxvhkAAEq8BLByIAA)