DEV Community

Cover image for Playing with Coroutines in Javascript, or how to pause an animation in a while(true) loop...
artydev
artydev

Posted on • Updated on

Playing with Coroutines in Javascript, or how to pause an animation in a while(true) loop...

Coroutines are pausable functions.
You can see a nice introduction here Coroutine Event Loops in Javascript

Here is a demo :

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)
})



Enter fullscreen mode Exit fullscreen mode

You can play with it here CoroRain

Top comments (0)