Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                    <div id="canvas-holder" style="width:100%">
        <canvas id="chart-area" width="500" height="500" />
    </div>
    <button id="randomizeData">Randomize Data</button>
              
            
!

CSS

              
                body {
  padding: 0;
  margin: 0;
}

#canvas-holder {
  width: 50%;
}
              
            
!

JS

              
                
  (function() {

      "use strict";

      //Declare root variable - window in the browser, global on the server
      var root = this,
          previous = root.Chart;

      //Occupy the global variable of Chart, and create a simple base class
      var Chart = function(context) {
          var chart = this;
          this.canvas = context.canvas;

          this.ctx = context;

          //Variables global to the chart
          var computeDimension = function(element, dimension) {
              if (element['offset' + dimension]) {
                  return element['offset' + dimension];
              } else {
                  return document.defaultView.getComputedStyle(element).getPropertyValue(dimension);
              }
          };

          var width = this.width = computeDimension(context.canvas, 'Width') || context.canvas.width;
          var height = this.height = computeDimension(context.canvas, 'Height') || context.canvas.height;

          // Firefox requires this to work correctly
          context.canvas.width = width;
          context.canvas.height = height;

          width = this.width = context.canvas.width;
          height = this.height = context.canvas.height;
          this.aspectRatio = this.width / this.height;
          //High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
          helpers.retinaScale(this);

          return this;
      };

      var defaultColor = 'rgba(0,0,0,0.1)';

      //Globally expose the defaults to allow for user updating/changing
      Chart.defaults = {
          global: {
              animation: {
                  duration: 1000,
                  easing: "easeOutQuart",
                  onProgress: function() {},
                  onComplete: function() {},
              },
              responsive: true,
              maintainAspectRatio: true,
              events: ["mousemove", "mouseout", "click", "touchstart", "touchmove", "touchend"],
              hover: {
                  onHover: null,
                  mode: 'single',
                  animationDuration: 400,
              },
              onClick: null,
              tooltips: {
                  enabled: true,
                  custom: null,
                  backgroundColor: "rgba(0,0,0,0.8)",
                  fontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
                  fontSize: 10,
                  fontStyle: "normal",
                  fontColor: "#fff",
                  titleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
                  titleFontSize: 12,
                  titleFontStyle: "bold",
                  titleFontColor: "#fff",
                  yPadding: 6,
                  xPadding: 6,
                  caretSize: 8,
                  cornerRadius: 6,
                  xOffset: 10,
                  template: [
                      '<% if(label){ %>',
                      '<%=label %>:',
                      '<% } %>',
                      '<%=value %>',
                  ].join(''),
                  multiTemplate: [
                      '<%if (datasetLabel){ %>',
                      '<%=datasetLabel %>:',
                      '<% } %>',
                      '<%=value %>'
                  ].join(''),
                  multiKeyBackground: '#fff',

              },
              defaultColor: defaultColor,

              // Element defaults
              elements: {
                  line: {
                      tension: 0.4,
                      backgroundColor: defaultColor,
                      borderWidth: 3,
                      borderColor: defaultColor,
                      fill: true, // do we fill in the area between the line and the x axis
                      skipNull: true,
                      drawNull: false,
                  },
                  point: {
                      radius: 3,
                      backgroundColor: defaultColor,
                      borderWidth: 1,
                      borderColor: defaultColor,
                      // Hover
                      hitRadius: 6,
                      hoverRadius: 4,
                      hoverBorderWidth: 2,
                  },
                  bar: {
                      backgroundColor: defaultColor,
                      borderWidth: 0,
                      borderColor: defaultColor,
                      valueSpacing: 5,
                      datasetSpacing: 1,
                  },
                  slice: {
                      backgroundColor: defaultColor,
                      borderColor: "#fff",
                      borderWidth: 2,
                  },
              }
          },
      };

      //Create a dictionary of chart types, to allow for extension of existing types
      Chart.types = {};

      //Global Chart helpers object for utility methods and classes
      var helpers = Chart.helpers = {};

      //-- Basic js utility methods
      var each = helpers.each = function(loopable, callback, self) {
              var additionalArgs = Array.prototype.slice.call(arguments, 3);
              // Check to see if null or undefined firstly.
              if (loopable) {
                  if (loopable.length === +loopable.length) {
                      var i;
                      for (i = 0; i < loopable.length; i++) {
                          callback.apply(self, [loopable[i], i].concat(additionalArgs));
                      }
                  } else {
                      for (var item in loopable) {
                          callback.apply(self, [loopable[item], item].concat(additionalArgs));
                      }
                  }
              }
          },
          clone = helpers.clone = function(obj) {
              var objClone = {};
              each(obj, function(value, key) {
                  if (obj.hasOwnProperty(key)) {
                      objClone[key] = value;
                  }
              });
              return objClone;
          },
          extend = helpers.extend = function(base) {
              each(Array.prototype.slice.call(arguments, 1), function(extensionObject) {
                  each(extensionObject, function(value, key) {
                      if (extensionObject.hasOwnProperty(key)) {
                          base[key] = value;
                      }
                  });
              });
              return base;
          },
          merge = helpers.merge = function(base, master) {
              //Merge properties in left object over to a shallow clone of object right.
              var args = Array.prototype.slice.call(arguments, 0);
              args.unshift({});
              return extend.apply(null, args);
          },
          // Need a special merge function to chart configs since they are now grouped
          configMerge = helpers.configMerge = function(_base) {
              var base = clone(_base);
              helpers.each(Array.prototype.slice.call(arguments, 1), function(extension) {
                  helpers.each(extension, function(value, key) {
                      if (extension.hasOwnProperty(key)) {
                          if (base.hasOwnProperty(key) && helpers.isArray(base[key]) && helpers.isArray(value)) {
                              // In this case we have an array of objects replacing another array. Rather than doing a strict replace,
                              // merge. This allows easy scale option merging
                              var baseArray = base[key];

                              helpers.each(value, function(valueObj, index) {
                                  if (index < baseArray.length) {
                                      baseArray[index] = helpers.configMerge(baseArray[index], valueObj);
                                  } else {
                                      baseArray.push(valueObj); // nothing to merge
                                  }
                              });
                          } else if (base.hasOwnProperty(key) && typeof base[key] == "object" && typeof value == "object") {
                              // If we are overwriting an object with an object, do a merge of the properties.
                              base[key] = helpers.configMerge(base[key], value);
                          } else {
                              // can just overwrite the value in this case
                              base[key] = value;
                          }
                      }
                  });
              });

              return base;
          },
          getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault = function(value, index, defaultValue) {
              if (!value) {
                  return defaultValue;
              }

              if (helpers.isArray(value) && index < value.length) {
                  return value[index];
              }

              return value;
          },
          indexOf = helpers.indexOf = function(arrayToSearch, item) {
              if (Array.prototype.indexOf) {
                  return arrayToSearch.indexOf(item);
              } else {
                  for (var i = 0; i < arrayToSearch.length; i++) {
                      if (arrayToSearch[i] === item) return i;
                  }
                  return -1;
              }
          },
          where = helpers.where = function(collection, filterCallback) {
              var filtered = [];

              helpers.each(collection, function(item) {
                  if (filterCallback(item)) {
                      filtered.push(item);
                  }
              });

              return filtered;
          },
          findNextWhere = helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex) {
              // Default to start of the array
              if (!startIndex) {
                  startIndex = -1;
              }
              for (var i = startIndex + 1; i < arrayToSearch.length; i++) {
                  var currentItem = arrayToSearch[i];
                  if (filterCallback(currentItem)) {
                      return currentItem;
                  }
              }
          },
          findPreviousWhere = helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) {
              // Default to end of the array
              if (!startIndex) {
                  startIndex = arrayToSearch.length;
              }
              for (var i = startIndex - 1; i >= 0; i--) {
                  var currentItem = arrayToSearch[i];
                  if (filterCallback(currentItem)) {
                      return currentItem;
                  }
              }
          },
          inherits = helpers.inherits = function(extensions) {
              //Basic javascript inheritance based on the model created in Backbone.js
              var parent = this;
              var ChartElement = (extensions && extensions.hasOwnProperty("constructor")) ? extensions.constructor : function() {
                  return parent.apply(this, arguments);
              };

              var Surrogate = function() {
                  this.constructor = ChartElement;
              };
              Surrogate.prototype = parent.prototype;
              ChartElement.prototype = new Surrogate();

              ChartElement.extend = inherits;

              if (extensions) extend(ChartElement.prototype, extensions);

              ChartElement.__super__ = parent.prototype;

              return ChartElement;
          },
          noop = helpers.noop = function() {},
          uid = helpers.uid = (function() {
              var id = 0;
              return function() {
                  return "chart-" + id++;
              };
          })(),
          warn = helpers.warn = function(str) {
              //Method for warning of errors
              if (window.console && typeof window.console.warn === "function") console.warn(str);
          },
          amd = helpers.amd = (typeof define === 'function' && define.amd),
          //-- Math methods
          isNumber = helpers.isNumber = function(n) {
              return !isNaN(parseFloat(n)) && isFinite(n);
          },
          max = helpers.max = function(array) {
              return Math.max.apply(Math, array);
          },
          min = helpers.min = function(array) {
              return Math.min.apply(Math, array);
          },
          sign = helpers.sign = function(x) {
              if (Math.sign) {
                  return Math.sign(x);
              } else {
                  x = +x; // convert to a number
                  if (x === 0 || isNaN(x)) {
                      return x;
                  }
                  return x > 0 ? 1 : -1;
              }
          },
          cap = helpers.cap = function(valueToCap, maxValue, minValue) {
              if (isNumber(maxValue)) {
                  if (valueToCap > maxValue) {
                      return maxValue;
                  }
              } else if (isNumber(minValue)) {
                  if (valueToCap < minValue) {
                      return minValue;
                  }
              }
              return valueToCap;
          },
          getDecimalPlaces = helpers.getDecimalPlaces = function(num) {
              if (num % 1 !== 0 && isNumber(num)) {
                  var s = num.toString();
                  if (s.indexOf("e-") < 0) {
                      // no exponent, e.g. 0.01
                      return s.split(".")[1].length;
                  } else if (s.indexOf(".") < 0) {
                      // no decimal point, e.g. 1e-9
                      return parseInt(s.split("e-")[1]);
                  } else {
                      // exponent and decimal point, e.g. 1.23e-9
                      var parts = s.split(".")[1].split("e-");
                      return parts[0].length + parseInt(parts[1]);
                  }
              } else {
                  return 0;
              }
          },
          toRadians = helpers.toRadians = function(degrees) {
              return degrees * (Math.PI / 180);
          },
          toDegrees = helpers.toDegrees = function(radians) {
              return radians * (180 / Math.PI);
          },
          // Gets the angle from vertical upright to the point about a centre.
          getAngleFromPoint = helpers.getAngleFromPoint = function(centrePoint, anglePoint) {
              var distanceFromXCenter = anglePoint.x - centrePoint.x,
                  distanceFromYCenter = anglePoint.y - centrePoint.y,
                  radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);

              var angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);

              if (angle < (-0.5 * Math.PI)) {
                  angle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2]
              }

              return {
                  angle: angle,
                  distance: radialDistanceFromCenter
              };
          },
          aliasPixel = helpers.aliasPixel = function(pixelWidth) {
              return (pixelWidth % 2 === 0) ? 0 : 0.5;
          },
          splineCurve = helpers.splineCurve = function(FirstPoint, MiddlePoint, AfterPoint, t) {
              //Props to Rob Spencer at scaled innovation for his post on splining between points
              //http://scaledinnovation.com/analytics/splines/aboutSplines.html
              var d01 = Math.sqrt(Math.pow(MiddlePoint.x - FirstPoint.x, 2) + Math.pow(MiddlePoint.y - FirstPoint.y, 2)),
                  d12 = Math.sqrt(Math.pow(AfterPoint.x - MiddlePoint.x, 2) + Math.pow(AfterPoint.y - MiddlePoint.y, 2)),
                  fa = t * d01 / (d01 + d12), // scaling factor for triangle Ta
                  fb = t * d12 / (d01 + d12);
              return {
                  previous: {
                      x: MiddlePoint.x - fa * (AfterPoint.x - FirstPoint.x),
                      y: MiddlePoint.y - fa * (AfterPoint.y - FirstPoint.y)
                  },
                  next: {
                      x: MiddlePoint.x + fb * (AfterPoint.x - FirstPoint.x),
                      y: MiddlePoint.y + fb * (AfterPoint.y - FirstPoint.y)
                  }
              };
          },
          calculateOrderOfMagnitude = helpers.calculateOrderOfMagnitude = function(val) {
              return Math.floor(Math.log(val) / Math.LN10);
          },
          calculateScaleRange = helpers.calculateScaleRange = function(valuesArray, drawingSize, textSize, startFromZero, integersOnly) {

              //Set a minimum step of two - a point at the top of the graph, and a point at the base
              var minSteps = 2,
                  maxSteps = Math.floor(drawingSize / (textSize * 1.5)),
                  skipFitting = (minSteps >= maxSteps);

              var maxValue = max(valuesArray),
                  minValue = min(valuesArray);

              // We need some degree of seperation here to calculate the scales if all the values are the same
              // Adding/minusing 0.5 will give us a range of 1.
              if (maxValue === minValue) {
                  maxValue += 0.5;
                  // So we don't end up with a graph with a negative start value if we've said always start from zero
                  if (minValue >= 0.5 && !startFromZero) {
                      minValue -= 0.5;
                  } else {
                      // Make up a whole number above the values
                      maxValue += 0.5;
                  }
              }

              var valueRange = Math.abs(maxValue - minValue),
                  rangeOrderOfMagnitude = calculateOrderOfMagnitude(valueRange),
                  graphMax = Math.ceil(maxValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),
                  graphMin = (startFromZero) ? 0 : Math.floor(minValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),
                  graphRange = graphMax - graphMin,
                  stepValue = Math.pow(10, rangeOrderOfMagnitude),
                  numberOfSteps = Math.round(graphRange / stepValue);

              //If we have more space on the graph we'll use it to give more definition to the data
              while ((numberOfSteps > maxSteps || (numberOfSteps * 2) < maxSteps) && !skipFitting) {
                  if (numberOfSteps > maxSteps) {
                      stepValue *= 2;
                      numberOfSteps = Math.round(graphRange / stepValue);
                      // Don't ever deal with a decimal number of steps - cancel fitting and just use the minimum number of steps.
                      if (numberOfSteps % 1 !== 0) {
                          skipFitting = true;
                      }
                  }
                  //We can fit in double the amount of scale points on the scale
                  else {
                      //If user has declared ints only, and the step value isn't a decimal
                      if (integersOnly && rangeOrderOfMagnitude >= 0) {
                          //If the user has said integers only, we need to check that making the scale more granular wouldn't make it a float
                          if (stepValue / 2 % 1 === 0) {
                              stepValue /= 2;
                              numberOfSteps = Math.round(graphRange / stepValue);
                          }
                          //If it would make it a float break out of the loop
                          else {
                              break;
                          }
                      }
                      //If the scale doesn't have to be an int, make the scale more granular anyway.
                      else {
                          stepValue /= 2;
                          numberOfSteps = Math.round(graphRange / stepValue);
                      }

                  }
              }

              if (skipFitting) {
                  numberOfSteps = minSteps;
                  stepValue = graphRange / numberOfSteps;
              }
              return {
                  steps: numberOfSteps,
                  stepValue: stepValue,
                  min: graphMin,
                  max: graphMin + (numberOfSteps * stepValue)
              };

          },
          // Implementation of the nice number algorithm used in determining where axis labels will go
          niceNum = helpers.niceNum = function(range, round) {
              var exponent = Math.floor(Math.log10(range));
              var fraction = range / Math.pow(10, exponent);
              var niceFraction;

              if (round) {
                  if (fraction < 1.5) {
                      niceFraction = 1;
                  } else if (fraction < 3) {
                      niceFraction = 2;
                  } else if (fraction < 7) {
                      niceFraction = 5;
                  } else {
                      niceFraction = 10;
                  }
              } else {
                  if (fraction <= 1.0) {
                      niceFraction = 1;
                  } else if (fraction <= 2) {
                      niceFraction = 2;
                  } else if (fraction <= 5) {
                      niceFraction = 5;
                  } else {
                      niceFraction = 10;
                  }
              }

              return niceFraction * Math.pow(10, exponent);
          },
          /* jshint ignore:start */
          // Blows up jshint errors based on the new Function constructor
          //Templating methods
          //Javascript micro templating by John Resig - source at http://ejohn.org/blog/javascript-micro-templating/
          template = helpers.template = function(templateString, valuesObject) {

              // If templateString is function rather than string-template - call the function for valuesObject

              if (templateString instanceof Function) {
                  return templateString(valuesObject);
              }

              var cache = {};

              function tmpl(str, data) {
                  // Figure out if we're getting a template, or if we need to
                  // load the template - and be sure to cache the result.
                  var fn = !/\W/.test(str) ?
                      cache[str] = cache[str] :

                      // Generate a reusable function that will serve as a template
                      // generator (and which will be cached).
                      new Function("obj",
                          "var p=[],print=function(){p.push.apply(p,arguments);};" +

                          // Introduce the data as local variables using with(){}
                          "with(obj){p.push('" +

                          // Convert the template into pure JavaScript
                          str
                          .replace(/[\r\t\n]/g, " ")
                          .split("<%").join("\t")
                          .replace(/((^|%>)[^\t]*)'/g, "$1\r")
                          .replace(/\t=(.*?)%>/g, "',$1,'")
                          .split("\t").join("');")
                          .split("%>").join("p.push('")
                          .split("\r").join("\\'") +
                          "');}return p.join('');"
                      );

                  // Provide some basic currying to the user
                  return data ? fn(data) : fn;
              }
              return tmpl(templateString, valuesObject);
          },
          /* jshint ignore:end */
          generateLabels = helpers.generateLabels = function(templateString, numberOfSteps, graphMin, stepValue) {
              var labelsArray = new Array(numberOfSteps);
              if (templateString) {
                  each(labelsArray, function(val, index) {
                      labelsArray[index] = template(templateString, {
                          value: (graphMin + (stepValue * (index + 1)))
                      });
                  });
              }
              return labelsArray;
          },
          //--Animation methods
          //Easing functions adapted from Robert Penner's easing equations
          //http://www.robertpenner.com/easing/
          easingEffects = helpers.easingEffects = {
              linear: function(t) {
                  return t;
              },
              easeInQuad: function(t) {
                  return t * t;
              },
              easeOutQuad: function(t) {
                  return -1 * t * (t - 2);
              },
              easeInOutQuad: function(t) {
                  if ((t /= 1 / 2) < 1) {
                      return 1 / 2 * t * t;
                  }
                  return -1 / 2 * ((--t) * (t - 2) - 1);
              },
              easeInCubic: function(t) {
                  return t * t * t;
              },
              easeOutCubic: function(t) {
                  return 1 * ((t = t / 1 - 1) * t * t + 1);
              },
              easeInOutCubic: function(t) {
                  if ((t /= 1 / 2) < 1) {
                      return 1 / 2 * t * t * t;
                  }
                  return 1 / 2 * ((t -= 2) * t * t + 2);
              },
              easeInQuart: function(t) {
                  return t * t * t * t;
              },
              easeOutQuart: function(t) {
                  return -1 * ((t = t / 1 - 1) * t * t * t - 1);
              },
              easeInOutQuart: function(t) {
                  if ((t /= 1 / 2) < 1) {
                      return 1 / 2 * t * t * t * t;
                  }
                  return -1 / 2 * ((t -= 2) * t * t * t - 2);
              },
              easeInQuint: function(t) {
                  return 1 * (t /= 1) * t * t * t * t;
              },
              easeOutQuint: function(t) {
                  return 1 * ((t = t / 1 - 1) * t * t * t * t + 1);
              },
              easeInOutQuint: function(t) {
                  if ((t /= 1 / 2) < 1) {
                      return 1 / 2 * t * t * t * t * t;
                  }
                  return 1 / 2 * ((t -= 2) * t * t * t * t + 2);
              },
              easeInSine: function(t) {
                  return -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;
              },
              easeOutSine: function(t) {
                  return 1 * Math.sin(t / 1 * (Math.PI / 2));
              },
              easeInOutSine: function(t) {
                  return -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);
              },
              easeInExpo: function(t) {
                  return (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));
              },
              easeOutExpo: function(t) {
                  return (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);
              },
              easeInOutExpo: function(t) {
                  if (t === 0) {
                      return 0;
                  }
                  if (t === 1) {
                      return 1;
                  }
                  if ((t /= 1 / 2) < 1) {
                      return 1 / 2 * Math.pow(2, 10 * (t - 1));
                  }
                  return 1 / 2 * (-Math.pow(2, -10 * --t) + 2);
              },
              easeInCirc: function(t) {
                  if (t >= 1) {
                      return t;
                  }
                  return -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);
              },
              easeOutCirc: function(t) {
                  return 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);
              },
              easeInOutCirc: function(t) {
                  if ((t /= 1 / 2) < 1) {
                      return -1 / 2 * (Math.sqrt(1 - t * t) - 1);
                  }
                  return 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);
              },
              easeInElastic: function(t) {
                  var s = 1.70158;
                  var p = 0;
                  var a = 1;
                  if (t === 0) {
                      return 0;
                  }
                  if ((t /= 1) == 1) {
                      return 1;
                  }
                  if (!p) {
                      p = 1 * 0.3;
                  }
                  if (a < Math.abs(1)) {
                      a = 1;
                      s = p / 4;
                  } else {
                      s = p / (2 * Math.PI) * Math.asin(1 / a);
                  }
                  return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
              },
              easeOutElastic: function(t) {
                  var s = 1.70158;
                  var p = 0;
                  var a = 1;
                  if (t === 0) {
                      return 0;
                  }
                  if ((t /= 1) == 1) {
                      return 1;
                  }
                  if (!p) {
                      p = 1 * 0.3;
                  }
                  if (a < Math.abs(1)) {
                      a = 1;
                      s = p / 4;
                  } else {
                      s = p / (2 * Math.PI) * Math.asin(1 / a);
                  }
                  return a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;
              },
              easeInOutElastic: function(t) {
                  var s = 1.70158;
                  var p = 0;
                  var a = 1;
                  if (t === 0) {
                      return 0;
                  }
                  if ((t /= 1 / 2) == 2) {
                      return 1;
                  }
                  if (!p) {
                      p = 1 * (0.3 * 1.5);
                  }
                  if (a < Math.abs(1)) {
                      a = 1;
                      s = p / 4;
                  } else {
                      s = p / (2 * Math.PI) * Math.asin(1 / a);
                  }
                  if (t < 1) {
                      return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
                  }
                  return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;
              },
              easeInBack: function(t) {
                  var s = 1.70158;
                  return 1 * (t /= 1) * t * ((s + 1) * t - s);
              },
              easeOutBack: function(t) {
                  var s = 1.70158;
                  return 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);
              },
              easeInOutBack: function(t) {
                  var s = 1.70158;
                  if ((t /= 1 / 2) < 1) {
                      return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));
                  }
                  return 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);
              },
              easeInBounce: function(t) {
                  return 1 - easingEffects.easeOutBounce(1 - t);
              },
              easeOutBounce: function(t) {
                  if ((t /= 1) < (1 / 2.75)) {
                      return 1 * (7.5625 * t * t);
                  } else if (t < (2 / 2.75)) {
                      return 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);
                  } else if (t < (2.5 / 2.75)) {
                      return 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);
                  } else {
                      return 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);
                  }
              },
              easeInOutBounce: function(t) {
                  if (t < 1 / 2) {
                      return easingEffects.easeInBounce(t * 2) * 0.5;
                  }
                  return easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;
              }
          },
          //Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
          requestAnimFrame = helpers.requestAnimFrame = (function() {
              return window.requestAnimationFrame ||
                  window.webkitRequestAnimationFrame ||
                  window.mozRequestAnimationFrame ||
                  window.oRequestAnimationFrame ||
                  window.msRequestAnimationFrame ||
                  function(callback) {
                      return window.setTimeout(callback, 1000 / 60);
                  };
          })(),
          cancelAnimFrame = helpers.cancelAnimFrame = (function() {
              return window.cancelAnimationFrame ||
                  window.webkitCancelAnimationFrame ||
                  window.mozCancelAnimationFrame ||
                  window.oCancelAnimationFrame ||
    
              
            
!
999px

Console