123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- import {
- degToRads,
- } from './common';
- import {
- extendPrototype,
- } from './functionExtensions';
- import DynamicPropertyContainer from './helpers/dynamicProperties';
- import Matrix from '../3rd_party/transformation-matrix';
- import PropertyFactory from './PropertyFactory';
- const 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) {
- var frameRate;
- 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;
- var 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;
- var py = this.py;
- 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 {
- v2 = defaultVector;
- v1 = v2;
- }
- 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() {
- this.appliedTransformations = 0;
- this.pre.reset();
- if (!this.a.effectsSequence.length) {
- 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 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;
- var len = data.or.k.length;
- for (i = 0; i < len; i += 1) {
- data.or.k[i].to = null;
- 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,
- };
- }());
- export default TransformPropertyFactory;
|