| var ShapePropertyFactory = (function () { |
| |
| var initFrame = -999999; |
| |
| function interpolateShape(frameNum, previousValue, caching) { |
| var iterationIndex = caching.lastIndex; |
| var keyPropS, keyPropE, isHold, j, k, jLen, kLen, perc, vertexValue; |
| var kf = this.keyframes; |
| if(frameNum < kf[0].t-this.offsetTime) { |
| keyPropS = kf[0].s[0]; |
| isHold = true; |
| iterationIndex = 0; |
| }else if(frameNum >= kf[kf.length - 1].t-this.offsetTime) { |
| keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0]; |
| /* if(kf[kf.length - 1].s){ |
| keyPropS = kf[kf.length - 1].s[0]; |
| }else{ |
| keyPropS = kf[kf.length - 2].e[0]; |
| } */ |
| isHold = true; |
| }else{ |
| var i = iterationIndex; |
| var len = kf.length- 1, flag = true, keyData, nextKeyData; |
| while(flag) { |
| keyData = kf[i]; |
| nextKeyData = kf[i+1]; |
| if((nextKeyData.t - this.offsetTime) > frameNum) { |
| break; |
| } |
| if(i < len - 1) { |
| i += 1; |
| }else{ |
| flag = false; |
| } |
| } |
| isHold = keyData.h === 1; |
| iterationIndex = i; |
| if(!isHold) { |
| if(frameNum >= nextKeyData.t-this.offsetTime) { |
| perc = 1; |
| }else if(frameNum < keyData.t-this.offsetTime) { |
| perc = 0; |
| }else{ |
| var fnc; |
| if(keyData.__fnct) { |
| fnc = keyData.__fnct; |
| }else{ |
| fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get; |
| keyData.__fnct = fnc; |
| } |
| perc = fnc((frameNum-(keyData.t-this.offsetTime))/((nextKeyData.t-this.offsetTime)-(keyData.t-this.offsetTime))); |
| } |
| keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0]; |
| } |
| keyPropS = keyData.s[0]; |
| } |
| jLen = previousValue._length; |
| kLen = keyPropS.i[0].length; |
| caching.lastIndex = iterationIndex; |
| |
| for(j=0;j<jLen;j+=1) { |
| for(k=0;k<kLen;k+=1) { |
| vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k]+(keyPropE.i[j][k]-keyPropS.i[j][k])*perc; |
| previousValue.i[j][k] = vertexValue; |
| vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k]+(keyPropE.o[j][k]-keyPropS.o[j][k])*perc; |
| previousValue.o[j][k] = vertexValue; |
| vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k]+(keyPropE.v[j][k]-keyPropS.v[j][k])*perc; |
| previousValue.v[j][k] = vertexValue; |
| } |
| } |
| } |
| |
| function interpolateShapeCurrentTime() { |
| var frameNum = this.comp.renderedFrame - this.offsetTime; |
| var initTime = this.keyframes[0].t - this.offsetTime; |
| var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime; |
| var lastFrame = this._caching.lastFrame; |
| if(!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) { |
| /// / |
| this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0; |
| this.interpolateShape(frameNum, this.pv, this._caching); |
| /// / |
| } |
| this._caching.lastFrame = frameNum; |
| return this.pv; |
| } |
| |
| function resetShape() { |
| this.paths = this.localShapeCollection; |
| } |
| |
| function shapesEqual(shape1, shape2) { |
| if(shape1._length !== shape2._length || shape1.c !== shape2.c) { |
| return false; |
| } |
| var i, len = shape1._length; |
| for(i = 0; i < len; i += 1) { |
| if(shape1.v[i][0] !== shape2.v[i][0] |
| || shape1.v[i][1] !== shape2.v[i][1] |
| || shape1.o[i][0] !== shape2.o[i][0] |
| || shape1.o[i][1] !== shape2.o[i][1] |
| || shape1.i[i][0] !== shape2.i[i][0] |
| || shape1.i[i][1] !== shape2.i[i][1]) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| function setVValue(newPath) { |
| if(!shapesEqual(this.v, newPath)) { |
| this.v = shape_pool.clone(newPath); |
| this.localShapeCollection.releaseShapes(); |
| this.localShapeCollection.addShape(this.v); |
| this._mdf = true; |
| this.paths = this.localShapeCollection; |
| } |
| } |
| |
| function processEffectsSequence() { |
| if (this.elem.globalData.frameId === this.frameId) { |
| return; |
| } else if (!this.effectsSequence.length) { |
| this._mdf = false; |
| return; |
| } |
| if (this.lock) { |
| this.setVValue(this.pv); |
| return; |
| } |
| this.lock = true; |
| this._mdf = false; |
| var finalValue = this.kf ? this.pv : this.data.ks ? this.data.ks.k : this.data.pt.k; |
| var i, len = this.effectsSequence.length; |
| for(i = 0; i < len; i += 1) { |
| finalValue = this.effectsSequence[i](finalValue); |
| } |
| this.setVValue(finalValue); |
| this.lock = false; |
| this.frameId = this.elem.globalData.frameId; |
| }; |
| |
| function ShapeProperty(elem, data, type) { |
| this.propType = 'shape'; |
| this.comp = elem.comp; |
| this.container = elem; |
| this.elem = elem; |
| this.data = data; |
| this.k = false; |
| this.kf = false; |
| this._mdf = false; |
| var pathData = type === 3 ? data.pt.k : data.ks.k; |
| this.v = shape_pool.clone(pathData); |
| this.pv = shape_pool.clone(this.v); |
| this.localShapeCollection = shapeCollection_pool.newShapeCollection(); |
| this.paths = this.localShapeCollection; |
| this.paths.addShape(this.v); |
| this.reset = resetShape; |
| this.effectsSequence = []; |
| } |
| |
| function addEffect(effectFunction) { |
| this.effectsSequence.push(effectFunction); |
| this.container.addDynamicProperty(this); |
| } |
| |
| ShapeProperty.prototype.interpolateShape = interpolateShape; |
| ShapeProperty.prototype.getValue = processEffectsSequence; |
| ShapeProperty.prototype.setVValue = setVValue; |
| ShapeProperty.prototype.addEffect = addEffect; |
| |
| function KeyframedShapeProperty(elem, data, type) { |
| this.propType = 'shape'; |
| this.comp = elem.comp; |
| this.elem = elem; |
| this.container = elem; |
| this.offsetTime = elem.data.st; |
| this.keyframes = type === 3 ? data.pt.k : data.ks.k; |
| this.k = true; |
| this.kf = true; |
| var i, len = this.keyframes[0].s[0].i.length; |
| var jLen = this.keyframes[0].s[0].i[0].length; |
| this.v = shape_pool.newElement(); |
| this.v.setPathData(this.keyframes[0].s[0].c, len); |
| this.pv = shape_pool.clone(this.v); |
| this.localShapeCollection = shapeCollection_pool.newShapeCollection(); |
| this.paths = this.localShapeCollection; |
| this.paths.addShape(this.v); |
| this.lastFrame = initFrame; |
| this.reset = resetShape; |
| this._caching = {lastFrame: initFrame, lastIndex: 0}; |
| this.effectsSequence = [interpolateShapeCurrentTime.bind(this)]; |
| } |
| KeyframedShapeProperty.prototype.getValue = processEffectsSequence; |
| KeyframedShapeProperty.prototype.interpolateShape = interpolateShape; |
| KeyframedShapeProperty.prototype.setVValue = setVValue; |
| KeyframedShapeProperty.prototype.addEffect = addEffect; |
| |
| var EllShapeProperty = (function () { |
| |
| var cPoint = roundCorner; |
| |
| function EllShapeProperty(elem, data) { |
| /* this.v = { |
| v: createSizedArray(4), |
| i: createSizedArray(4), |
| o: createSizedArray(4), |
| c: true |
| }; */ |
| this.v = shape_pool.newElement(); |
| this.v.setPathData(true, 4); |
| this.localShapeCollection = shapeCollection_pool.newShapeCollection(); |
| this.paths = this.localShapeCollection; |
| this.localShapeCollection.addShape(this.v); |
| this.d = data.d; |
| this.elem = elem; |
| this.comp = elem.comp; |
| this.frameId = -1; |
| this.initDynamicPropertyContainer(elem); |
| this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this); |
| this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this); |
| if(this.dynamicProperties.length) { |
| this.k = true; |
| }else{ |
| this.k = false; |
| this.convertEllToPath(); |
| } |
| }; |
| |
| EllShapeProperty.prototype = { |
| reset: resetShape, |
| getValue: function () { |
| if(this.elem.globalData.frameId === this.frameId) { |
| return; |
| } |
| this.frameId = this.elem.globalData.frameId; |
| this.iterateDynamicProperties(); |
| |
| if(this._mdf) { |
| this.convertEllToPath(); |
| } |
| }, |
| convertEllToPath: function () { |
| var p0 = this.p.v[0], p1 = this.p.v[1], s0 = this.s.v[0]/2, s1 = this.s.v[1]/2; |
| var _cw = this.d !== 3; |
| var _v = this.v; |
| _v.v[0][0] = p0; |
| _v.v[0][1] = p1 - s1; |
| _v.v[1][0] = _cw ? p0 + s0 : p0 - s0; |
| _v.v[1][1] = p1; |
| _v.v[2][0] = p0; |
| _v.v[2][1] = p1 + s1; |
| _v.v[3][0] = _cw ? p0 - s0 : p0 + s0; |
| _v.v[3][1] = p1; |
| _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint; |
| _v.i[0][1] = p1 - s1; |
| _v.i[1][0] = _cw ? p0 + s0 : p0 - s0; |
| _v.i[1][1] = p1 - s1 * cPoint; |
| _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint; |
| _v.i[2][1] = p1 + s1; |
| _v.i[3][0] = _cw ? p0 - s0 : p0 + s0; |
| _v.i[3][1] = p1 + s1 * cPoint; |
| _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint; |
| _v.o[0][1] = p1 - s1; |
| _v.o[1][0] = _cw ? p0 + s0 : p0 - s0; |
| _v.o[1][1] = p1 + s1 * cPoint; |
| _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint; |
| _v.o[2][1] = p1 + s1; |
| _v.o[3][0] = _cw ? p0 - s0 : p0 + s0; |
| _v.o[3][1] = p1 - s1 * cPoint; |
| } |
| } |
| |
| extendPrototype([DynamicPropertyContainer], EllShapeProperty); |
| |
| return EllShapeProperty; |
| }()); |
| |
| var StarShapeProperty = (function () { |
| |
| function StarShapeProperty(elem, data) { |
| this.v = shape_pool.newElement(); |
| this.v.setPathData(true, 0); |
| this.elem = elem; |
| this.comp = elem.comp; |
| this.data = data; |
| this.frameId = -1; |
| this.d = data.d; |
| this.initDynamicPropertyContainer(elem); |
| if(data.sy === 1) { |
| this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this); |
| this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this); |
| this.convertToPath = this.convertStarToPath; |
| } else { |
| this.convertToPath = this.convertPolygonToPath; |
| } |
| this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this); |
| this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this); |
| this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this); |
| this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this); |
| this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this); |
| this.localShapeCollection = shapeCollection_pool.newShapeCollection(); |
| this.localShapeCollection.addShape(this.v); |
| this.paths = this.localShapeCollection; |
| if(this.dynamicProperties.length) { |
| this.k = true; |
| }else{ |
| this.k = false; |
| this.convertToPath(); |
| } |
| }; |
| |
| StarShapeProperty.prototype = { |
| reset: resetShape, |
| getValue: function () { |
| if(this.elem.globalData.frameId === this.frameId) { |
| return; |
| } |
| this.frameId = this.elem.globalData.frameId; |
| this.iterateDynamicProperties(); |
| if(this._mdf) { |
| this.convertToPath(); |
| } |
| }, |
| convertStarToPath: function () { |
| var numPts = Math.floor(this.pt.v)*2; |
| var angle = Math.PI*2/numPts; |
| /* this.v.v.length = numPts; |
| this.v.i.length = numPts; |
| this.v.o.length = numPts; */ |
| var longFlag = true; |
| var longRad = this.or.v; |
| var shortRad = this.ir.v; |
| var longRound = this.os.v; |
| var shortRound = this.is.v; |
| var longPerimSegment = 2*Math.PI*longRad/(numPts*2); |
| var shortPerimSegment = 2*Math.PI*shortRad/(numPts*2); |
| var i, rad, roundness, perimSegment, currentAng = -Math.PI/ 2; |
| currentAng += this.r.v; |
| var dir = this.data.d === 3 ? -1 : 1; |
| this.v._length = 0; |
| for(i=0;i<numPts;i+=1) { |
| rad = longFlag ? longRad : shortRad; |
| roundness = longFlag ? longRound : shortRound; |
| perimSegment = longFlag ? longPerimSegment : shortPerimSegment; |
| var x = rad * Math.cos(currentAng); |
| var y = rad * Math.sin(currentAng); |
| var ox = x === 0 && y === 0 ? 0 : y/Math.sqrt(x*x + y*y); |
| var oy = x === 0 && y === 0 ? 0 : -x/Math.sqrt(x*x + y*y); |
| x += + this.p.v[0]; |
| y += + this.p.v[1]; |
| this.v.setTripleAt(x, y, x-ox*perimSegment*roundness*dir, y-oy*perimSegment*roundness*dir, x+ox*perimSegment*roundness*dir, y+oy*perimSegment*roundness*dir, i, true); |
| |
| /* this.v.v[i] = [x,y]; |
| this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir]; |
| this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir]; |
| this.v._length = numPts; */ |
| longFlag = !longFlag; |
| currentAng += angle*dir; |
| } |
| }, |
| convertPolygonToPath: function () { |
| var numPts = Math.floor(this.pt.v); |
| var angle = Math.PI*2/numPts; |
| var rad = this.or.v; |
| var roundness = this.os.v; |
| var perimSegment = 2*Math.PI*rad/(numPts*4); |
| var i, currentAng = -Math.PI/ 2; |
| var dir = this.data.d === 3 ? -1 : 1; |
| currentAng += this.r.v; |
| this.v._length = 0; |
| for(i=0;i<numPts;i+=1) { |
| var x = rad * Math.cos(currentAng); |
| var y = rad * Math.sin(currentAng); |
| var ox = x === 0 && y === 0 ? 0 : y/Math.sqrt(x*x + y*y); |
| var oy = x === 0 && y === 0 ? 0 : -x/Math.sqrt(x*x + y*y); |
| x += + this.p.v[0]; |
| y += + this.p.v[1]; |
| this.v.setTripleAt(x, y, x-ox*perimSegment*roundness*dir, y-oy*perimSegment*roundness*dir, x+ox*perimSegment*roundness*dir, y+oy*perimSegment*roundness*dir, i, true); |
| currentAng += angle*dir; |
| } |
| this.paths.length = 0; |
| this.paths[0] = this.v; |
| } |
| |
| } |
| extendPrototype([DynamicPropertyContainer], StarShapeProperty); |
| |
| return StarShapeProperty; |
| }()); |
| |
| var RectShapeProperty = (function () { |
| |
| function RectShapeProperty(elem, data) { |
| this.v = shape_pool.newElement(); |
| this.v.c = true; |
| this.localShapeCollection = shapeCollection_pool.newShapeCollection(); |
| this.localShapeCollection.addShape(this.v); |
| this.paths = this.localShapeCollection; |
| this.elem = elem; |
| this.comp = elem.comp; |
| this.frameId = -1; |
| this.d = data.d; |
| this.initDynamicPropertyContainer(elem); |
| this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this); |
| this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this); |
| this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this); |
| if(this.dynamicProperties.length) { |
| this.k = true; |
| }else{ |
| this.k = false; |
| this.convertRectToPath(); |
| } |
| }; |
| |
| RectShapeProperty.prototype = { |
| convertRectToPath: function () { |
| var p0 = this.p.v[0], p1 = this.p.v[1], v0 = this.s.v[0]/2, v1 = this.s.v[1]/2; |
| var round = bm_min(v0, v1, this.r.v); |
| var cPoint = round*(1-roundCorner); |
| this.v._length = 0; |
| |
| if(this.d === 2 || this.d === 1) { |
| this.v.setTripleAt(p0+v0, p1-v1+round, p0+v0, p1-v1+round, p0+v0, p1-v1+cPoint, 0, true); |
| this.v.setTripleAt(p0+v0, p1+v1-round, p0+v0, p1+v1-cPoint, p0+v0, p1+v1-round, 1, true); |
| if(round!== 0) { |
| this.v.setTripleAt(p0+v0-round, p1+v1, p0+v0-round, p1+v1, p0+v0-cPoint, p1+v1, 2, true); |
| this.v.setTripleAt(p0-v0+round, p1+v1, p0-v0+cPoint, p1+v1, p0-v0+round, p1+v1, 3, true); |
| this.v.setTripleAt(p0-v0, p1+v1-round, p0-v0, p1+v1-round, p0-v0, p1+v1-cPoint, 4, true); |
| this.v.setTripleAt(p0-v0, p1-v1+round, p0-v0, p1-v1+cPoint, p0-v0, p1-v1+round, 5, true); |
| this.v.setTripleAt(p0-v0+round, p1-v1, p0-v0+round, p1-v1, p0-v0+cPoint, p1-v1, 6, true); |
| this.v.setTripleAt(p0+v0-round, p1-v1, p0+v0-cPoint, p1-v1, p0+v0-round, p1-v1, 7, true); |
| } else { |
| this.v.setTripleAt(p0-v0, p1+v1, p0-v0+cPoint, p1+v1, p0-v0, p1+v1, 2); |
| this.v.setTripleAt(p0-v0, p1-v1, p0-v0, p1-v1+cPoint, p0-v0, p1-v1, 3); |
| } |
| }else{ |
| this.v.setTripleAt(p0+v0, p1-v1+round, p0+v0, p1-v1+cPoint, p0+v0, p1-v1+round, 0, true); |
| if(round!== 0) { |
| this.v.setTripleAt(p0+v0-round, p1-v1, p0+v0-round, p1-v1, p0+v0-cPoint, p1-v1, 1, true); |
| this.v.setTripleAt(p0-v0+round, p1-v1, p0-v0+cPoint, p1-v1, p0-v0+round, p1-v1, 2, true); |
| this.v.setTripleAt(p0-v0, p1-v1+round, p0-v0, p1-v1+round, p0-v0, p1-v1+cPoint, 3, true); |
| this.v.setTripleAt(p0-v0, p1+v1-round, p0-v0, p1+v1-cPoint, p0-v0, p1+v1-round, 4, true); |
| this.v.setTripleAt(p0-v0+round, p1+v1, p0-v0+round, p1+v1, p0-v0+cPoint, p1+v1, 5, true); |
| this.v.setTripleAt(p0+v0-round, p1+v1, p0+v0-cPoint, p1+v1, p0+v0-round, p1+v1, 6, true); |
| this.v.setTripleAt(p0+v0, p1+v1-round, p0+v0, p1+v1-round, p0+v0, p1+v1-cPoint, 7, true); |
| } else { |
| this.v.setTripleAt(p0-v0, p1-v1, p0-v0+cPoint, p1-v1, p0-v0, p1-v1, 1, true); |
| this.v.setTripleAt(p0-v0, p1+v1, p0-v0, p1+v1-cPoint, p0-v0, p1+v1, 2, true); |
| this.v.setTripleAt(p0+v0, p1+v1, p0+v0-cPoint, p1+v1, p0+v0, p1+v1, 3, true); |
| |
| } |
| } |
| }, |
| getValue: function (frameNum) { |
| if(this.elem.globalData.frameId === this.frameId) { |
| return; |
| } |
| this.frameId = this.elem.globalData.frameId; |
| this.iterateDynamicProperties(); |
| if(this._mdf) { |
| this.convertRectToPath(); |
| } |
| |
| }, |
| reset: resetShape |
| } |
| extendPrototype([DynamicPropertyContainer], RectShapeProperty); |
| |
| return RectShapeProperty; |
| }()); |
| |
| function getShapeProp(elem, data, type) { |
| var prop; |
| if(type === 3 || type === 4) { |
| var dataProp = type === 3 ? data.pt : data.ks; |
| var keys = dataProp.k; |
| if(keys.length) { |
| prop = new KeyframedShapeProperty(elem, data, type); |
| }else{ |
| prop = new ShapeProperty(elem, data, type); |
| } |
| }else if(type === 5) { |
| prop = new RectShapeProperty(elem, data); |
| }else if(type === 6) { |
| prop = new EllShapeProperty(elem, data); |
| }else if(type === 7) { |
| prop = new StarShapeProperty(elem, data); |
| } |
| if(prop.k) { |
| elem.addDynamicProperty(prop); |
| } |
| return prop; |
| } |
| |
| function getConstructorFunction() { |
| return ShapeProperty; |
| } |
| |
| function getKeyframedConstructorFunction() { |
| return KeyframedShapeProperty; |
| } |
| |
| var ob = {}; |
| ob.getShapeProp = getShapeProp; |
| ob.getConstructorFunction = getConstructorFunction; |
| ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction; |
| return ob; |
| }()); |