| var TransformPropertyFactory = (function () { |
| |
| var defaultVector = [0, 0]; |
| |
| function applyToMatrix(mat) { |
| var _mdf = this._mdf; |
| this.iterateDynamicProperties(); |
| this._mdf = this._mdf || _mdf; |
| if (this.a) { |
| mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]); |
| } |
| if (this.s) { |
| mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]); |
| } |
| if (this.sk) { |
| mat.skewFromAxis(-this.sk.v, this.sa.v); |
| } |
| if (this.r) { |
| mat.rotate(-this.r.v); |
| } else { |
| mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]); |
| } |
| if (this.data.p.s) { |
| if (this.data.p.z) { |
| mat.translate(this.px.v, this.py.v, -this.pz.v); |
| } else { |
| mat.translate(this.px.v, this.py.v, 0); |
| } |
| } else { |
| mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]); |
| } |
| } |
| function processKeys(forceRender) { |
| if (this.elem.globalData.frameId === this.frameId) { |
| return; |
| } |
| if (this._isDirty) { |
| this.precalculateMatrix(); |
| this._isDirty = false; |
| } |
| |
| this.iterateDynamicProperties(); |
| |
| if (this._mdf || forceRender) { |
| this.v.cloneFromProps(this.pre.props); |
| if (this.appliedTransformations < 1) { |
| this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]); |
| } |
| if (this.appliedTransformations < 2) { |
| this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]); |
| } |
| if (this.sk && this.appliedTransformations < 3) { |
| this.v.skewFromAxis(-this.sk.v, this.sa.v); |
| } |
| if (this.r && this.appliedTransformations < 4) { |
| this.v.rotate(-this.r.v); |
| } else if (!this.r && this.appliedTransformations < 4) { |
| this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]); |
| } |
| if (this.autoOriented) { |
| var v1, v2, frameRate = this.elem.globalData.frameRate; |
| if (this.p && this.p.keyframes && this.p.getValueAtTime) { |
| if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) { |
| v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0); |
| v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0); |
| } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) { |
| v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0); |
| v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0); |
| } else { |
| v1 = this.p.pv; |
| v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime); |
| } |
| } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) { |
| v1 = []; |
| v2 = []; |
| var px = this.px, py = this.py, frameRate; |
| if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) { |
| v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0); |
| v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0); |
| v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate, 0); |
| v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate, 0); |
| } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) { |
| v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate), 0); |
| v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate), 0); |
| v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0); |
| v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0); |
| } else { |
| v1 = [px.pv, py.pv]; |
| v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime); |
| v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime); |
| } |
| } else { |
| v1 = v2 = defaultVector; |
| } |
| this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0])); |
| } |
| if (this.data.p && this.data.p.s) { |
| if (this.data.p.z) { |
| this.v.translate(this.px.v, this.py.v, -this.pz.v); |
| } else { |
| this.v.translate(this.px.v, this.py.v, 0); |
| } |
| } else { |
| this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]); |
| } |
| } |
| this.frameId = this.elem.globalData.frameId; |
| } |
| |
| function precalculateMatrix() { |
| if (!this.a.k) { |
| this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]); |
| this.appliedTransformations = 1; |
| } else { |
| return; |
| } |
| if (!this.s.effectsSequence.length) { |
| this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]); |
| this.appliedTransformations = 2; |
| } else { |
| return; |
| } |
| if (this.sk) { |
| if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) { |
| this.pre.skewFromAxis(-this.sk.v, this.sa.v); |
| this.appliedTransformations = 3; |
| } else { |
| return; |
| } |
| } |
| if (this.r) { |
| if (!this.r.effectsSequence.length) { |
| this.pre.rotate(-this.r.v); |
| this.appliedTransformations = 4; |
| } else { |
| return; |
| } |
| } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) { |
| this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]); |
| this.appliedTransformations = 4; |
| } |
| } |
| |
| function autoOrient() { |
| // |
| // var prevP = this.getValueAtTime(); |
| } |
| |
| function addDynamicProperty(prop) { |
| this._addDynamicProperty(prop); |
| this.elem.addDynamicProperty(prop); |
| this._isDirty = true; |
| } |
| |
| function TransformProperty(elem, data, container) { |
| this.elem = elem; |
| this.frameId = -1; |
| this.propType = 'transform'; |
| this.data = data; |
| this.v = new Matrix(); |
| // Precalculated matrix with non animated properties |
| this.pre = new Matrix(); |
| this.appliedTransformations = 0; |
| this.initDynamicPropertyContainer(container || elem); |
| if (data.p && data.p.s) { |
| this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this); |
| this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this); |
| if (data.p.z) { |
| this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this); |
| } |
| } else { |
| this.p = PropertyFactory.getProp(elem, data.p || { k: [0, 0, 0] }, 1, 0, this); |
| } |
| if (data.rx) { |
| this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this); |
| this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this); |
| this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this); |
| if (data.or.k[0].ti) { |
| var i, len = data.or.k.length; |
| for (i = 0; i < len; i += 1) { |
| data.or.k[i].to = data.or.k[i].ti = null; |
| } |
| } |
| this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this); |
| // sh Indicates it needs to be capped between -180 and 180 |
| this.or.sh = true; |
| } else { |
| this.r = PropertyFactory.getProp(elem, data.r || { k: 0 }, 0, degToRads, this); |
| } |
| if (data.sk) { |
| this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this); |
| this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this); |
| } |
| this.a = PropertyFactory.getProp(elem, data.a || { k: [0, 0, 0] }, 1, 0, this); |
| this.s = PropertyFactory.getProp(elem, data.s || { k: [100, 100, 100] }, 1, 0.01, this); |
| // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes. |
| if (data.o) { |
| this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem); |
| } else { |
| this.o = { _mdf: false, v: 1 }; |
| } |
| this._isDirty = true; |
| if (!this.dynamicProperties.length) { |
| this.getValue(true); |
| } |
| } |
| |
| TransformProperty.prototype = { |
| applyToMatrix: applyToMatrix, |
| getValue: processKeys, |
| precalculateMatrix: precalculateMatrix, |
| autoOrient: autoOrient, |
| }; |
| |
| extendPrototype([DynamicPropertyContainer], TransformProperty); |
| TransformProperty.prototype.addDynamicProperty = addDynamicProperty; |
| TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty; |
| |
| function getTransformProperty(elem, data, container) { |
| return new TransformProperty(elem, data, container); |
| } |
| |
| return { |
| getTransformProperty: getTransformProperty, |
| }; |
| |
| }()); |