Physical Spring Eqn.

https://medium.com/@willsilversmith/the-spring-factory-4c3d988e7129

HTML

<div id="ball"></div>

CSS

#ball {
  position: absolute;
  top: calc(50% - 50px);
  left: calc(50% - 50px);
  width: 100px;
  height: 100px;
  border-radius: 100%;
  background-color: rgba(0, 0, 0, .8);
}

JavaScript

window.onload = function() {
  var ball = document.getElementById('ball');

  animation({
    obj: ball,
    msec: 1500,
    easing: springFactory({
      damping: 0.2,
      halfcycles: 15,
      initial_position: 0.5, // +50% screen, from center
      initial_velocity: 0,
    }),
  });
};

/* Example animation function 
 * 
 * Interpolate between a start and end position.
 *
 * obj.x represents a position parameter (e.g. 12.2)
 * end_pos is the value obj.x will have at the end of the animation
 * msec is the number of milliseconds we want to run the animation for
 * easing is a timing function that accepts a number between 0 to 1 
 *    and returns the proportion of the interpolation between start and end to move the object to. 
 * 
 * Returns: void (performs animation as a side effect)
 */
function animation(args) {
  args = args || {};

  var easing = args.easing || function(t) {
    return t
  }; // default to linear easing
  var obj = args.obj;

  var style = window.getComputedStyle(obj);

  var start_pos = parseInt(style.top, 10),
    height = args.height || 0,
    msec = args.msec || 1000;

  // performance.now is guaranteed to increase and gives sub-millisecond resolution
  // Date.now is susceptible to system clock changes and gives some number of milliseconds resolution
  var start = window.performance.now();

  function displacement(fraction) {
    var height = parseFloat(style.height.replace("px", ''), 10);
    height /= 2;
    height += "px";

    return "calc(50% - " + height + " - " + (fraction * 100) + "%)";
  }

  function frame() {
    var now = window.performance.now();
    var t = (now - start) / msec; // normalize to 0..1

    if (t >= 1) { // if animation complete or running over
      obj.style.top = displacement(easing(1)); // ensure the animation terminates in the specified state
      return;
    }


    obj.style.top = displacement(easing(t));

    requestAnimationFrame(frame); // next frame!
  }

  requestAnimationFrame(frame); // you...