| 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){ |
| if(kf[kf.length - 2].h === 1){ |
| 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 = 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 || !this.effectsSequence.length) { |
| 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(dataProp.a === 1 || 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; |
| }()); |