function spring(string, duration) {

  var params = parseEasingParameters(string);
  var mass = minMax(is.und(params[0]) ? 1 : params[0], .1, 100);
  var stiffness = minMax(is.und(params[1]) ? 100 : params[1], .1, 100);
  var damping = minMax(is.und(params[2]) ? 10 : params[2], .1, 100);
  var velocity =  minMax(is.und(params[3]) ? 0 : params[3], .1, 100);
  var w0 = Math.sqrt(stiffness / mass);
  var zeta = damping / (2 * Math.sqrt(stiffness * mass));
  var wd = zeta < 1 ? w0 * Math.sqrt(1 - zeta * zeta) : 0;
  var a = 1;
  var b = zeta < 1 ? (zeta * w0 + -velocity) / wd : -velocity + w0;

  function solver(t) {
    var progress = duration ? (duration * t) / 1000 : t;
    if (zeta < 1) {
      progress = Math.exp(-progress * zeta * w0) * (a * Math.cos(wd * progress) + b * Math.sin(wd * progress));
    } else {
      progress = (a + b * progress) * Math.exp(-progress * w0);
    }
    if (t === 0 || t === 1) { return t; }
    return 1 - progress;
  }

  function getDuration() {
    var cached = cache.springs[string];
    if (cached) { return cached; }
    var frame = 1/6;
    var elapsed = 0;
    var rest = 0;
    while(true) {
      elapsed += frame;
      if (solver(elapsed) === 1) {
        rest++;
        if (rest >= 16) { break; }
      } else {
        rest = 0;
      }
    }
    var duration = elapsed * frame * 1000;
    cache.springs[string] = duration;
    return duration;
  }

  return duration ? solver : getDuration;

}
function spring(string, duration) {

  var params = parseEasingParameters(string);
  var mass = minMax(is.und(params[0]) ? 1 : params[0], .1, 100);
  var stiffness = minMax(is.und(params[1]) ? 100 : params[1], .1, 100);
  var damping = minMax(is.und(params[2]) ? 10 : params[2], .1, 100);
  var velocity =  minMax(is.und(params[3]) ? 0 : params[3], .1, 100);
  var w0 = Math.sqrt(stiffness / mass);
  var zeta = damping / (2 * Math.sqrt(stiffness * mass));
  var wd = zeta < 1 ? w0 * Math.sqrt(1 - zeta * zeta) : 0;
  var a = 1;
  var b = zeta < 1 ? (zeta * w0 + -velocity) / wd : -velocity + w0;

  function solver(t) {
    var progress = duration ? (duration * t) / 1000 : t;
    if (zeta < 1) {
      progress = Math.exp(-progress * zeta * w0) * (a * Math.cos(wd * progress) + b * Math.sin(wd * progress));
    } else {
      progress = (a + b * progress) * Math.exp(-progress * w0);
    }
    if (t === 0 || t === 1) { return t; }
    return 1 - progress;
  }

  function getDuration() {
    var cached = cache.springs[string];
    if (cached) { return cached; }
    var frame = 1/6;
    var elapsed = 0;
    var rest = 0;
    while(true) {
      elapsed += frame;
      if (solver(elapsed) === 1) {
        rest++;
        if (rest >= 16) { break; }
      } else {
        rest = 0;
      }
    }
    var duration = elapsed * frame * 1000;
    cache.springs[string] = duration;
    return duration;
  }

  return duration ? solver : getDuration;

}
function spring ( string , duration ) { var params = parseEasingParameters ( string ) ; var mass = minMax ( is . und ( params [ 0 ] ) ? 1 : params [ 0 ] , .1 , 100 ) ; var stiffness = minMax ( is . und ( params [ 1 ] ) ? 100 : params [ 1 ] , .1 , 100 ) ; var damping = minMax ( is . und ( params [ 2 ] ) ? 10 : params [ 2 ] , .1 , 100 ) ; var velocity = minMax ( is . und ( params [ 3 ] ) ? 0 : params [ 3 ] , .1 , 100 ) ; var w0 = Math . sqrt ( stiffness / mass ) ; var zeta = damping / ( 2 * Math . sqrt ( stiffness * mass ) ) ; var wd = zeta < 1 ? w0 * Math . sqrt ( 1 - zeta * zeta ) : 0 ; var a = 1 ; var b = zeta < 1 ? ( zeta * w0 + - velocity ) / wd : - velocity + w0 ; function solver ( t ) { var progress = duration ? ( duration * t ) / 1000 : t ; if ( zeta < 1 ) { progress = Math . exp ( - progress * zeta * w0 ) * ( a * Math . cos ( wd * progress ) + b * Math . sin ( wd * progress ) ) ; } else { progress = ( a + b * progress ) * Math . exp ( - progress * w0 ) ; } if ( t === 0 || t === 1 ) { return t ; } return 1 - progress ; } function getDuration ( ) { var cached = cache . springs [ string ] ; if ( cached ) { return cached ; } var frame = 1 / 6 ; var elapsed = 0 ; var rest = 0 ; while ( true ) { elapsed += frame ; if ( solver ( elapsed ) === 1 ) { rest ++ ; if ( rest >= 16 ) { break ; } } else { rest = 0 ; } } var duration = elapsed * frame * 1000 ; cache . springs [ string ] = duration ; return duration ; } return duration ? solver : getDuration ; }
Spring solver inspired by Webkit Copyright © 2016 Apple Inc. All rights reserved. https://webkit.org/demos/spring/spring.js
Spring solver inspired by Webkit Copyright © 2016 Apple Inc . All rights reserved . https : // webkit . org / demos / spring / spring . js
Spring function