smootherStep

Forked from https://jsfiddle.net/pajtai/gAAp2/

by intrinsica

HTML

<!-- BLUE box is JS animated smootherStep (minJerk) easing
     RED box is CSS animated approximation of smootherStep (see https://jwilliamdunn.blogspot.com/2019/06/easesmoother.html)
     GREEN box is CSS ease-in-out for reference
     
     NOTE: JS will naturally fall out of sync with the CSS animation
     A few milliseconds are trimmed from the duration to compensate.
--> 
<div id="box1"></div><div id="box2"></div><div id="box3"></div>

CSS

#box1 {
  width: 50px;
  height: 50px;
  margin-left:0;
  background-color:blue;
}
body {
  width:100%;
  background-color: black;
}



@keyframes r {
  from {margin-left: 0px;}
  to {margin-left: calc(100% - 50px);}
}
#box2 {
    width:50px;
    height:50px;
    background-color:red;
    margin-left:0;
    
    animation: r 1s infinite;
    animation-timing-function: cubic-bezier(.49,0,.51,1);
    animation-direction: alternate;
}


#box3 {
    width:50px;
    height:50px;
    background-color:green;
    margin-left:0;
    
    animation: r 1s infinite;
    animation-timing-function: ease-in-out;
    animation-direction: alternate;
}

JavaScript

(function(window) {
  var r = 0, g = 1, b = 2,
      document = window.document,
      box = document.getElementById('box1'),
      easing = {
easeInOutSmoother: function(t) { var ts = t * t, tc = ts * t; return 6*tc*ts - 15*ts*ts + 10*tc }
},
      // make smart use of the browsers animation frame if available
      // default to 60fps if not
      // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
      requestAnimationFrame = (function () {

        return (window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            function (callback) {

                this.setTimeout(callback, 1000 / 60);
            }).bind(window);
      })(),
      // The animation equation with user friendly argument
      // This will take care of normalization before calling the easing equation,     
      // * tickHook - function that get called on each tick with the updated number
      // * startNum - initial value
      // * endNum - final value
      // * duration - how long animation last in milliseconds
      // * callback - (optional) function to call when animation finishes
      // * easingEq - (optional) easing equation
      animate = function(tickHook, startNum, endNum, duration, callback, easingEq) {
          
        var easingEq = easingEq || easing.easeInOutSmoother,
            changeInNum = endNum - startNum,
            startTime = new Date().getTime(),            
            engine = function() {
               var now = new Date().getTime(),
                   timeNorm = (now - startTime) / duration,
                   completionNorm = easingEq(timeNorm),
                   newNum = startNum + completionNorm * changeInNum;
              
              if (now - startTime > duration) {
               // clearTimeout(engine);
     ...