Files
ionic-framework/test/html/dynamics.js
2014-05-12 13:07:58 -05:00

1668 lines
44 KiB
JavaScript

// 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);