// Generated by CoffeeScript 1.4.0 (function() { var Animation, Animations, Bezier, Dynamic, DynamicElement, Dynamics, EaseInOut, Gravity, GravityWithForce, Linear, Loop, Matrix, SelfSpring, Spring, Vector, animationFrame, animationStart, browserSupportPrefixFor, browserSupportTransform, browserSupportWithPrefix, cacheFn, combineVector, convertToMatrix3d, css, decomposeMatrix, defaultForProperty, degProperties, getFirstFrame, hasCommonProperties, interpolateMatrix, keysForTransform, lengthVector, matrixToString, normalizeVector, parseFrames, propertiesAtFrame, pxProperties, recomposeMatrix, set, stopAnimationsForEl, transformProperties, transformStringToMatrixString, unitFor, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Vector = (function() { function Vector(els) { this.els = els; this.cross = __bind(this.cross, this); this.dot = __bind(this.dot, this); this.e = __bind(this.e, this); } Vector.prototype.e = function(i) { if (i < 1 || i > this.els.length) { return null; } else { return this.els[i - 1]; } }; Vector.prototype.dot = function(vector) { var V, n, product; V = vector.els || vector; product = 0; n = this.els.length; if (n !== V.length) { return null; } n += 1; while (--n) { product += this.els[n - 1] * V[n - 1]; } return product; }; Vector.prototype.cross = function(vector) { var A, B; B = vector.els || vector; if (this.els.length !== 3 || B.length !== 3) { return null; } A = this.els; return new Vector([(A[1] * B[2]) - (A[2] * B[1]), (A[2] * B[0]) - (A[0] * B[2]), (A[0] * B[1]) - (A[1] * B[0])]); }; return Vector; })(); Matrix = (function() { function Matrix(els) { this.els = els; this.inverse = __bind(this.inverse, this); this.augment = __bind(this.augment, this); this.toRightTriangular = __bind(this.toRightTriangular, this); this.transpose = __bind(this.transpose, this); this.multiply = __bind(this.multiply, this); this.dup = __bind(this.dup, this); this.e = __bind(this.e, this); } Matrix.prototype.e = function(i, j) { if (i < 1 || i > this.els.length || j < 1 || j > this.els[0].length) { return null; } return this.els[i - 1][j - 1]; }; Matrix.prototype.dup = function() { return new Matrix(this.els); }; Matrix.prototype.multiply = function(matrix) { var M, c, cols, elements, i, j, ki, kj, nc, ni, nj, returnVector, sum; returnVector = matrix.modulus ? true : false; M = matrix.els || matrix; if (typeof M[0][0] === 'undefined') { M = new Matrix(M).els; } ni = this.els.length; ki = ni; kj = M[0].length; cols = this.els[0].length; elements = []; ni += 1; while (--ni) { i = ki - ni; elements[i] = []; nj = kj; nj += 1; while (--nj) { j = kj - nj; sum = 0; nc = cols; nc += 1; while (--nc) { c = cols - nc; sum += this.els[i][c] * M[c][j]; } elements[i][j] = sum; } } M = new Matrix(elements); if (returnVector) { return M.col(1); } else { return M; } }; Matrix.prototype.transpose = function() { var cols, elements, i, j, ni, nj, rows; rows = this.els.length; cols = this.els[0].length; elements = []; ni = cols; ni += 1; while (--ni) { i = cols - ni; elements[i] = []; nj = rows; nj += 1; while (--nj) { j = rows - nj; elements[i][j] = this.els[j][i]; } } return new Matrix(elements); }; Matrix.prototype.toRightTriangular = function() { var M, els, i, j, k, kp, multiplier, n, np, p, _i, _j, _ref, _ref1; M = this.dup(); n = this.els.length; k = n; kp = this.els[0].length; while (--n) { i = k - n; if (M.els[i][i] === 0) { for (j = _i = _ref = i + 1; _ref <= k ? _i < k : _i > k; j = _ref <= k ? ++_i : --_i) { if (M.els[j][i] !== 0) { els = []; np = kp; np += 1; while (--np) { p = kp - np; els.push(M.els[i][p] + M.els[j][p]); } M.els[i] = els; break; } } } if (M.els[i][i] !== 0) { for (j = _j = _ref1 = i + 1; _ref1 <= k ? _j < k : _j > k; j = _ref1 <= k ? ++_j : --_j) { multiplier = M.els[j][i] / M.els[i][i]; els = []; np = kp; np += 1; while (--np) { p = kp - np; els.push(p <= i ? 0 : M.els[j][p] - M.els[i][p] * multiplier); } M.els[j] = els; } } } return M; }; Matrix.prototype.augment = function(matrix) { var M, T, cols, i, j, ki, kj, ni, nj; M = matrix.els || matrix; if (typeof M[0][0] === 'undefined') { M = new Matrix(M).els; } T = this.dup(); cols = T.els[0].length; ni = T.els.length; ki = ni; kj = M[0].length; if (ni !== M.length) { return null; } ni += 1; while (--ni) { i = ki - ni; nj = kj; nj += 1; while (--nj) { j = kj - nj; T.els[i][cols + j] = M[i][j]; } } return T; }; Matrix.prototype.inverse = function() { var M, divisor, els, i, inverse_elements, j, ki, kp, new_element, np, p, vni, _i; vni = this.els.length; ki = ni; M = this.augment(Matrix.I(ni)).toRightTriangular(); kp = M.els[0].length; inverse_elements = []; ni += 1; while (--ni) { i = ni - 1; els = []; np = kp; inverse_elements[i] = []; divisor = M.els[i][i]; np += 1; while (--np) { p = kp - np; new_element = M.els[i][p] / divisor; els.push(new_element); if (p >= ki) { inverse_elements[i].push(new_element); } } M.els[i] = els; for (j = _i = 0; 0 <= i ? _i < i : _i > i; j = 0 <= i ? ++_i : --_i) { els = []; np = kp; np += 1; while (--np) { p = kp - np; els.push(M.els[j][p] - M.els[i][p] * M.els[j][i]); } M.els[j] = els; } } return new Matrix(inverse_elements); }; Matrix.I = function(n) { var els, i, j, k, nj; els = []; k = n; n += 1; while (--n) { i = k - n; els[i] = []; nj = k; nj += 1; while (--nj) { j = k - nj; els[i][j] = i === j ? 1 : 0; } } return new Matrix(els); }; return Matrix; })(); Dynamic = (function() { Dynamic.properties = {}; function Dynamic(options) { var k, v, _ref; this.options = options != null ? options : {}; this.next = __bind(this.next, this); this.init = __bind(this.init, this); _ref = this.options.type.properties; for (k in _ref) { v = _ref[k]; if (!(this.options[k] != null) && !v.editable) { this.options[k] = v["default"]; } } } Dynamic.prototype.init = function() { return this.t = 0; }; Dynamic.prototype.next = function(step) { var r; if (this.t > 1) { this.t = 1; } r = this.at(this.t); this.t += step; return r; }; Dynamic.prototype.at = function(t) { return [t, t]; }; return Dynamic; })(); Linear = (function(_super) { __extends(Linear, _super); function Linear() { return Linear.__super__.constructor.apply(this, arguments); } Linear.properties = { duration: { min: 100, max: 4000, "default": 1000 } }; Linear.prototype.at = function(t) { return [t, t]; }; return Linear; })(Dynamic); Gravity = (function(_super) { __extends(Gravity, _super); Gravity.properties = { bounce: { min: 0, max: 80, "default": 40 }, gravity: { min: 1, max: 4000, "default": 1000 }, expectedDuration: { editable: false } }; function Gravity(options) { var _ref; this.options = options != null ? options : {}; this.at = __bind(this.at, this); this.curve = __bind(this.curve, this); this.init = __bind(this.init, this); this.length = __bind(this.length, this); this.gravityValue = __bind(this.gravityValue, this); this.bounceValue = __bind(this.bounceValue, this); this.duration = __bind(this.duration, this); this.expectedDuration = __bind(this.expectedDuration, this); if ((_ref = this.initialForce) == null) { this.initialForce = false; } this.options.duration = this.duration(); Gravity.__super__.constructor.call(this, this.options); } Gravity.prototype.expectedDuration = function() { return this.duration(); }; Gravity.prototype.duration = function() { return Math.round(1000 * 1000 / this.options.gravity * this.length()); }; Gravity.prototype.bounceValue = function() { return Math.min(this.options.bounce / 100, 80); }; Gravity.prototype.gravityValue = function() { return this.options.gravity / 100; }; Gravity.prototype.length = function() { var L, b, bounce, curve, gravity; bounce = this.bounceValue(); gravity = this.gravityValue(); b = Math.sqrt(2 / gravity); curve = { a: -b, b: b, H: 1 }; if (this.initialForce) { curve.a = 0; curve.b = curve.b * 2; } while (curve.H > 0.001) { L = curve.b - curve.a; curve = { a: curve.b, b: curve.b + L * bounce, H: curve.H * bounce * bounce }; } return curve.b; }; Gravity.prototype.init = function() { var L, b, bounce, curve, gravity, _results; Gravity.__super__.init.apply(this, arguments); L = this.length(); gravity = this.gravityValue() * L * L; bounce = this.bounceValue(); b = Math.sqrt(2 / gravity); this.curves = []; curve = { a: -b, b: b, H: 1 }; if (this.initialForce) { curve.a = 0; curve.b = curve.b * 2; } this.curves.push(curve); _results = []; while (curve.b < 1 && curve.H > 0.001) { L = curve.b - curve.a; curve = { a: curve.b, b: curve.b + L * bounce, H: curve.H * bounce * bounce }; _results.push(this.curves.push(curve)); } return _results; }; Gravity.prototype.curve = function(a, b, H, t) { var L, c, t2; L = b - a; t2 = (2 / L) * t - 1 - (a * 2 / L); c = t2 * t2 * H - H + 1; if (this.initialForce) { c = 1 - c; } return c; }; Gravity.prototype.at = function(t) { var bounce, curve, gravity, i, v; bounce = this.options.bounce / 100; gravity = this.options.gravity; i = 0; curve = this.curves[i]; while (!(t >= curve.a && t <= curve.b)) { i += 1; curve = this.curves[i]; if (!curve) { break; } } if (!curve) { v = this.initialForce ? 0 : 1; } else { v = this.curve(curve.a, curve.b, curve.H, t); } return [t, v]; }; return Gravity; })(Dynamic); GravityWithForce = (function(_super) { __extends(GravityWithForce, _super); GravityWithForce.prototype.returnsToSelf = true; function GravityWithForce(options) { this.options = options != null ? options : {}; this.initialForce = true; GravityWithForce.__super__.constructor.call(this, this.options); } return GravityWithForce; })(Gravity); Spring = (function(_super) { __extends(Spring, _super); function Spring() { this.at = __bind(this.at, this); return Spring.__super__.constructor.apply(this, arguments); } Spring.properties = { frequency: { min: 0, max: 100, "default": 15 }, friction: { min: 1, max: 1000, "default": 200 }, anticipationStrength: { min: 0, max: 1000, "default": 0 }, anticipationSize: { min: 0, max: 99, "default": 0 }, duration: { min: 100, max: 4000, "default": 1000 } }; Spring.prototype.at = function(t) { var A, At, a, angle, b, decal, frequency, friction, frictionT, s, v, y0, yS, _this = this; frequency = Math.max(1, this.options.frequency); friction = Math.pow(20, this.options.friction / 100); s = this.options.anticipationSize / 100; decal = Math.max(0, s); frictionT = (t / (1 - s)) - (s / (1 - s)); if (t < s) { A = function(t) { var M, a, b, x0, x1; M = 0.8; x0 = s / (1 - s); x1 = 0; b = (x0 - (M * x1)) / (x0 - x1); a = (M - b) / x0; return (a * t * _this.options.anticipationStrength / 100) + b; }; yS = (s / (1 - s)) - (s / (1 - s)); y0 = (0 / (1 - s)) - (s / (1 - s)); b = Math.acos(1 / A(yS)); a = (Math.acos(1 / A(y0)) - b) / (frequency * (-s)); } else { A = function(t) { return Math.pow(friction / 10, -t) * (1 - t); }; b = 0; a = 1; } At = A(frictionT); angle = frequency * (t - s) * a + b; v = 1 - (At * Math.cos(angle)); return [t, v, At, frictionT, angle]; }; return Spring; })(Dynamic); SelfSpring = (function(_super) { __extends(SelfSpring, _super); function SelfSpring() { this.at = __bind(this.at, this); return SelfSpring.__super__.constructor.apply(this, arguments); } SelfSpring.properties = { frequency: { min: 0, max: 100, "default": 15 }, friction: { min: 1, max: 1000, "default": 200 }, duration: { min: 100, max: 4000, "default": 1000 } }; SelfSpring.prototype.returnsToSelf = true; SelfSpring.prototype.at = function(t) { var A, At, At2, Ax, angle, frequency, friction, v, _this = this; frequency = Math.max(1, this.options.frequency); friction = Math.pow(20, this.options.friction / 100); A = function(t) { return 1 - Math.pow(friction / 10, -t) * (1 - t); }; At = A(t); At2 = A(1 - t); Ax = (Math.cos(t * 2 * 3.14 - 3.14) / 2) + 0.5; Ax = Math.pow(Ax, this.options.friction / 100); angle = frequency * t; v = Math.cos(angle) * Ax; return [t, v, Ax, -Ax]; }; return SelfSpring; })(Dynamic); Bezier = (function(_super) { __extends(Bezier, _super); Bezier.properties = { points: { type: 'points', "default": [ { x: 0, y: 0, controlPoints: [ { x: 0.2, y: 0 } ] }, { x: 0.5, y: 1.2, controlPoints: [ { x: 0.3, y: 1.2 }, { x: 0.8, y: 1.2 } ] }, { x: 1, y: 1, controlPoints: [ { x: 0.8, y: 1 } ] } ] }, duration: { min: 100, max: 4000, "default": 1000 } }; function Bezier(options) { this.options = options != null ? options : {}; this.at = __bind(this.at, this); this.yForX = __bind(this.yForX, this); this.B = __bind(this.B, this); this.returnsToSelf = this.options.points[this.options.points.length - 1].y === 0; Bezier.__super__.constructor.call(this, this.options); } Bezier.prototype.B_ = function(t, p0, p1, p2, p3) { return (Math.pow(1 - t, 3) * p0) + (3 * Math.pow(1 - t, 2) * t * p1) + (3 * (1 - t) * Math.pow(t, 2) * p2) + Math.pow(t, 3) * p3; }; Bezier.prototype.B = function(t, p0, p1, p2, p3) { return { x: this.B_(t, p0.x, p1.x, p2.x, p3.x), y: this.B_(t, p0.y, p1.y, p2.y, p3.y) }; }; Bezier.prototype.yForX = function(xTarget, Bs) { var B, aB, i, lower, percent, upper, x, xTolerance, _i, _len; B = null; for (_i = 0, _len = Bs.length; _i < _len; _i++) { aB = Bs[_i]; if (xTarget >= aB(0).x && xTarget <= aB(1).x) { B = aB; } if (B !== null) { break; } } if (!B) { if (this.returnsToSelf) { return 0; } else { return 1; } } xTolerance = 0.0001; lower = 0; upper = 1; percent = (upper + lower) / 2; x = B(percent).x; i = 0; while (Math.abs(xTarget - x) > xTolerance && i < 100) { if (xTarget > x) { lower = percent; } else { upper = percent; } percent = (upper + lower) / 2; x = B(percent).x; i += 1; } return B(percent).y; }; Bezier.prototype.at = function(t) { var Bs, i, k, points, x, y, _fn, _this = this; x = t; points = this.options.points || Bezier.properties.points["default"]; Bs = []; _fn = function(pointA, pointB) { var B; B = function(t) { return _this.B(t, pointA, pointA.controlPoints[pointA.controlPoints.length - 1], pointB.controlPoints[0], pointB); }; return Bs.push(B); }; for (i in points) { k = parseInt(i); if (k >= points.length - 1) { break; } _fn(points[k], points[k + 1]); } y = this.yForX(x, Bs); return [x, y]; }; return Bezier; })(Dynamic); EaseInOut = (function(_super) { __extends(EaseInOut, _super); EaseInOut.properties = { friction: { min: 1, max: 1000, "default": 500 }, duration: { min: 100, max: 4000, "default": 1000 } }; function EaseInOut(options) { var friction, points; this.options = options != null ? options : {}; this.at = __bind(this.at, this); EaseInOut.__super__.constructor.apply(this, arguments); friction = this.options.friction || EaseInOut.properties.friction["default"]; points = [ { x: 0, y: 0, controlPoints: [ { x: 1 - (friction / 1000), y: 0 } ] }, { x: 1, y: 1, controlPoints: [ { x: friction / 1000, y: 1 } ] } ]; this.bezier = new Bezier({ type: Bezier, duration: this.options.duration, points: points }); } EaseInOut.prototype.at = function(t) { return this.bezier.at(t); }; return EaseInOut; })(Dynamic); cacheFn = function(func) { var cachedMethod, data; data = {}; cachedMethod = function() { var k, key, result, _i, _len; key = ""; for (_i = 0, _len = arguments.length; _i < _len; _i++) { k = arguments[_i]; key += k.toString() + ","; } result = data[key]; if (!result) { data[key] = result = func.apply(this, arguments); } return result; }; return cachedMethod; }; browserSupportTransform = function() { return browserSupportWithPrefix("transform"); }; browserSupportPrefixFor = cacheFn(function(property) { var k, prefix, prop, propArray, propertyName, _i, _j, _len, _len1, _ref; propArray = property.split('-'); propertyName = ""; for (_i = 0, _len = propArray.length; _i < _len; _i++) { prop = propArray[_i]; propertyName += prop.substring(0, 1).toUpperCase() + prop.substring(1); } _ref = ["Webkit", "Moz"]; for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { prefix = _ref[_j]; k = prefix + propertyName; if (document.body.style[k] !== void 0) { return prefix; } } return ''; }); browserSupportWithPrefix = cacheFn(function(property) { var prefix; prefix = browserSupportPrefixFor(property); if (prefix === 'Moz') { return "" + prefix + (property.substring(0, 1).toUpperCase() + property.substring(1)); } if (prefix !== '') { return "-" + (prefix.toLowerCase()) + "-" + property; } return property; }); lengthVector = function(vector) { var a, e, _i, _len, _ref; a = 0; _ref = vector.els; for (_i = 0, _len = _ref.length; _i < _len; _i++) { e = _ref[_i]; a += Math.pow(e, 2); } return Math.sqrt(a); }; normalizeVector = function(vector) { var e, i, length, newElements, _ref; length = lengthVector(vector); newElements = []; _ref = vector.els; for (i in _ref) { e = _ref[i]; newElements[i] = e / length; } return new Vector(newElements); }; combineVector = function(a, b, ascl, bscl) { var i, result, _i; result = []; for (i = _i = 0; _i <= 2; i = ++_i) { result[i] = (ascl * a.els[i]) + (bscl * b.els[i]); } return new Vector(result); }; decomposeMatrix = function(matrix) { var els, i, inversePerspectiveMatrix, j, k, pdum3, perspective, perspectiveMatrix, quaternion, result, rightHandSide, rotate, row, rowElement, s, scale, skew, t, translate, transposedInversePerspectiveMatrix, type, typeKey, v, w, x, y, z, _i, _j, _k, _l, _m, _n, _o, _p; translate = []; scale = []; skew = []; quaternion = []; perspective = []; els = matrix.els; if (els[3][3] === 0) { return false; } for (i = _i = 0; _i <= 3; i = ++_i) { for (j = _j = 0; _j <= 3; j = ++_j) { els[i][j] /= els[3][3]; } } perspectiveMatrix = matrix.dup(); for (i = _k = 0; _k <= 2; i = ++_k) { perspectiveMatrix.els[i][3] = 0; } perspectiveMatrix.els[3][3] = 1; if (els[0][3] !== 0 || els[1][3] !== 0 || els[2][3] !== 0) { rightHandSide = new Vector(els.slice(0, 4)[3]); inversePerspectiveMatrix = perspectiveMatrix.inverse(); transposedInversePerspectiveMatrix = inversePerspectiveMatrix.transpose(); perspective = transposedInversePerspectiveMatrix.multiply(rightHandSide).els; for (i = _l = 0; _l <= 2; i = ++_l) { els[i][3] = 0; } els[3][3] = 1; } else { perspective = [0, 0, 0, 1]; } for (i = _m = 0; _m <= 2; i = ++_m) { translate[i] = els[3][i]; els[3][i] = 0; } row = []; for (i = _n = 0; _n <= 2; i = ++_n) { row[i] = new Vector(els[i].slice(0, 3)); } scale[0] = lengthVector(row[0]); row[0] = normalizeVector(row[0]); skew[0] = row[0].dot(row[1]); row[1] = combineVector(row[1], row[0], 1.0, -skew[0]); scale[1] = lengthVector(row[1]); row[1] = normalizeVector(row[1]); skew[0] /= scale[1]; skew[1] = row[0].dot(row[2]); row[2] = combineVector(row[2], row[0], 1.0, -skew[1]); skew[2] = row[1].dot(row[2]); row[2] = combineVector(row[2], row[1], 1.0, -skew[2]); scale[2] = lengthVector(row[2]); row[2] = normalizeVector(row[2]); skew[1] /= scale[2]; skew[2] /= scale[2]; pdum3 = row[1].cross(row[2]); if (row[0].dot(pdum3) < 0) { for (i = _o = 0; _o <= 2; i = ++_o) { scale[i] *= -1; for (j = _p = 0; _p <= 2; j = ++_p) { row[i].els[j] *= -1; } } } rowElement = function(index, elementIndex) { return row[index].els[elementIndex]; }; rotate = []; rotate[1] = Math.asin(-rowElement(0, 2)); if (Math.cos(rotate[1]) !== 0) { rotate[0] = Math.atan2(rowElement(1, 2), rowElement(2, 2)); rotate[2] = Math.atan2(rowElement(0, 1), rowElement(0, 0)); } else { rotate[0] = Math.atan2(-rowElement(2, 0), rowElement(1, 1)); rotate[1] = 0; } t = rowElement(0, 0) + rowElement(1, 1) + rowElement(2, 2) + 1.0; if (t > 1e-4) { s = 0.5 / Math.sqrt(t); w = 0.25 / s; x = (rowElement(2, 1) - rowElement(1, 2)) * s; y = (rowElement(0, 2) - rowElement(2, 0)) * s; z = (rowElement(1, 0) - rowElement(0, 1)) * s; } else if ((rowElement(0, 0) > rowElement(1, 1)) && (rowElement(0, 0) > rowElement(2, 2))) { s = Math.sqrt(1.0 + rowElement(0, 0) - rowElement(1, 1) - rowElement(2, 2)) * 2.0; x = 0.25 * s; y = (rowElement(0, 1) + rowElement(1, 0)) / s; z = (rowElement(0, 2) + rowElement(2, 0)) / s; w = (rowElement(2, 1) - rowElement(1, 2)) / s; } else if (rowElement(1, 1) > rowElement(2, 2)) { s = Math.sqrt(1.0 + rowElement(1, 1) - rowElement(0, 0) - rowElement(2, 2)) * 2.0; x = (rowElement(0, 1) + rowElement(1, 0)) / s; y = 0.25 * s; z = (rowElement(1, 2) + rowElement(2, 1)) / s; w = (rowElement(0, 2) - rowElement(2, 0)) / s; } else { s = Math.sqrt(1.0 + rowElement(2, 2) - rowElement(0, 0) - rowElement(1, 1)) * 2.0; x = (rowElement(0, 2) + rowElement(2, 0)) / s; y = (rowElement(1, 2) + rowElement(2, 1)) / s; z = 0.25 * s; w = (rowElement(1, 0) - rowElement(0, 1)) / s; } quaternion = [x, y, z, w]; result = { translate: translate, scale: scale, skew: skew, quaternion: quaternion, perspective: perspective, rotate: rotate }; for (typeKey in result) { type = result[typeKey]; for (k in type) { v = type[k]; if (isNaN(v)) { type[k] = 0; } } } return result; }; interpolateMatrix = function(decomposedA, decomposedB, t, only) { var angle, decomposed, i, invscale, invth, k, qa, qb, scale, th, _i, _j, _k, _l, _len, _ref, _ref1; if (only == null) { only = []; } decomposed = {}; _ref = ['translate', 'scale', 'skew', 'perspective']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { k = _ref[_i]; decomposed[k] = []; for (i = _j = 0, _ref1 = decomposedA[k].length - 1; 0 <= _ref1 ? _j <= _ref1 : _j >= _ref1; i = 0 <= _ref1 ? ++_j : --_j) { if (only.indexOf(k) > -1 || only.indexOf("" + k + ['x', 'y', 'z'][i]) > -1) { decomposed[k][i] = (decomposedB[k][i] - decomposedA[k][i]) * t + decomposedA[k][i]; } else { decomposed[k][i] = decomposedA[k][i]; } } } if (only.indexOf('rotate') !== -1) { qa = decomposedA.quaternion; qb = decomposedB.quaternion; angle = qa[0] * qb[0] + qa[1] * qb[1] + qa[2] * qb[2] + qa[3] * qb[3]; if (angle < 0.0) { for (i = _k = 0; _k <= 3; i = ++_k) { qa[i] = -qa[i]; } angle = -angle; } if (angle + 1.0 > .05) { if (1.0 - angle >= .05) { th = Math.acos(angle); invth = 1.0 / Math.sin(th); scale = Math.sin(th * (1.0 - t)) * invth; invscale = Math.sin(th * t) * invth; } else { scale = 1.0 - t; invscale = t; } } else { qb[0] = -qa[1]; qb[1] = qa[0]; qb[2] = -qa[3]; qb[3] = qa[2]; scale = Math.sin(piDouble * (.5 - t)); invscale = Math.sin(piDouble * t); } decomposed.quaternion = []; for (i = _l = 0; _l <= 3; i = ++_l) { decomposed.quaternion[i] = qa[i] * scale + qb[i] * invscale; } } else { decomposed.quaternion = decomposedA.quaternion; } return decomposed; }; recomposeMatrix = function(decomposedMatrix) { var i, j, match, matrix, quaternion, skew, temp, w, x, y, z, _i, _j, _k, _l; matrix = Matrix.I(4); for (i = _i = 0; _i <= 3; i = ++_i) { matrix.els[i][3] = decomposedMatrix.perspective[i]; } quaternion = decomposedMatrix.quaternion; x = quaternion[0]; y = quaternion[1]; z = quaternion[2]; w = quaternion[3]; skew = decomposedMatrix.skew; match = [[1, 0], [2, 0], [2, 1]]; for (i = _j = 2; _j >= 0; i = --_j) { if (skew[i]) { temp = Matrix.I(4); temp.els[match[i][0]][match[i][1]] = skew[i]; matrix = matrix.multiply(temp); } } matrix = matrix.multiply(new Matrix([[1 - 2 * (y * y + z * z), 2 * (x * y - z * w), 2 * (x * z + y * w), 0], [2 * (x * y + z * w), 1 - 2 * (x * x + z * z), 2 * (y * z - x * w), 0], [2 * (x * z - y * w), 2 * (y * z + x * w), 1 - 2 * (x * x + y * y), 0], [0, 0, 0, 1]])); for (i = _k = 0; _k <= 2; i = ++_k) { for (j = _l = 0; _l <= 2; j = ++_l) { matrix.els[i][j] *= decomposedMatrix.scale[i]; } matrix.els[3][i] = decomposedMatrix.translate[i]; } return matrix; }; matrixToString = function(matrix) { var i, j, str, _i, _j; str = 'matrix3d('; for (i = _i = 0; _i <= 3; i = ++_i) { for (j = _j = 0; _j <= 3; j = ++_j) { str += matrix.els[i][j]; if (!(i === 3 && j === 3)) { str += ','; } } } str += ')'; return str; }; transformStringToMatrixString = cacheFn(function(transform) { var matrixEl, result, style; matrixEl = document.createElement('div'); matrixEl.style[browserSupportTransform()] = transform; document.body.appendChild(matrixEl); style = window.getComputedStyle(matrixEl, null); result = style.transform || style[browserSupportTransform()]; document.body.removeChild(matrixEl); return result; }); convertToMatrix3d = function(transform) { var digits, elements, i, match, matrixElements, _i; match = transform.match(/matrix3?d?\(([-0-9, \.]*)\)/); if (match) { digits = match[1].split(','); digits = digits.map(parseFloat); if (digits.length === 6) { elements = [digits[0], digits[1], 0, 0, digits[2], digits[3], 0, 0, 0, 0, 1, 0, digits[4], digits[5], 0, 1]; } else { elements = digits; } } else { elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; } matrixElements = []; for (i = _i = 0; _i <= 3; i = ++_i) { matrixElements.push(elements.slice(i * 4, i * 4 + 4)); } return new Matrix(matrixElements); }; getFirstFrame = function(properties) { var frame, k, style, v; frame = {}; style = window.getComputedStyle(this.el, null); for (k in properties) { if (transformProperties.contains(k)) { k = 'transform'; } if (!frame[k]) { v = this.el.style[browserSupportWithPrefix(k)]; if (v == null) { v = style[browserSupportWithPrefix(k)]; } frame[k] = v; } } return frame; }; parseFrames = function(frames) { var k, match, newFrames, newProperties, percent, properties, transform, transforms, unit, v, vString, value; newFrames = {}; for (percent in frames) { properties = frames[percent]; transforms = []; newProperties = {}; for (k in properties) { v = properties[k]; if (k === 'transform') { transforms.push(v); } else if (transformProperties.contains(k)) { v = "" + k + "(" + v + (unitFor(k, v)) + ")"; transforms.push(v); } else { vString = v + ""; match = vString.match(/([-0-9.]*)(.*)/); value = parseFloat(match[1]); unit = match[2]; newProperties[k] = { value: value, originalValue: v, unit: unit }; } } if (transforms.length > 0) { transform = transforms.join(' '); newProperties['transform'] = { value: decomposeMatrix(convertToMatrix3d(transformStringToMatrixString(transform))), originalValue: transform, unit: '' }; } newFrames[percent] = newProperties; } return newFrames; }; defaultForProperty = function(property) { if (property === 'opacity') { return 1; } return 0; }; animationFrame = function(ts) { var at, dTs, properties, t, _base; if (this.stopped) { Loop.remove(this); return {}; } t = 0; if (this.ts) { dTs = ts - this.ts; t = dTs / this.options.duration; } else { this.ts = ts; } at = this.dynamic().at(t); properties = propertiesAtFrame.call(this, at[1], { progress: t }); if (t >= 1) { Loop.remove(this); this.animating = false; this.dynamic().init(); if (typeof (_base = this.options).complete === "function") { _base.complete(this); } } return properties; }; propertiesAtFrame = function(t, args) { var dValue, frame0, frame1, k, newValue, oldValue, progress, properties, transform, unit, v, value; if (args == null) { args = {}; } frame0 = this.frames[0]; frame1 = this.frames[100]; progress = args.progress; if (progress == null) { progress = -1; } transform = ''; properties = {}; for (k in frame1) { v = frame1[k]; value = v.value; unit = v.unit; newValue = null; if (progress >= 1) { if (this.returnsToSelf) { newValue = frame0[k].value; } else { newValue = frame1[k].value; } } if (k === 'transform') { if (newValue == null) { newValue = interpolateMatrix(frame0[k].value, frame1[k].value, t, this.keysToInterpolate); } properties['transform'] = recomposeMatrix(newValue); } else { if (!newValue) { oldValue = null; if (frame0[k]) { oldValue = frame0[k].value; } if (!(oldValue != null) || isNaN(oldValue)) { oldValue = defaultForProperty(k); } dValue = value - oldValue; newValue = oldValue + (dValue * t); } properties[k] = newValue; } } return properties; }; animationStart = function() { if (!this.options.animated) { alert('!!! need to do something here'); return; } this.animating = true; this.ts = null; if (this.stopped) { this.stopped = false; } return Loop.add(this); }; keysForTransform = function(transform) { var keys, match, matches, _i, _len; matches = transform.match(/[a-zA-Z0-9]*\([^)]*\)/g); keys = []; if (matches != null) { for (_i = 0, _len = matches.length; _i < _len; _i++) { match = matches[_i]; keys.push(match.substring(0, match.indexOf('('))); } } return keys; }; Animations = []; hasCommonProperties = function(props1, props2) { var k, v; for (k in props1) { v = props1[k]; if (props2[k] != null) { return true; } } return false; }; stopAnimationsForEl = function(el, properties) { var animation, _i, _len, _results; _results = []; for (_i = 0, _len = Animations.length; _i < _len; _i++) { animation = Animations[_i]; if (animation.el === el && hasCommonProperties(animation.to, properties)) { _results.push(animation.stop()); } else { _results.push(void 0); } } return _results; }; Loop = { animations: [], running: false, start: function() { this.running = true; return requestAnimationFrame(this.tick.bind(this)); }, stop: function() { return this.running = false; }, tick: function(ts) { var animation, animations, el, elProperties, found, k, properties, propertiesByEls, v, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; if (!this.running) { return; } animations = this.animations.slice(); propertiesByEls = []; for (_i = 0, _len = animations.length; _i < _len; _i++) { animation = animations[_i]; properties = animationFrame.call(animation, ts); found = false; for (_j = 0, _len1 = propertiesByEls.length; _j < _len1; _j++) { _ref = propertiesByEls[_j], el = _ref[0], elProperties = _ref[1]; if (animation.el === el) { for (k in properties) { v = properties[k]; if (k === 'transform' && elProperties[k]) { v = v.multiply(elProperties[k]); } elProperties[k] = v; } found = true; break; } } if (!found) { propertiesByEls.push([animation.el, properties]); } } for (_k = 0, _len2 = propertiesByEls.length; _k < _len2; _k++) { _ref1 = propertiesByEls[_k], el = _ref1[0], properties = _ref1[1]; if (properties['transform'] != null) { properties['transform'] = matrixToString(properties['transform']); } css(el, properties); } return requestAnimationFrame(this.tick.bind(this)); }, add: function(animation) { if (this.animations.indexOf(animation) === -1) { this.animations.push(animation); } if (!this.running && this.animations.length > 0) { return this.start(); } }, remove: function(animation) { if (this.running && this.animations.length === 0) { return this.stop(); } } }; set = function(array) { var obj, v, _i, _len; obj = {}; for (_i = 0, _len = array.length; _i < _len; _i++) { v = array[_i]; obj[v] = 1; } return { obj: obj, contains: function(v) { return obj[v] != null; } }; }; pxProperties = set(['marginTop', 'marginLeft', 'marginBottom', 'marginRight', 'paddingTop', 'paddingLeft', 'paddingBottom', 'paddingRight', 'top', 'left', 'bottom', 'right', 'translateX', 'translateY', 'translateZ']); degProperties = set(['rotate', 'rotateX', 'rotateY', 'rotateZ', 'skew', 'skewX', 'skewY', 'skewZ']); transformProperties = set(['translateX', 'translateY', 'translateZ', 'scale', 'scaleX', 'scaleY', 'scaleZ', 'rotate', 'rotateX', 'rotateY', 'rotateZ', 'skew', 'skewX', 'skewY', 'skewZ', 'perspective', 'width', 'height', 'maxWidth', 'maxHeight', 'minWidth', 'minHeight']); unitFor = function(k, v) { if (typeof v !== 'number') { return ''; } if (pxProperties.contains(k)) { return 'px'; } else if (degProperties.contains(k)) { return 'deg'; } return ''; }; css = function(el, properties) { var k, transforms, v; transforms = []; for (k in properties) { v = properties[k]; if (k === 'transform') { transforms.push(v); } if (transformProperties.contains(k)) { transforms.push("" + k + "(" + v + (unitFor(k, v)) + ")"); } else { el.style[browserSupportWithPrefix(k)] = "" + v + (unitFor(k, v)); } } if (transforms.length > 0) { return el.style[browserSupportWithPrefix("transform")] = transforms.join(' '); } }; Animation = (function() { function Animation(el, to, options) { var redraw; this.el = el; this.to = to; if (options == null) { options = {}; } this.stop = __bind(this.stop, this); this.start = __bind(this.start, this); this.dynamic = __bind(this.dynamic, this); this.setOptions = __bind(this.setOptions, this); if (window['jQuery'] && this.el instanceof jQuery) { this.el = this.el[0]; } this.animating = false; redraw = this.el.offsetHeight; this.frames = parseFrames({ 0: getFirstFrame.call(this, this.to), 100: this.to }); this.keysToInterpolate = []; if (this.frames[100]['transform'] != null) { this.keysToInterpolate = keysForTransform(this.frames[100]['transform'].originalValue); this.keysToInterpolate = this.keysToInterpolate.map(function(e) { return e.toLowerCase(); }); } this.setOptions(options); if (this.options.debugName && Dynamics.InteractivePanel) { Dynamics.InteractivePanel.addAnimation(this); } Animations.push(this); } Animation.prototype.setOptions = function(options) { var optionsChanged, _base, _base1, _base2, _base3, _ref, _ref1, _ref2, _ref3, _ref4; if (options == null) { options = {}; } optionsChanged = (_ref = this.options) != null ? _ref.optionsChanged : void 0; this.options = options; if ((_ref1 = (_base = this.options).duration) == null) { _base.duration = 1000; } if ((_ref2 = (_base1 = this.options).complete) == null) { _base1.complete = null; } if ((_ref3 = (_base2 = this.options).type) == null) { _base2.type = Linear; } if ((_ref4 = (_base3 = this.options).animated) == null) { _base3.animated = true; } this.returnsToSelf = false || this.dynamic().returnsToSelf; this._dynamic = null; if ((this.options.debugName != null) && (Dynamics.Overrides != null) && Dynamics.Overrides["for"](this.options.debugName)) { this.options = Dynamics.Overrides.getOverride(this.options, this.options.debugName); } this.dynamic().init(); return typeof optionsChanged === "function" ? optionsChanged() : void 0; }; Animation.prototype.dynamic = function() { var _ref; if ((_ref = this._dynamic) == null) { this._dynamic = new this.options.type(this.options); } return this._dynamic; }; Animation.prototype.start = function(options) { var _ref, _ref1; if (options == null) { options = {}; } if ((_ref = options.delay) == null) { options.delay = this.options.delay; } if ((_ref1 = options.delay) == null) { options.delay = 0; } stopAnimationsForEl(this.el, this.to); if (options.delay <= 0) { return animationStart.call(this); } else { return setTimeout(animationStart.bind(this), options.delay); } }; Animation.prototype.stop = function() { this.animating = false; return this.stopped = true; }; return Animation; })(); DynamicElement = (function() { function DynamicElement(el) { this.delay = __bind(this.delay, this); this.start = __bind(this.start, this); this.to = __bind(this.to, this); this.css = __bind(this.css, this); this._el = el; this._delay = 0; this._animations = []; } DynamicElement.prototype.css = function(to) { css(this._el, to); return this; }; DynamicElement.prototype.to = function(to, options) { if (options == null) { options = {}; } options.delay = this._delay; this._animations.push(new Dynamics.Animation(this._el, to, options)); return this; }; DynamicElement.prototype.start = function() { var animation, _i, _len, _ref; _ref = this._animations; for (_i = 0, _len = _ref.length; _i < _len; _i++) { animation = _ref[_i]; animation.start(); } this._animations = []; this._delay = 0; return this; }; DynamicElement.prototype.delay = function(delay) { this._delay += delay; return this; }; return DynamicElement; })(); this.dynamic = function(el) { return new DynamicElement(el); }; Dynamics = { Animation: Animation, Types: { Spring: Spring, SelfSpring: SelfSpring, Gravity: Gravity, GravityWithForce: GravityWithForce, Linear: Linear, Bezier: Bezier, EaseInOut: EaseInOut }, css: css }; try { if (module) { module.exports = Dynamics; } else { this.Dynamics = Dynamics; } } catch (e) { this.Dynamics = Dynamics; } }).call(this);