RafX Tutorial 5

Move an HTML element infinitely, with an ability to break

by Ibrahim Tanyalcin

HTML

<script src="https://cdn.jsdelivr.net/npm/rafx"></script>
<button>BREAK</button>
<div id="ball">

</div>

CSS

* {
  box-sizing: border-box;
}

body {
  display: flex;
  flex-flow: column wrap;
  justify-content: start;
  align-items: center;
  width: 100vw;
  height: 100vh;
  margin: 0px;
}

button {
  flex: 0 0 auto;
  margin: 20px;
}

#ball {
  flex: 0 0 auto;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background: Blue;
}

JavaScript

//decay = 1.5, range = 3
function elastic(t){
	t *= Math.PI * 2 * 3;
  return (1 - Math.sin(t) / (Math.pow(t, 1.5))) || 0;
}
var recursive = null, //check below to what this variable is assigned
		breaker = document.getElementsByTagName("button")[0];
breaker.onclick = function(){
	recursive && recursive.break();
}

function moveBall(x, y, ledger){
	x = x || 0;
	y = y || 0;
  ledger = ledger || {};
  ledger.x = ledger.x || 0;
  ledger.y = ledger.y || 0;
	ledger.duration = ledger.duration || 60; //60 frames === 1 second
	ledger.node = ledger.node || document.getElementById("ball");
	return rafx.async(ledger)
		.animate(function(ledger,o){
      var _t = elastic(o.i / ledger.duration),
      		_x = ledger.x + (x * _t),
          _y = ledger.y + (y * _t),
      		translate = "translate(" + _x + "px," + _y + "px)";
      ledger.node.style.transform = translate;
      return ledger;
		},{i:0} /*o*/)
		.until(function(ledger,o){
    	return ++o.i === 60;
    })
    .then(function(ledger){
    	ledger.x += x;
      ledger.y += y;
      return ledger;
    });
}

function moveAroundRect(){
  return moveBall(100,0)
  .then(function(ledger){
    return moveBall(0,100,ledger);
  })
  .then(function(ledger){
    return moveBall(-100,0,ledger);
  })
  .then(function(ledger){
    return moveBall(0,-100,ledger);
  });
}

recursive = rafx.async()
	.recurse(function(){
  	console.log("After break I won't be running anymore!");
  	return moveAroundRect();
  })
  .until(function(){
  	return false;
  });