(function (root, factory) { if(typeof define === "function" && define.amd) { define( factory); } else if(typeof module === "object" && module.exports) { module.exports = factory(); } else { root.bodymovin = factory(); } }(window, function() {var svgNS = "http://www.w3.org/2000/svg"; var subframeEnabled = true; var expressionsPlugin; var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); var cachedColors = {}; var bm_rounder = Math.round; var bm_rnd; var bm_pow = Math.pow; var bm_sqrt = Math.sqrt; var bm_abs = Math.abs; var bm_floor = Math.floor; var bm_max = Math.max; var bm_min = Math.min; var blitter = 10; var BMMath = {}; (function(){ var propertyNames = Object.getOwnPropertyNames(Math); var i, len = propertyNames.length; for(i=0;i 0; --i) result += chars[Math.round(Math.random() * (chars.length - 1))]; return result; } function HSVtoRGB(h, s, v) { var r, g, b, i, f, p, q, t; if (arguments.length === 1) { s = h.s, v = h.v, h = h.h; } i = Math.floor(h * 6); f = h * 6 - i; p = v * (1 - s); q = v * (1 - f * s); t = v * (1 - (1 - f) * s); switch (i % 6) { case 0: r = v, g = t, b = p; break; case 1: r = q, g = v, b = p; break; case 2: r = p, g = v, b = t; break; case 3: r = p, g = q, b = v; break; case 4: r = t, g = p, b = v; break; case 5: r = v, g = p, b = q; break; } return [ r, g, b ]; } function RGBtoHSV(r, g, b) { if (arguments.length === 1) { g = r.g, b = r.b, r = r.r; } var max = Math.max(r, g, b), min = Math.min(r, g, b), d = max - min, h, s = (max === 0 ? 0 : d / max), v = max / 255; switch (max) { case min: h = 0; break; case r: h = (g - b) + d * (g < b ? 6: 0); h /= 6 * d; break; case g: h = (b - r) + d * 2; h /= 6 * d; break; case b: h = (r - g) + d * 4; h /= 6 * d; break; } return [ h, s, v ]; } function addSaturationToRGB(color,offset){ var hsv = RGBtoHSV(color[0]*255,color[1]*255,color[2]*255); hsv[1] += offset; if (hsv[1] > 1) { hsv[1] = 1; } else if (hsv[1] <= 0) { hsv[1] = 0; } return HSVtoRGB(hsv[0],hsv[1],hsv[2]); } function addBrightnessToRGB(color,offset){ var hsv = RGBtoHSV(color[0]*255,color[1]*255,color[2]*255); hsv[2] += offset; if (hsv[2] > 1) { hsv[2] = 1; } else if (hsv[2] < 0) { hsv[2] = 0; } return HSVtoRGB(hsv[0],hsv[1],hsv[2]); } function addHueToRGB(color,offset) { var hsv = RGBtoHSV(color[0]*255,color[1]*255,color[2]*255); hsv[0] += offset/360; if (hsv[0] > 1) { hsv[0] -= 1; } else if (hsv[0] < 0) { hsv[0] += 1; } return HSVtoRGB(hsv[0],hsv[1],hsv[2]); } function componentToHex(c) { var hex = c.toString(16); return hex.length == 1 ? '0' + hex : hex; } var rgbToHex = (function(){ var colorMap = []; var i; var hex; for(i=0;i<256;i+=1){ hex = i.toString(16); colorMap[i] = hex.length == 1 ? '0' + hex : hex; } return function(r, g, b) { if(r<0){ r = 0; } if(g<0){ g = 0; } if(b<0){ b = 0; } return '#' + colorMap[r] + colorMap[g] + colorMap[b]; }; }()); function fillToRgba(hex,alpha){ if(!cachedColors[hex]){ var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); cachedColors[hex] = parseInt(result[1], 16)+','+parseInt(result[2], 16)+','+parseInt(result[3], 16); } return 'rgba('+cachedColors[hex]+','+alpha+')'; } var fillColorToString = (function(){ var colorMap = []; return function(colorArr,alpha){ if(alpha !== undefined){ colorArr[3] = alpha; } if(!colorMap[colorArr[0]]){ colorMap[colorArr[0]] = {}; } if(!colorMap[colorArr[0]][colorArr[1]]){ colorMap[colorArr[0]][colorArr[1]] = {}; } if(!colorMap[colorArr[0]][colorArr[1]][colorArr[2]]){ colorMap[colorArr[0]][colorArr[1]][colorArr[2]] = {}; } if(!colorMap[colorArr[0]][colorArr[1]][colorArr[2]][colorArr[3]]){ colorMap[colorArr[0]][colorArr[1]][colorArr[2]][colorArr[3]] = 'rgba(' + colorArr.join(',')+')'; } return colorMap[colorArr[0]][colorArr[1]][colorArr[2]][colorArr[3]]; }; }()); function RenderedFrame(tr,o) { this.tr = tr; this.o = o; } function LetterProps(o,sw,sc,fc,m,p){ this.o = o; this.sw = sw; this.sc = sc; this.fc = fc; this.m = m; this.props = p; } function iterateDynamicProperties(num){ var i, len = this.dynamicProperties; for(i=0;i= overflow) { // To avoid rounding up, before adding n /= 2; // last byte, shift everything d /= 2; // right using integer math until x >>>= 1; // we have exactly the desired bits. } return (n + x) / d; // Form the number within [0, 1). }; prng.int32 = function() { return arc4.g(4) | 0; } prng.quick = function() { return arc4.g(4) / 0x100000000; } prng.double = prng; // Mix the randomness into accumulated entropy. mixkey(tostring(arc4.S), pool); // Calling convention: what to return as a function of prng, seed, is_math. return (options.pass || callback || function(prng, seed, is_math_call, state) { if (state) { // Load the arc4 state from the given state if it has an S array. if (state.S) { copy(state, arc4); } // Only provide the .state method if requested via options.state. prng.state = function() { return copy(arc4, {}); } } // If called as a method of Math (Math.seedrandom()), mutate // Math.random because that is how seedrandom.js has worked since v1.0. if (is_math_call) { math[rngname] = prng; return seed; } // Otherwise, it is a newer calling convention, so return the // prng directly. else return prng; })( prng, shortseed, 'global' in options ? options.global : (this == math), options.state); } math['seed' + rngname] = seedrandom; // // ARC4 // // An ARC4 implementation. The constructor takes a key in the form of // an array of at most (width) integers that should be 0 <= x < (width). // // The g(count) method returns a pseudorandom integer that concatenates // the next (count) outputs from ARC4. Its return value is a number x // that is in the range 0 <= x < (width ^ count). // function ARC4(key) { var t, keylen = key.length, me = this, i = 0, j = me.i = me.j = 0, s = me.S = []; // The empty key [] is treated as [0]. if (!keylen) { key = [keylen++]; } // Set up S using the standard key scheduling algorithm. while (i < width) { s[i] = i++; } for (i = 0; i < width; i++) { s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))]; s[j] = t; } // The "g" method returns the next (count) outputs as one number. (me.g = function(count) { // Using instance members instead of closure state nearly doubles speed. var t, r = 0, i = me.i, j = me.j, s = me.S; while (count--) { t = s[i = mask & (i + 1)]; r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))]; } me.i = i; me.j = j; return r; // For robust unpredictability, the function call below automatically // discards an initial batch of values. This is called RC4-drop[256]. // See http://google.com/search?q=rsa+fluhrer+response&btnI })(width); } // // copy() // Copies internal state of ARC4 to or from a plain object. // function copy(f, t) { t.i = f.i; t.j = f.j; t.S = f.S.slice(); return t; }; // // flatten() // Converts an object tree to nested arrays of strings. // function flatten(obj, depth) { var result = [], typ = (typeof obj), prop; if (depth && typ == 'object') { for (prop in obj) { try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {} } } return (result.length ? result : typ == 'string' ? obj : obj + '\0'); } // // mixkey() // Mixes a string seed into a key that is an array of integers, and // returns a shortened string seed that is equivalent to the result key. // function mixkey(seed, key) { var stringseed = seed + '', smear, j = 0; while (j < stringseed.length) { key[mask & j] = mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++)); } return tostring(key); } // // autoseed() // Returns an object for autoseeding, using window.crypto and Node crypto // module if available. // function autoseed() { try { if (nodecrypto) { return tostring(nodecrypto.randomBytes(width)); } var out = new Uint8Array(width); (global.crypto || global.msCrypto).getRandomValues(out); return tostring(out); } catch (e) { var browser = global.navigator, plugins = browser && browser.plugins; return [+new Date, global, plugins, global.screen, tostring(pool)]; } } // // tostring() // Converts an array of charcodes to a string // function tostring(a) { return String.fromCharCode.apply(0, a); } // // When seedrandom.js is loaded, we immediately mix a few bits // from the built-in RNG into the entropy pool. Because we do // not want to interfere with deterministic PRNG state later, // seedrandom will not call math.random on its own again after // initialization. // mixkey(math.random(), pool); // // Nodejs and AMD support: export the implementation as a module using // either convention. // // End anonymous scope, and pass initial values. })( [], // pool: entropy pool starts empty BMMath // math: package containing random, pow, and seedrandom ); var BezierFactory = (function(){ /** * BezierEasing - use bezier curve for transition easing function * by Gaëtan Renaudeau 2014 - 2015 – MIT License * * Credits: is based on Firefox's nsSMILKeySpline.cpp * Usage: * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ]) * spline.get(x) => returns the easing value | x must be in [0, 1] range * */ var ob = {}; ob.getBezierEasing = getBezierEasing; var beziers = {}; function getBezierEasing(a,b,c,d,nm){ var str = nm || ('bez_' + a+'_'+b+'_'+c+'_'+d).replace(/\./g, 'p'); if(beziers[str]){ return beziers[str]; } var bezEasing = new BezierEasing([a,b,c,d]); beziers[str] = bezEasing; return bezEasing; } // These values are established by empiricism with tests (tradeoff: performance VS precision) var NEWTON_ITERATIONS = 4; var NEWTON_MIN_SLOPE = 0.001; var SUBDIVISION_PRECISION = 0.0000001; var SUBDIVISION_MAX_ITERATIONS = 10; var kSplineTableSize = 11; var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0); var float32ArraySupported = typeof Float32Array === "function"; function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; } function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; } function C (aA1) { return 3.0 * aA1; } // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2. function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2)*aT + B(aA1, aA2))*aT + C(aA1))*aT; } // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2. function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2)*aT*aT + 2.0 * B(aA1, aA2) * aT + C(aA1); } function binarySubdivide (aX, aA, aB, mX1, mX2) { var currentX, currentT, i = 0; do { currentT = aA + (aB - aA) / 2.0; currentX = calcBezier(currentT, mX1, mX2) - aX; if (currentX > 0.0) { aB = currentT; } else { aA = currentT; } } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS); return currentT; } function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) { for (var i = 0; i < NEWTON_ITERATIONS; ++i) { var currentSlope = getSlope(aGuessT, mX1, mX2); if (currentSlope === 0.0) return aGuessT; var currentX = calcBezier(aGuessT, mX1, mX2) - aX; aGuessT -= currentX / currentSlope; } return aGuessT; } /** * points is an array of [ mX1, mY1, mX2, mY2 ] */ function BezierEasing (points) { this._p = points; this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize); this._precomputed = false; this.get = this.get.bind(this); } BezierEasing.prototype = { get: function (x) { var mX1 = this._p[0], mY1 = this._p[1], mX2 = this._p[2], mY2 = this._p[3]; if (!this._precomputed) this._precompute(); if (mX1 === mY1 && mX2 === mY2) return x; // linear // Because JavaScript number are imprecise, we should guarantee the extremes are right. if (x === 0) return 0; if (x === 1) return 1; return calcBezier(this._getTForX(x), mY1, mY2); }, // Private part _precompute: function () { var mX1 = this._p[0], mY1 = this._p[1], mX2 = this._p[2], mY2 = this._p[3]; this._precomputed = true; if (mX1 !== mY1 || mX2 !== mY2) this._calcSampleValues(); }, _calcSampleValues: function () { var mX1 = this._p[0], mX2 = this._p[2]; for (var i = 0; i < kSplineTableSize; ++i) { this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2); } }, /** * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection. */ _getTForX: function (aX) { var mX1 = this._p[0], mX2 = this._p[2], mSampleValues = this._mSampleValues; var intervalStart = 0.0; var currentSample = 1; var lastSample = kSplineTableSize - 1; for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) { intervalStart += kSampleStepSize; } --currentSample; // Interpolate to provide an initial guess for t var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample+1] - mSampleValues[currentSample]); var guessForT = intervalStart + dist * kSampleStepSize; var initialSlope = getSlope(guessForT, mX1, mX2); if (initialSlope >= NEWTON_MIN_SLOPE) { return newtonRaphsonIterate(aX, guessForT, mX1, mX2); } else if (initialSlope === 0.0) { return guessForT; } else { return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2); } } }; return ob; }()) function matrixManagerFunction(){ var mat = new Matrix(); var returnMatrix2D = function(rX, scaleX, scaleY, tX, tY){ return mat.reset().translate(tX,tY).rotate(rX).scale(scaleX,scaleY).toCSS(); }; var getMatrix = function(animData){ return returnMatrix2D(animData.tr.r[2],animData.tr.s[0],animData.tr.s[1],animData.tr.p[0],animData.tr.p[1]); }; return { getMatrix : getMatrix }; } var MatrixManager = matrixManagerFunction; (function () { var lastTime = 0; var vendors = ['ms', 'moz', 'webkit', 'o']; for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame']; } if(!window.requestAnimationFrame) window.requestAnimationFrame = function (callback, element) { var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16 - (currTime - lastTime)); var id = window.setTimeout(function () { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }; if(!window.cancelAnimationFrame) window.cancelAnimationFrame = function (id) { clearTimeout(id); }; }()); function createElement(parent,child,params){ if(child){ child.prototype = Object.create(parent.prototype); child.prototype.constructor = child; child.prototype._parent = parent.prototype; }else{ var instance = Object.create(parent.prototype,params); var getType = {}; if(instance && getType.toString.call(instance.init) === '[object Function]'){ instance.init(); } return instance; } } function extendPrototype(source,destination){ for (var attr in source.prototype) { if (source.prototype.hasOwnProperty(attr)) destination.prototype[attr] = source.prototype[attr]; } } function bezFunction(){ var easingFunctions = []; var math = Math; function pointOnLine2D(x1,y1, x2,y2, x3,y3){ var det1 = (x1*y2) + (y1*x3) + (x2*y3) - (x3*y2) - (y3*x1) - (x2*y1); return det1 > -0.0001 && det1 < 0.0001; } function pointOnLine3D(x1,y1,z1, x2,y2,z2, x3,y3,z3){ return pointOnLine2D(x1,y1, x2,y2, x3,y3) && pointOnLine2D(x1,z1, x2,z2, x3,z3); } /*function getEasingCurve(aa,bb,cc,dd,encodedFuncName) { if(!encodedFuncName){ encodedFuncName = ('bez_' + aa+'_'+bb+'_'+cc+'_'+dd).replace(/\./g, 'p'); } if(easingFunctions[encodedFuncName]){ return easingFunctions[encodedFuncName]; } var A0, B0, C0; var A1, B1, C1; easingFunctions[encodedFuncName] = function(tt) { var x = tt; var i = 0, z; while (++i < 20) { C0 = 3 * aa; B0 = 3 * (cc - aa) - C0; A0 = 1 - C0 - B0; z = (x * (C0 + x * (B0 + x * A0))) - tt; if (bm_abs(z) < 1e-3) break; x -= z / (C0 + x * (2 * B0 + 3 * A0 * x)); } C1 = 3 * bb; B1 = 3 * (dd - bb) - C1; A1 = 1 - C1 - B1; var polyB = x * (C1 + x * (B1 + x * A1)); //return c * polyB + b; return polyB; }; return easingFunctions[encodedFuncName]; }*/ var getBezierLength = (function(){ function Segment(l,p){ this.l = l; this.p = p; } return function(pt1,pt2,pt3,pt4){ var curveSegments = defaultCurveSegments; var k; var i, len; var ptCoord,perc,addedLength = 0; var ptDistance; var point = [],lastPoint = []; var lengthData = { addedLength: 0, segments: [] }; len = pt3.length; for(k=0;k lengthPos ? -1 : 1; var flag = true; while(flag){ if(segments[initPos].l <= lengthPos && segments[initPos+1].l > lengthPos){ lPerc = (lengthPos - segments[initPos].l)/(segments[initPos+1].l-segments[initPos].l); flag = false; }else{ initPos += dir; } if(initPos < 0 || initPos >= len - 1){ flag = false; } } return segments[initPos].p + (segments[initPos+1].p - segments[initPos].p)*lPerc; } } function SegmentPoints(){ this.pt1 = new Array(2); this.pt2 = new Array(2); this.pt3 = new Array(2); this.pt4 = new Array(2); } function getNewSegment(pt1,pt2,pt3,pt4,startPerc,endPerc, bezierData){ var pts = new SegmentPoints(); startPerc = startPerc < 0 ? 0 : startPerc > 1 ? 1 : startPerc; var t0 = getDistancePerc(startPerc,bezierData); endPerc = endPerc > 1 ? 1 : endPerc; var t1 = getDistancePerc(endPerc,bezierData); var i, len = pt1.length; var u0 = 1 - t0; var u1 = 1 - t1; //Math.round(num * 100) / 100 for(i=0;i=0;i-=1){ if(arr[i].ty == 'sh'){ if(arr[i].ks.k.i){ convertPathsToAbsoluteValues(arr[i].ks.k); }else{ jLen = arr[i].ks.k.length; for(j=0;janimVersion[0]){ return true; } else if(animVersion[0] > minimum[0]){ return false; } if(minimum[1]>animVersion[1]){ return true; } else if(animVersion[1] > minimum[1]){ return false; } if(minimum[2]>animVersion[2]){ return true; } else if(animVersion[2] > minimum[2]){ return false; } } var checkText = (function(){ var minimumVersion = [4,4,14]; function updateTextLayer(textLayer){ var documentData = textLayer.t.d; textLayer.t.d = { k: [ { s:documentData, t:0 } ] } } function iterateLayers(layers){ var i, len = layers.length; for(i=0;i=0;i-=1){ if(arr[i].ty == 'sh'){ if(arr[i].ks.k.i){ arr[i].ks.k.c = arr[i].closed; }else{ jLen = arr[i].ks.k.length; for(j=0;j=0;i-=1){ if(arr[i].ty == 'sh'){ if(arr[i].ks.k.i){ blitPaths(arr[i].ks.k); }else{ jLen = arr[i].ks.k.length; for(j=0;j=0){ val[i] /= blitter; i-=1; } } return val; } function blitProperty(data){ if(!data.k.length){ data.k = blitValue(data.k); }else if(typeof(data.k[0]) === 'number'){ data.k = blitValue(data.k); } else { var i, len = data.k.length; for(i=0;i boxWidth){ if(lastSpaceIndex === -1){ //i -= 1; documentData.t = documentData.t.substr(0,i) + "\r" + documentData.t.substr(i); len += 1; } else { i = lastSpaceIndex; documentData.t = documentData.t.substr(0,i) + "\r" + documentData.t.substr(i+1); } lastSpaceIndex = -1; lineWidth = 0; }else { lineWidth += cLength; } } len = documentData.t.length; } lineWidth = 0; cLength = 0; for (i = 0;i < len ;i += 1) { newLineFlag = false; if(documentData.t.charAt(i) === ' '){ val = '\u00A0'; }else if(documentData.t.charCodeAt(i) === 13){ lineWidths.push(lineWidth); maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth; lineWidth = 0; val = ''; newLineFlag = true; currentLine += 1; }else{ val = documentData.t.charAt(i); } if(fontManager.chars){ charData = fontManager.getCharData(documentData.t.charAt(i), fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily); cLength = newLineFlag ? 0 : charData.w*documentData.s/100; }else{ //var charWidth = fontManager.measureText(val, documentData.f, documentData.s); //tCanvasHelper.font = documentData.s + 'px '+ fontManager.getFontByName(documentData.f).fFamily; cLength = fontManager.measureText(val, documentData.f, documentData.s); } // lineWidth += cLength; letters.push({l:cLength,an:cLength,add:currentSize,n:newLineFlag, anIndexes:[], val: val, line: currentLine}); if(anchorGrouping == 2){ currentSize += cLength; if(val == '' || val == '\u00A0' || i == len - 1){ if(val == '' || val == '\u00A0'){ currentSize -= cLength; } while(currentPos<=i){ letters[currentPos].an = currentSize; letters[currentPos].ind = index; letters[currentPos].extra = cLength; currentPos += 1; } index += 1; currentSize = 0; } }else if(anchorGrouping == 3){ currentSize += cLength; if(val == '' || i == len - 1){ if(val == ''){ currentSize -= cLength; } while(currentPos<=i){ letters[currentPos].an = currentSize; letters[currentPos].ind = index; letters[currentPos].extra = cLength; currentPos += 1; } currentSize = 0; index += 1; } }else{ letters[index].ind = index; letters[index].extra = 0; index += 1; } } documentData.l = letters; maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth; lineWidths.push(lineWidth); if(documentData.sz){ documentData.boxWidth = documentData.sz[0]; documentData.justifyOffset = 0; }else{ documentData.boxWidth = maxLineWidth; switch(documentData.j){ case 1: documentData.justifyOffset = - documentData.boxWidth; break; case 2: documentData.justifyOffset = - documentData.boxWidth/2; break; default: documentData.justifyOffset = 0; } } documentData.lineWidths = lineWidths; var animators = data.t.a; jLen = animators.length; var based, ind, indexes = []; for(j=0;j var l = document.createElement('link'); l.type = "text/css"; l.rel = "stylesheet"; l.href = fontArr[i].fPath; defs.appendChild(l); } else if(fontArr[i].fOrigin === 't'){ // var sc = document.createElement('script'); sc.setAttribute('src',fontArr[i].fPath); defs.appendChild(sc); } fontArr[i].helper = createHelper(defs,fontArr[i]); this.fonts.push(fontArr[i]); } checkLoadedFonts.bind(this)(); } function addChars(chars){ if(!chars){ return; } if(!this.chars){ this.chars = []; } var i, len = chars.length; var j, jLen = this.chars.length, found; for(i=0;i= this.keyframes[this.keyframes.length- 1].t-this.offsetTime && frameNum >= this.keyframes[this.keyframes.length- 1].t-this.offsetTime) || (this.lastFrame < this.keyframes[0].t-this.offsetTime && frameNum < this.keyframes[0].t-this.offsetTime))))){ var i = this.lastFrame < frameNum ? this._lastIndex : 0; var len = this.keyframes.length- 1,flag = true; var keyData, nextKeyData; while(flag){ keyData = this.keyframes[i]; nextKeyData = this.keyframes[i+1]; if(i == len-1 && frameNum >= nextKeyData.t - this.offsetTime){ if(keyData.h){ keyData = nextKeyData; } break; } if((nextKeyData.t - this.offsetTime) > frameNum){ break; } if(i < len - 1){ i += 1; }else{ flag = false; } } this._lastIndex = i; var k, kLen,perc,jLen, j, fnc; if(keyData.to){ if(!keyData.bezierData){ bez.buildBezierData(keyData); } var bezierData = keyData.bezierData; if(frameNum >= nextKeyData.t-this.offsetTime || frameNum < keyData.t-this.offsetTime){ var ind = frameNum >= nextKeyData.t-this.offsetTime ? bezierData.points.length - 1 : 0; kLen = bezierData.points[ind].point.length; for(k = 0; k < kLen; k += 1){ this.pv[k] = bezierData.points[ind].point[k]; this.v[k] = this.mult ? this.pv[k]*this.mult : this.pv[k]; if(this.lastPValue[k] !== this.pv[k]) { this.mdf = true; this.lastPValue[k] = this.pv[k]; } } this._lastBezierData = null; }else{ if(keyData.__fnct){ fnc = keyData.__fnct; }else{ fnc = BezierFactory.getBezierEasing(keyData.o.x,keyData.o.y,keyData.i.x,keyData.i.y,keyData.n).get; keyData.__fnct = fnc; } perc = fnc((frameNum-(keyData.t-this.offsetTime))/((nextKeyData.t-this.offsetTime)-(keyData.t-this.offsetTime))); var distanceInLine = bezierData.segmentLength*perc; var segmentPerc; var addedLength = (this.lastFrame < frameNum && this._lastBezierData === bezierData) ? this._lastAddedLength : 0; j = (this.lastFrame < frameNum && this._lastBezierData === bezierData) ? this._lastPoint : 0; flag = true; jLen = bezierData.points.length; while(flag){ addedLength +=bezierData.points[j].partialLength; if(distanceInLine === 0 || perc === 0 || j == bezierData.points.length - 1){ kLen = bezierData.points[j].point.length; for(k=0;k= addedLength && distanceInLine < addedLength + bezierData.points[j+1].partialLength){ segmentPerc = (distanceInLine-addedLength)/(bezierData.points[j+1].partialLength); kLen = bezierData.points[j].point.length; for(k=0;k= nextKeyData.t-this.offsetTime){ perc = 1; }else if(frameNum < keyData.t-this.offsetTime){ perc = 0; }else{ if(keyData.o.x instanceof Array){ if(!keyData.__fnct){ keyData.__fnct = []; } if (!keyData.__fnct[i]) { outX = keyData.o.x[i] || keyData.o.x[0]; outY = keyData.o.y[i] || keyData.o.y[0]; inX = keyData.i.x[i] || keyData.i.x[0]; inY = keyData.i.y[i] || keyData.i.y[0]; fnc = BezierFactory.getBezierEasing(outX,outY,inX,inY).get; keyData.__fnct[i] = fnc; } else { fnc = keyData.__fnct[i]; } } else { if (!keyData.__fnct) { outX = keyData.o.x; outY = keyData.o.y; inX = keyData.i.x; inY = keyData.i.y; fnc = BezierFactory.getBezierEasing(outX,outY,inX,inY).get; keyData.__fnct = fnc; } else{ fnc = keyData.__fnct; } } perc = fnc((frameNum-(keyData.t-this.offsetTime))/((nextKeyData.t-this.offsetTime)-(keyData.t-this.offsetTime))); } } if(this.sh && keyData.h !== 1){ var initP = keyData.s[i]; var endP = keyData.e[i]; if(initP-endP < -180){ initP += 360; } else if(initP-endP > 180){ initP -= 360; } keyValue = initP+(endP-initP)*perc; } else { keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i]+(keyData.e[i]-keyData.s[i])*perc; } if(len === 1){ this.v = this.mult ? keyValue*this.mult : keyValue; this.pv = keyValue; if(this.lastPValue != this.pv){ this.mdf = true; this.lastPValue = this.pv; } }else{ this.v[i] = this.mult ? keyValue*this.mult : keyValue; this.pv[i] = keyValue; if(this.lastPValue[i] !== this.pv[i]){ this.mdf = true; this.lastPValue[i] = this.pv[i]; } } } } } this.lastFrame = frameNum; this.frameId = this.elem.globalData.frameId; } function getNoValue(){} function ValueProperty(elem,data, mult){ this.mult = mult; this.v = mult ? data.k * mult : data.k; this.pv = data.k; this.mdf = false; this.comp = elem.comp; this.k = false; this.kf = false; this.vel = 0; this.getValue = getNoValue; } function MultiDimensionalProperty(elem,data, mult){ this.mult = mult; this.data = data; this.mdf = false; this.comp = elem.comp; this.k = false; this.kf = false; this.frameId = -1; this.v = Array.apply(null, {length:data.k.length}); this.pv = Array.apply(null, {length:data.k.length}); this.lastValue = Array.apply(null, {length:data.k.length}); var arr = Array.apply(null, {length:data.k.length}); this.vel = arr.map(function () { return 0 }); var i, len = data.k.length; for(i = 0;i= this.p.keyframes[this.p.keyframes.length - 1].t) { v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / this.elem.globalData.frameRate), 0); v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.01) / this.elem.globalData.frameRate, 0); } else { v1 = this.p.pv; v2 = this.p.getValueAtTime((this.p.lastFrame+this.p.offsetTime - 0.01) / this.elem.globalData.frameRate, this.p.offsetTime); } this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0])); } if(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]); } } //console.log(this.v.to2dCSS()) this.frameId = this.elem.globalData.frameId; } function setInverted(){ this.inverted = true; this.iv = new Matrix(); if(!this.k){ if(this.data.p.s){ this.iv.translate(this.px.v,this.py.v,-this.pz.v); }else{ this.iv.translate(this.p.v[0],this.p.v[1],-this.p.v[2]); } if(this.r){ this.iv.rotate(-this.r.v); }else{ this.iv.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v); } if(this.s){ this.iv.scale(this.s.v[0],this.s.v[1],1); } if(this.a){ this.iv.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]); } } } function autoOrient(){ // //var prevP = this.getValueAtTime(); } return function TransformProperty(elem,data,arr){ this.elem = elem; this.frameId = -1; this.type = 'transform'; this.dynamicProperties = []; this.mdf = false; this.data = data; this.getValue = processKeys; this.applyToMatrix = applyToMatrix; this.setInverted = setInverted; this.autoOrient = autoOrient; this.v = new Matrix(); if(data.p.s){ this.px = PropertyFactory.getProp(elem,data.p.x,0,0,this.dynamicProperties); this.py = PropertyFactory.getProp(elem,data.p.y,0,0,this.dynamicProperties); if(data.p.z){ this.pz = PropertyFactory.getProp(elem,data.p.z,0,0,this.dynamicProperties); } }else{ this.p = PropertyFactory.getProp(elem,data.p,1,0,this.dynamicProperties); } if(data.r) { this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this.dynamicProperties); } else if(data.rx) { this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this.dynamicProperties); this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this.dynamicProperties); this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this.dynamicProperties); this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this.dynamicProperties); } if(data.sk){ this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this.dynamicProperties); this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this.dynamicProperties); } if(data.a) { this.a = PropertyFactory.getProp(elem,data.a,1,0,this.dynamicProperties); } if(data.s) { this.s = PropertyFactory.getProp(elem,data.s,1,0.01,this.dynamicProperties); } if(data.o){ this.o = PropertyFactory.getProp(elem,data.o,0,0.01,arr); } else { this.o = {mdf:false,v:1}; } if(this.dynamicProperties.length){ arr.push(this); }else{ if(this.a){ this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]); } if(this.s){ this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]); } if(this.sk){ this.v.skewFromAxis(-this.sk.v,this.sa.v); } if(this.r){ this.v.rotate(-this.r.v); }else{ 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.data.p.s){ if(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]); } } Object.defineProperty(this, "position", { get: positionGetter}); Object.defineProperty(this, "xPosition", { get: xPositionGetter}); Object.defineProperty(this, "yPosition", { get: yPositionGetter}); Object.defineProperty(this, "orientation", { get: orientationGetter}); Object.defineProperty(this, "anchorPoint", { get: anchorGetter}); Object.defineProperty(this, "rotation", { get: rotationGetter}); Object.defineProperty(this, "scale", { get: scaleGetter}); Object.defineProperty(this, "opacity", { get: opacityGetter}); Object.defineProperty(this, "skew", { get: skewGetter}); Object.defineProperty(this, "skewAxis", { get: skewAxisGetter}); } }()); function getProp(elem,data,type, mult, arr) { var p; if(type === 2){ p = new TransformProperty(elem, data, arr); } else if(data.a === 0){ if(type === 0) { p = new ValueProperty(elem,data,mult); } else { p = new MultiDimensionalProperty(elem,data, mult); } } else if(data.a === 1){ if(type === 0) { p = new KeyframedValueProperty(elem,data,mult); } else { p = new KeyframedMultidimensionalProperty(elem,data, mult); } } else if(!data.k.length){ p = new ValueProperty(elem,data, mult); }else if(typeof(data.k[0]) === 'number'){ p = new MultiDimensionalProperty(elem,data, mult); }else{ switch(type){ case 0: p = new KeyframedValueProperty(elem,data,mult); break; case 1: p = new KeyframedMultidimensionalProperty(elem,data,mult); break; } } if(p.k){ arr.push(p); } return p; } var getGradientProp = (function(){ function getValue(forceRender){ this.prop.getValue(); this.cmdf = false; this.omdf = false; if(this.prop.mdf || forceRender){ var i, len = this.data.p*4; var mult, val; for(i=0;ie){ var _s = s; s = e; e = _s; } this.finalS = s; this.finalE = e; } function getMult(ind){ //var easer = bez.getEasingCurve(this.ne.v/100,0,1-this.xe.v/100,1); var easer = BezierFactory.getBezierEasing(this.ne.v/100,0,1-this.xe.v/100,1).get; var mult = 0; var s = this.finalS; var e = this.finalE; var type = this.data.sh; if(type == 2){ if(e === s){ mult = ind >= e ? 1 : 0; }else{ mult = max(0,min(0.5/(e-s) + (ind-s)/(e-s),1)); } mult = easer(mult); }else if(type == 3){ if(e === s){ mult = ind >= e ? 0 : 1; }else{ mult = 1 - max(0,min(0.5/(e-s) + (ind-s)/(e-s),1)); } mult = easer(mult); }else if(type == 4){ if(e === s){ mult = 0; }else{ mult = max(0,min(0.5/(e-s) + (ind-s)/(e-s),1)); if(mult<.5){ mult *= 2; }else{ mult = 1 - 2*(mult-0.5); } } mult = easer(mult); }else if(type == 5){ if(e === s){ mult = 0; }else{ var tot = e - s; /*ind += 0.5; mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind;*/ ind = min(max(0,ind+0.5-s),e-s); var x = -tot/2+ind; var a = tot/2; mult = Math.sqrt(1 - (x*x)/(a*a)); } mult = easer(mult); }else if(type == 6){ if(e === s){ mult = 0; }else{ ind = min(max(0,ind+0.5-s),e-s); mult = (1+(Math.cos((Math.PI+Math.PI*2*(ind)/(e-s)))))/2; /* ind = Math.min(Math.max(s,ind),e-1); mult = (1+(Math.cos((Math.PI+Math.PI*2*(ind-s)/(e-1-s)))))/2; mult = Math.max(mult,(1/(e-1-s))/(e-1-s));*/ } mult = easer(mult); }else { if(ind >= floor(s)){ if(ind-s < 0){ mult = 1 - (s - ind); }else{ mult = max(0,min(e-ind,1)); } } mult = easer(mult); } return mult*this.a.v; } return function TextSelectorProp(elem,data, arr){ this.mdf = false; this.k = false; this.data = data; this.dynamicProperties = []; this.getValue = updateRange; this.getMult = getMult; this.comp = elem.comp; this.finalS = 0; this.finalE = 0; this.s = PropertyFactory.getProp(elem,data.s || {k:0},0,0,this.dynamicProperties); if('e' in data){ this.e = PropertyFactory.getProp(elem,data.e,0,0,this.dynamicProperties); }else{ this.e = {v:data.r === 2 ? data.totalChars : 100}; } this.o = PropertyFactory.getProp(elem,data.o || {k:0},0,0,this.dynamicProperties); this.xe = PropertyFactory.getProp(elem,data.xe || {k:0},0,0,this.dynamicProperties); this.ne = PropertyFactory.getProp(elem,data.ne || {k:0},0,0,this.dynamicProperties); this.a = PropertyFactory.getProp(elem,data.a,0,0.01,this.dynamicProperties); if(this.dynamicProperties.length){ arr.push(this); }else{ this.getValue(); } } }()); function getTextSelectorProp(elem, data,arr) { return new TextSelectorProp(elem, data, arr); }; var ob = {}; ob.getProp = getProp; ob.getDashProp = getDashProp; ob.getTextSelectorProp = getTextSelectorProp; ob.getGradientProp = getGradientProp; return ob; }()); function ShapePath(){ this.c = false; this._length = 0; this._maxLength = 8; this.v = Array.apply(null,{length:this._maxLength}); this.o = Array.apply(null,{length:this._maxLength}); this.i = Array.apply(null,{length:this._maxLength}); }; ShapePath.prototype.setPathData = function(closed, len) { this.c = closed; while(len > this._maxLength){ this.doubleArrayLength(); } var i = 0; while(i < len){ this.v[i] = point_pool.newPoint(); this.o[i] = point_pool.newPoint(); this.i[i] = point_pool.newPoint(); i += 1; } this._length = len; }; ShapePath.prototype.doubleArrayLength = function() { this.v = this.v.concat(Array.apply(null,{length:this._maxLength})) this.i = this.i.concat(Array.apply(null,{length:this._maxLength})) this.o = this.o.concat(Array.apply(null,{length:this._maxLength})) this._maxLength *= 2; }; ShapePath.prototype.setXYAt = function(x, y, type, pos, replace) { var arr; this._length = Math.max(this._length, pos + 1); if(this._length >= this._maxLength) { this.doubleArrayLength(); } switch(type){ case 'v': arr = this.v; break; case 'i': arr = this.i; break; case 'o': arr = this.o; break; } if(!arr[pos] || (arr[pos] && !replace)){ arr[pos] = point_pool.newPoint(); } arr[pos][0] = x; arr[pos][1] = y; }; ShapePath.prototype.setTripleAt = function(vX,vY,oX,oY,iX,iY,pos, replace) { this.setXYAt(vX,vY,'v',pos, replace); this.setXYAt(oX,oY,'o',pos, replace); this.setXYAt(iX,iY,'i',pos, replace); }; var ShapePropertyFactory = (function(){ var initFrame = -999999; function interpolateShape() { if(this.elem.globalData.frameId === this.frameId){ return; } this.mdf = false; var frameNum = this.comp.renderedFrame - this.offsetTime; if(!((this.lastFrame !== initFrame && ((this.lastFrame < this.keyframes[0].t-this.offsetTime && frameNum < this.keyframes[0].t-this.offsetTime) || (this.lastFrame > this.keyframes[this.keyframes.length - 1].t-this.offsetTime && frameNum > this.keyframes[this.keyframes.length - 1].t-this.offsetTime))))){ var keyPropS,keyPropE,isHold; if(frameNum < this.keyframes[0].t-this.offsetTime){ keyPropS = this.keyframes[0].s[0]; isHold = true; this._lastIndex = 0; }else if(frameNum >= this.keyframes[this.keyframes.length - 1].t-this.offsetTime){ if(this.keyframes[this.keyframes.length - 2].h === 1){ keyPropS = this.keyframes[this.keyframes.length - 1].s[0]; }else{ keyPropS = this.keyframes[this.keyframes.length - 2].e[0]; } isHold = true; }else{ var i = this.lastFrame < initFrame ? this._lastIndex : 0; var len = this.keyframes.length- 1,flag = true,keyData,nextKeyData, j, jLen, k, kLen; while(flag){ keyData = this.keyframes[i]; nextKeyData = this.keyframes[i+1]; if((nextKeyData.t - this.offsetTime) > frameNum){ break; } if(i < len - 1){ i += 1; }else{ flag = false; } } isHold = keyData.h === 1; this._lastIndex = i; var perc; 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 = this.v._length; kLen = keyPropS.i[0].length; var hasModified = false; var vertexValue; for(j=0;je){ var _s = s; s = e; e = _s; } this.sValue = s; this.eValue = e; this.oValue = o; } } TrimModifier.prototype.initModifierProperties = function(elem,data){ this.sValue = 0; this.eValue = 0; this.oValue = 0; this.getValue = this.processKeys; this.s = PropertyFactory.getProp(elem,data.s,0,0.01,this.dynamicProperties); this.e = PropertyFactory.getProp(elem,data.e,0,0.01,this.dynamicProperties); this.o = PropertyFactory.getProp(elem,data.o,0,0,this.dynamicProperties); this.m = data.m; if(!this.dynamicProperties.length){ this.getValue(true); } }; TrimModifier.prototype.getSegmentsLength = function(shapeData){ var closed = shapeData.c; var pathV = shapeData.v; var pathO = shapeData.o; var pathI = shapeData.i; var i, len = shapeData._length; var lengths = []; var totalLength = 0; for(i=0;i= 1){ segments.push({ s: s - 1, e: e - 1 }) }else{ segments.push({ s: s, e: 1 }) segments.push({ s: 0, e: e - 1 }) } var shapeSegments = []; var i, len = segments.length, segmentOb; for(i = 0; i < len; i += 1) { segmentOb = segments[i]; if (segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength) { } else { var shapeS, shapeE; if(segmentOb.s * totalModifierLength <= addedLength) { shapeS = 0; } else { shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength; } if(segmentOb.e * totalModifierLength >= addedLength + shapeLength) { shapeE = 1; } else { shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength); } shapeSegments.push([shapeS, shapeE]); } } if(!shapeSegments.length){ shapeSegments.push([0,0]); } return shapeSegments; } TrimModifier.prototype.processShapes = function(firstFrame){ var shapePaths; var i, len = this.shapes.length; var j, jLen; var s = this.sValue; var e = this.eValue; var pathsData,pathData, totalShapeLength, totalModifierLength = 0; if(e === s){ for(i=0;i= 0; i -= 1){ shapeData = this.shapes[i]; if (shapeData.shape.mdf) { localShapeCollection = shapeData.localShapeCollection; localShapeCollection.releaseShapes(); if(this.m === 2 && len > 1) { var edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength); addedLength += shapeData.totalShapeLength; } else { edges = [[shapeS, shapeE]] } jLen = edges.length; for (j = 0; j < jLen; j += 1) { shapeS = edges[j][0]; shapeE = edges[j][1]; segments.length = 0; if(shapeE <= 1){ segments.push({ s:shapeData.totalShapeLength * shapeS, e:shapeData.totalShapeLength * shapeE }) }else if(shapeS >= 1){ segments.push({ s:shapeData.totalShapeLength * (shapeS - 1), e:shapeData.totalShapeLength * (shapeE - 1) }) }else{ segments.push({ s:shapeData.totalShapeLength * shapeS, e:shapeData.totalShapeLength }) segments.push({ s:0, e:shapeData.totalShapeLength*(shapeE - 1) }) } var newShapesData = this.addShapes(shapeData,segments[0]); if (segments[0].s !== segments[0].e) { var lastPos; if(segments.length > 1){ if(shapeData.shape.v.c){ var lastShape = newShapesData.pop(); this.addPaths(newShapesData, localShapeCollection); newShapesData = this.addShapes(shapeData,segments[1], lastShape); } else { this.addPaths(newShapesData, localShapeCollection); newShapesData = this.addShapes(shapeData,segments[1]); } } this.addPaths(newShapesData, localShapeCollection); } } shapeData.shape.paths = localShapeCollection; } } } if(!this.dynamicProperties.length){ this.mdf = false; } } TrimModifier.prototype.addPaths = function(newPaths, localShapeCollection) { var i, len = newPaths.length; for(i = 0; i < len; i += 1) { localShapeCollection.addShape(newPaths[i]) } } TrimModifier.prototype.addSegment = function(pt1,pt2,pt3,pt4,shapePath,pos, newShape) { /*console.log(pt1, 'vertex: v, at: ', pos); console.log(pt2, 'vertex: o, at: ', pos); console.log(pt3, 'vertex: i, at: ', pos + 1); console.log(pt4, 'vertex: v, at: ', pos + 1); console.log('newShape: ', newShape);*/ shapePath.setXYAt(pt2[0],pt2[1],'o',pos); shapePath.setXYAt(pt3[0],pt3[1],'i',pos + 1); if(newShape){ shapePath.setXYAt(pt1[0],pt1[1],'v',pos); } shapePath.setXYAt(pt4[0],pt4[1],'v',pos + 1); } TrimModifier.prototype.addShapes = function(shapeData, shapeSegment, shapePath){ var pathsData = shapeData.pathsData; var shapePaths = shapeData.shape.paths.shapes; var i, len = shapeData.shape.paths._length, j, jLen; var addedLength = 0; var currentLengthData,segmentCount; var lengths; var segment; var shapes = []; var initPos; var newShape = true; if(!shapePath){ shapePath = shape_pool.newShape(); segmentCount = 0; initPos = 0; } else { segmentCount = shapePath._length; initPos = shapePath._length; } shapes.push(shapePath); for(i=0;i shapeSegment.e){ shapePath.c = false; break; } else { if(shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength){ this.addSegment(shapePaths[i].v[j-1],shapePaths[i].o[j-1],shapePaths[i].i[j],shapePaths[i].v[j],shapePath,segmentCount,newShape); newShape = false; } else { segment = bez.getNewSegment(shapePaths[i].v[j-1],shapePaths[i].v[j],shapePaths[i].o[j-1],shapePaths[i].i[j], (shapeSegment.s - addedLength)/currentLengthData.addedLength,(shapeSegment.e - addedLength)/currentLengthData.addedLength, lengths[j-1]); this.addSegment(segment.pt1,segment.pt3,segment.pt4,segment.pt2,shapePath,segmentCount,newShape); newShape = false; shapePath.c = false; } addedLength += currentLengthData.addedLength; segmentCount += 1; } } if(shapePaths[i].c){ currentLengthData = lengths[j-1]; if(addedLength <= shapeSegment.e){ var segmentLength = lengths[j-1].addedLength; if(shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength){ this.addSegment(shapePaths[i].v[j-1],shapePaths[i].o[j-1],shapePaths[i].i[0],shapePaths[i].v[0],shapePath,segmentCount,newShape); newShape = false; }else{ segment = bez.getNewSegment(shapePaths[i].v[j-1],shapePaths[i].v[0],shapePaths[i].o[j-1],shapePaths[i].i[0], (shapeSegment.s - addedLength)/segmentLength,(shapeSegment.e - addedLength)/segmentLength, lengths[j-1]); this.addSegment(segment.pt1,segment.pt3,segment.pt4,segment.pt2,shapePath,segmentCount,newShape); newShape = false; shapePath.c = false; } } else { shapePath.c = false; } addedLength += currentLengthData.addedLength; segmentCount += 1; } if(shapePath._length){ shapePath.setXYAt(shapePath.v[initPos][0],shapePath.v[initPos][1],'i',initPos); shapePath.setXYAt(shapePath.v[shapePath._length - 1][0],shapePath.v[shapePath._length - 1][1],'o',shapePath._length - 1); } if(addedLength > shapeSegment.e){ break; } if(i 0 ? Math.floor(offset) : Math.ceil(offset); var k, pathData, shapeCollection, shapeCollectionList; var tMat = this.tr.v.props; var pProps = this.pMatrix.props; var rProps = this.rMatrix.props; var sProps = this.sMatrix.props; var iteration = 0; var l, lLen, tProps,transformers, maxLvl; for(i=0;i 0) { while(iterationroundOffset){ this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true); iteration -= 1; } if(offsetModulo){ this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, - offsetModulo, true); iteration -= offsetModulo; } } for(j=0;j= maxLvl; l -= 1) { tProps = transformers[l].mProps.v.props; this.matrix.transform(tProps[0],tProps[1],tProps[2],tProps[3],tProps[4],tProps[5],tProps[6],tProps[7],tProps[8],tProps[9],tProps[10],tProps[11],tProps[12],tProps[13],tProps[14],tProps[15]); } } if(iteration !== 0){ this.matrix.transform(rProps[0],rProps[1],rProps[2],rProps[3],rProps[4],rProps[5],rProps[6],rProps[7],rProps[8],rProps[9],rProps[10],rProps[11],rProps[12],rProps[13],rProps[14],rProps[15]); this.matrix.transform(sProps[0],sProps[1],sProps[2],sProps[3],sProps[4],sProps[5],sProps[6],sProps[7],sProps[8],sProps[9],sProps[10],sProps[11],sProps[12],sProps[13],sProps[14],sProps[15]); this.matrix.transform(pProps[0],pProps[1],pProps[2],pProps[3],pProps[4],pProps[5],pProps[6],pProps[7],pProps[8],pProps[9],pProps[10],pProps[11],pProps[12],pProps[13],pProps[14],pProps[15]); } localShapeCollection.addShape(this.processPath(currentPath, this.matrix)); this.matrix.reset(); iteration += 1; } } } shapeData.shape.paths = localShapeCollection; } }; RepeaterModifier.prototype.processPath = function(path, transform) { var clonedPath = shape_pool.clone(path, transform); return clonedPath; }; ShapeModifiers.registerModifier('rp',RepeaterModifier); function ShapeCollection(){ this._length = 0; this._maxLength = 4; this.shapes = Array.apply(null,{length:this._maxLength}); }; ShapeCollection.prototype.addShape = function(shapeData){ if(this._length === this._maxLength){ this.shapes = this.shapes.concat(Array.apply(null,{length:this._maxLength})); this._maxLength *= 2; } this.shapes[this._length] = shapeData; this._length += 1; }; ShapeCollection.prototype.releaseShapes = function(){ var i; for(i = 0; i < this._length; i += 1) { shape_pool.release(this.shapes[i]); } this._length = 0; }; var ImagePreloader = (function(){ function imageLoaded(){ this.loadedAssets += 1; if(this.loadedAssets === this.totalImages){ } } function getAssetsPath(assetData){ var path = ''; if(this.assetsPath){ var imagePath = assetData.p; if(imagePath.indexOf('images/') !== -1){ imagePath = imagePath.split('/')[1]; } path = this.assetsPath + imagePath; } else { path = this.path; path += assetData.u ? assetData.u : ''; path += assetData.p; } return path; } function loadImage(path){ var img = document.createElement('img'); img.addEventListener('load', imageLoaded.bind(this), false); img.addEventListener('error', imageLoaded.bind(this), false); img.src = path; } function loadAssets(assets){ this.totalAssets = assets.length; var i; for(i=0;i= 0; i--) { if (!this.elements[i]) { data = this.layers[i]; if(data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) { this.buildItem(i); } } this.completeLayers = this.elements[i] ? this.completeLayers:false; } this.checkPendingElements(); }; BaseRenderer.prototype.createItem = function(layer){ switch(layer.ty){ case 2: return this.createImage(layer); case 0: return this.createComp(layer); case 1: return this.createSolid(layer); case 4: return this.createShape(layer); case 5: return this.createText(layer); case 99: return null; } return this.createBase(layer); }; BaseRenderer.prototype.buildAllItems = function(){ var i, len = this.layers.length; for(i=0;i= 0; i--) { if(this.completeLayers || this.elements[i]){ this.elements[i].prepareFrame(num - this.layers[i].st); } } for (i = len - 1; i >= 0; i--) { if(this.completeLayers || this.elements[i]){ this.elements[i].renderFrame(); } } }; SVGRenderer.prototype.appendElementInPos = function(element, pos){ var newElement = element.getBaseElement(); if(!newElement){ return; } var i = 0; var nextElement; while(i 0){ this.element.maskedElement.setAttribute(maskRef, "url(#" + layerId + ")"); } defs.appendChild(this.maskElement); }; MaskElement.prototype.getMaskProperty = function(pos){ return this.viewData[pos].prop; }; MaskElement.prototype.prepareFrame = function(){ var i, len = this.dynamicProperties.length; for(i=0;i 1){ pathString += " C"+bm_rnd(pathNodes.o[i-1][0])+','+bm_rnd(pathNodes.o[i-1][1]) + " "+bm_rnd(pathNodes.i[0][0])+','+bm_rnd(pathNodes.i[0][1]) + " "+bm_rnd(pathNodes.v[0][0])+','+bm_rnd(pathNodes.v[0][1]); } //pathNodes.__renderedString = pathString; if(viewData.lastPath !== pathString){ if(viewData.elem){ if(!pathNodes.c){ viewData.elem.setAttribute('d',''); }else if(pathData.inv){ viewData.elem.setAttribute('d',this.solidPath + pathString); }else{ viewData.elem.setAttribute('d',pathString); } } viewData.lastPath = pathString; } }; MaskElement.prototype.getMask = function(nm){ var i = 0, len = this.masksProperties.length; while(i num) { if(this.isVisible !== true){ this.elemMdf = true; this.globalData.mdf = true; this.isVisible = true; this.firstFrame = true; if(this.data.hasMask){ this.maskManager.firstFrame = true; } } }else{ if(this.isVisible !== false){ this.elemMdf = true; this.globalData.mdf = true; this.isVisible = false; } } var i, len = this.dynamicProperties.length; for(i=0;i num){ break; } textDocumentData = this.data.t.d.k[i].s; i += 1; } this.lettersChangedFlag = false; if(textDocumentData !== this.currentTextDocumentData){ this.currentTextDocumentData = textDocumentData; this.lettersChangedFlag = true; this.buildNewText(); } this._parent.prepareFrame.call(this, num); } ITextElement.prototype.createPathShape = function(matrixHelper, shapes) { var j,jLen = shapes.length; var k, kLen, pathNodes; var shapeStr = ''; for(j=0;j= currentLength + animatorOffset || !points) { perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength; xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc; yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc; matrixHelper.translate(0, -(renderedData.m.a.v[1] * yOff / 100) + yPos); flag = false; } else if (points) { segmentLength += currentPoint.partialLength; pointInd += 1; if (pointInd >= points.length) { pointInd = 0; segmentInd += 1; if (!segments[segmentInd]) { if (mask.v.c) { pointInd = 0; segmentInd = 0; points = segments[segmentInd].bezierData.points; } else { segmentLength -= currentPoint.partialLength; points = null; } } else { points = segments[segmentInd].bezierData.points; } } if (points) { prevPoint = currentPoint; currentPoint = points[pointInd]; partialLength = currentPoint.partialLength; } } } offf = letters[i].an / 2 - letters[i].add; matrixHelper.translate(-offf, 0, 0); } else { offf = letters[i].an/2 - letters[i].add; matrixHelper.translate(-offf,0,0); // Grouping alignment matrixHelper.translate(-renderedData.m.a.v[0]*letters[i].an/200, -renderedData.m.a.v[1]*yOff/100, 0); } lineLength += letters[i].l/2; for(j=0;j= max){ colorValue = inputDelta < 0 ? outputBlack : outputWhite; } else { colorValue = (outputBlack + outputDelta * Math.pow((perc - inputBlack) / inputDelta, 1 / gamma)); } table[pos++] = colorValue; cnt += 256/(segments-1); } return table.join(' '); }; SVGProLevelsFilter.prototype.renderFrame = function(forceRender){ if(forceRender || this.filterManager.mdf){ var val, cnt, perc, bezier; var effectElements = this.filterManager.effectElements; if(this.feFuncRComposed && (forceRender || effectElements[2].p.mdf || effectElements[3].p.mdf || effectElements[4].p.mdf || effectElements[5].p.mdf || effectElements[6].p.mdf)){ val = this.getTableValue(effectElements[2].p.v,effectElements[3].p.v,effectElements[4].p.v,effectElements[5].p.v,effectElements[6].p.v); this.feFuncRComposed.setAttribute('tableValues',val); this.feFuncGComposed.setAttribute('tableValues',val); this.feFuncBComposed.setAttribute('tableValues',val); } if(this.feFuncR && (forceRender || effectElements[9].p.mdf || effectElements[10].p.mdf || effectElements[11].p.mdf || effectElements[12].p.mdf || effectElements[13].p.mdf)){ val = this.getTableValue(effectElements[9].p.v,effectElements[10].p.v,effectElements[11].p.v,effectElements[12].p.v,effectElements[13].p.v); this.feFuncR.setAttribute('tableValues',val); } if(this.feFuncG && (forceRender || effectElements[16].p.mdf || effectElements[17].p.mdf || effectElements[18].p.mdf || effectElements[19].p.mdf || effectElements[20].p.mdf)){ val = this.getTableValue(effectElements[16].p.v,effectElements[17].p.v,effectElements[18].p.v,effectElements[19].p.v,effectElements[20].p.v); this.feFuncG.setAttribute('tableValues',val); } if(this.feFuncB && (forceRender || effectElements[23].p.mdf || effectElements[24].p.mdf || effectElements[25].p.mdf || effectElements[26].p.mdf || effectElements[27].p.mdf)){ val = this.getTableValue(effectElements[23].p.v,effectElements[24].p.v,effectElements[25].p.v,effectElements[26].p.v,effectElements[27].p.v); this.feFuncB.setAttribute('tableValues',val); } if(this.feFuncA && (forceRender || effectElements[30].p.mdf || effectElements[31].p.mdf || effectElements[32].p.mdf || effectElements[33].p.mdf || effectElements[34].p.mdf)){ val = this.getTableValue(effectElements[30].p.v,effectElements[31].p.v,effectElements[32].p.v,effectElements[33].p.v,effectElements[34].p.v); this.feFuncA.setAttribute('tableValues',val); } } }; function SVGDropShadowEffect(filter, filterManager){ /* */ /**/ filter.setAttribute('x','-100%'); filter.setAttribute('y','-100%'); filter.setAttribute('width','400%'); filter.setAttribute('height','400%'); this.filterManager = filterManager; var feGaussianBlur = document.createElementNS(svgNS,'feGaussianBlur'); feGaussianBlur.setAttribute('in','SourceAlpha'); feGaussianBlur.setAttribute('result','drop_shadow_1'); feGaussianBlur.setAttribute('stdDeviation','0'); this.feGaussianBlur = feGaussianBlur; filter.appendChild(feGaussianBlur); var feOffset = document.createElementNS(svgNS,'feOffset'); feOffset.setAttribute('dx','25'); feOffset.setAttribute('dy','0'); feOffset.setAttribute('in','drop_shadow_1'); feOffset.setAttribute('result','drop_shadow_2'); this.feOffset = feOffset; filter.appendChild(feOffset); var feFlood = document.createElementNS(svgNS,'feFlood'); feFlood.setAttribute('flood-color','#00ff00'); feFlood.setAttribute('flood-opacity','1'); feFlood.setAttribute('result','drop_shadow_3'); this.feFlood = feFlood; filter.appendChild(feFlood); var feComposite = document.createElementNS(svgNS,'feComposite'); feComposite.setAttribute('in','drop_shadow_3'); feComposite.setAttribute('in2','drop_shadow_2'); feComposite.setAttribute('operator','in'); feComposite.setAttribute('result','drop_shadow_4'); filter.appendChild(feComposite); var feMerge = document.createElementNS(svgNS,'feMerge'); filter.appendChild(feMerge); var feMergeNode; feMergeNode = document.createElementNS(svgNS,'feMergeNode'); feMerge.appendChild(feMergeNode); feMergeNode = document.createElementNS(svgNS,'feMergeNode'); feMergeNode.setAttribute('in','SourceGraphic'); this.feMergeNode = feMergeNode; this.feMerge = feMerge; this.originalNodeAdded = false; feMerge.appendChild(feMergeNode); } SVGDropShadowEffect.prototype.renderFrame = function(forceRender){ if(forceRender || this.filterManager.mdf){ if(forceRender || this.filterManager.effectElements[4].p.mdf){ this.feGaussianBlur.setAttribute('stdDeviation', this.filterManager.effectElements[4].p.v / 4); } if(forceRender || this.filterManager.effectElements[0].p.mdf){ var col = this.filterManager.effectElements[0].p.v; this.feFlood.setAttribute('flood-color',rgbToHex(Math.round(col[0]*255),Math.round(col[1]*255),Math.round(col[2]*255))); } if(forceRender || this.filterManager.effectElements[1].p.mdf){ this.feFlood.setAttribute('flood-opacity',this.filterManager.effectElements[1].p.v/255); } if(forceRender || this.filterManager.effectElements[2].p.mdf || this.filterManager.effectElements[3].p.mdf){ var distance = this.filterManager.effectElements[3].p.v var angle = (this.filterManager.effectElements[2].p.v - 90) * degToRads var x = distance * Math.cos(angle) var y = distance * Math.sin(angle) this.feOffset.setAttribute('dx', x); this.feOffset.setAttribute('dy', y); } /*if(forceRender || this.filterManager.effectElements[5].p.mdf){ if(this.filterManager.effectElements[5].p.v === 1 && this.originalNodeAdded) { this.feMerge.removeChild(this.feMergeNode); this.originalNodeAdded = false; } else if(this.filterManager.effectElements[5].p.v === 0 && !this.originalNodeAdded) { this.feMerge.appendChild(this.feMergeNode); this.originalNodeAdded = true; } }*/ } }; function SVGEffects(elem){ var i, len = elem.data.ef.length; var filId = randomString(10); var fil = filtersFactory.createFilter(filId); var count = 0; this.filters = []; var filterManager; for(i=0;i arr.g.p*4) || arr.g.k.k.length > arr.g.p*4){ var opFill; var stop, j, jLen; var mask = document.createElementNS(svgNS,"mask"); var maskElement = document.createElementNS(svgNS, 'path'); mask.appendChild(maskElement); var opacityId = 'op_'+randomString(10); var maskId = 'mk_'+randomString(10); mask.setAttribute('id',maskId); if(arr.t === 1){ opFill = document.createElementNS(svgNS,'linearGradient'); } else { opFill = document.createElementNS(svgNS,'radialGradient'); } opFill.setAttribute('id',opacityId); opFill.setAttribute('spreadMethod','pad'); opFill.setAttribute('gradientUnits','userSpaceOnUse'); jLen = arr.g.k.k[0].s ? arr.g.k.k[0].s.length : arr.g.k.k.length; var stops = []; for(j=arr.g.p*4;j=0;i-=1){ if(arr[i].ty == 'fl' || arr[i].ty == 'st' || arr[i].ty == 'gf' || arr[i].ty == 'gs'){ data[i] = {}; styleOb = { type: arr[i].ty, d: '', ld: '', lvl: level, mdf: false }; var pathElement = document.createElementNS(svgNS, "path"); data[i].o = PropertyFactory.getProp(this,arr[i].o,0,0.01,dynamicProperties); if(arr[i].ty == 'st' || arr[i].ty == 'gs') { pathElement.setAttribute('stroke-linecap', this.lcEnum[arr[i].lc] || 'round'); ////pathElement.style.strokeLinecap = this.lcEnum[arr[i].lc] || 'round'; pathElement.setAttribute('stroke-linejoin',this.ljEnum[arr[i].lj] || 'round'); ////pathElement.style.strokeLinejoin = this.ljEnum[arr[i].lj] || 'round'; pathElement.setAttribute('fill-opacity','0'); ////pathElement.style.fillOpacity = 0; if(arr[i].lj == 1) { pathElement.setAttribute('stroke-miterlimit',arr[i].ml); ////pathElement.style.strokeMiterlimit = arr[i].ml; } data[i].w = PropertyFactory.getProp(this,arr[i].w,0,null,dynamicProperties); if(arr[i].d){ var d = PropertyFactory.getDashProp(this,arr[i].d,'svg',dynamicProperties); if(!d.k){ pathElement.setAttribute('stroke-dasharray', d.dasharray); ////pathElement.style.strokeDasharray = d.dasharray; pathElement.setAttribute('stroke-dashoffset', d.dashoffset); ////pathElement.style.strokeDashoffset = d.dashoffset; } data[i].d = d; } } if(arr[i].ty == 'fl' || arr[i].ty == 'st'){ data[i].c = PropertyFactory.getProp(this,arr[i].c,1,255,dynamicProperties); container.appendChild(pathElement); } else { data[i].g = PropertyFactory.getGradientProp(this,arr[i].g,dynamicProperties); if(arr[i].t == 2){ data[i].h = PropertyFactory.getProp(this,arr[i].h,1,0.01,dynamicProperties); data[i].a = PropertyFactory.getProp(this,arr[i].a,1,degToRads,dynamicProperties); } data[i].s = PropertyFactory.getProp(this,arr[i].s,1,null,dynamicProperties); data[i].e = PropertyFactory.getProp(this,arr[i].e,1,null,dynamicProperties); this.setGradientData(pathElement,arr[i],data[i], styleOb); var maskId = this.setGradientOpacity(arr[i],data[i], styleOb); if(maskId){ pathElement.setAttribute('mask','url(#'+maskId+')'); } data[i].elem = pathElement; container.appendChild(pathElement); } if(arr[i].r === 2) { pathElement.setAttribute('fill-rule', 'evenodd'); } if(arr[i].ln){ pathElement.setAttribute('id',arr[i].ln); } if(arr[i].cl){ pathElement.setAttribute('class',arr[i].cl); } styleOb.pElem = pathElement; this.stylesList.push(styleOb); data[i].style = styleOb; ownArrays.push(styleOb); }else if(arr[i].ty == 'gr'){ data[i] = { it: [] }; var g = document.createElementNS(svgNS,'g'); container.appendChild(g); data[i].gr = g; this.searchShapes(arr[i].it,data[i].it,g,dynamicProperties, level + 1, ownTransformers); }else if(arr[i].ty == 'tr'){ data[i] = { transform : { op: PropertyFactory.getProp(this,arr[i].o,0,0.01,dynamicProperties), mProps: PropertyFactory.getProp(this,arr[i],2,null,dynamicProperties) }, elements: [] }; currentTransform = data[i].transform; ownTransformers.push(currentTransform); }else if(arr[i].ty == 'sh' || arr[i].ty == 'rc' || arr[i].ty == 'el' || arr[i].ty == 'sr'){ data[i] = { elements : [], caches:[], styles : [], transformers: ownTransformers, lStr: '' }; var ty = 4; if(arr[i].ty == 'rc'){ ty = 5; }else if(arr[i].ty == 'el'){ ty = 6; }else if(arr[i].ty == 'sr'){ ty = 7; } data[i].sh = ShapePropertyFactory.getShapeProp(this,arr[i],ty,dynamicProperties); data[i].lvl = level; this.shapes.push(data[i].sh); this.addShapeToModifiers(data[i]); jLen = this.stylesList.length; for(j=0;j=0;i-=1){ this.shapeModifiers[i].processShapes(this.firstFrame); } }; IShapeElement.prototype.renderFrame = function(parentMatrix){ var renderParent = this._parent.renderFrame.call(this,parentMatrix); if(renderParent===false){ this.hide(); return; } this.globalToLocal([0,0,0]); if(this.hidden){ this.layerElement.style.display = 'block'; this.hidden = false; } this.renderModifiers(); this.renderShape(null,null,true, null); }; IShapeElement.prototype.hide = function(){ if(!this.hidden){ this.layerElement.style.display = 'none'; var i, len = this.stylesList.length; for(i=len-1;i>=0;i-=1){ if(this.stylesList[i].ld !== '0'){ this.stylesList[i].ld = '0'; this.stylesList[i].pElem.style.display = 'none'; if(this.stylesList[i].pElem.parentNode){ this.stylesList[i].parent = this.stylesList[i].pElem.parentNode; //this.stylesList[i].pElem.parentNode.removeChild(this.stylesList[i].pElem); } } } this.hidden = true; } }; IShapeElement.prototype.renderShape = function(items,data,isMain, container){ var i, len; if(!items){ items = this.shapesData; len = this.stylesList.length; for(i=0;i=0;i-=1){ ty = items[i].ty; if(ty == 'tr'){ if(this.firstFrame || data[i].transform.op.mdf && container){ container.setAttribute('opacity',data[i].transform.op.v); } if(this.firstFrame || data[i].transform.mProps.mdf && container){ container.setAttribute('transform',data[i].transform.mProps.v.to2dCSS()); } }else if(ty == 'sh' || ty == 'el' || ty == 'rc' || ty == 'sr'){ this.renderPath(items[i],data[i]); }else if(ty == 'fl'){ this.renderFill(items[i],data[i]); }else if(ty == 'gf'){ this.renderGradient(items[i],data[i]); }else if(ty == 'gs'){ this.renderGradient(items[i],data[i]); this.renderStroke(items[i],data[i]); }else if(ty == 'st'){ this.renderStroke(items[i],data[i]); }else if(ty == 'gr'){ this.renderShape(items[i].it,data[i].it,false, data[i].gr); }else if(ty == 'tm'){ // } } if(isMain) { len = this.stylesList.length; for (i = 0; i < len; i += 1) { if (this.stylesList[i].ld === '0') { this.stylesList[i].ld = '1'; this.stylesList[i].pElem.style.display = 'block'; //this.stylesList[i].parent.appendChild(this.stylesList[i].pElem); } if (this.stylesList[i].mdf || this.firstFrame) { this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d); if(this.stylesList[i].msElem){ this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d); } } } if (this.firstFrame) { this.firstFrame = false; } } }; IShapeElement.prototype.renderPath = function(pathData,viewData){ var len, i, j, jLen,pathStringTransformed,redraw,pathNodes,l, lLen = viewData.elements.length; var lvl = viewData.lvl; for(l=0;l 0) { redraw = viewData.transformers[k].mProps.mdf || redraw; props = viewData.transformers[k].mProps.v.props; mat.transform(props[0],props[1],props[2],props[3],props[4],props[5],props[6],props[7],props[8],props[9],props[10],props[11],props[12],props[13],props[14],props[15]); iterations --; k --; } if(redraw){ for(j=0;j= 1 ? 0.99 : viewData.h.v <= -1 ? -0.99:viewData.h.v; var dist = rad*percent; var x = Math.cos(ang + viewData.a.v)*dist + pt1[0]; var y = Math.sin(ang + viewData.a.v)*dist + pt1[1]; gfill.setAttribute('fx',x); gfill.setAttribute('fy',y); if(opFill){ opFill.setAttribute('fx',x); opFill.setAttribute('fy',y); } } //gfill.setAttribute('fy','200'); } }; IShapeElement.prototype.renderStroke = function(styleData,viewData){ var styleElem = viewData.style; //TODO fix dashes var d = viewData.d; var dasharray,dashoffset; if(d && d.k && (d.mdf || this.firstFrame)){ styleElem.pElem.setAttribute('stroke-dasharray', d.dasharray); ////styleElem.pElem.style.strokeDasharray = d.dasharray; styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset); ////styleElem.pElem.style.strokeDashoffset = d.dashoffset; } if(viewData.c && (viewData.c.mdf || this.firstFrame)){ styleElem.pElem.setAttribute('stroke','rgb('+bm_floor(viewData.c.v[0])+','+bm_floor(viewData.c.v[1])+','+bm_floor(viewData.c.v[2])+')'); ////styleElem.pElem.style.stroke = 'rgb('+bm_floor(viewData.c.v[0])+','+bm_floor(viewData.c.v[1])+','+bm_floor(viewData.c.v[2])+')'; } if(viewData.o.mdf || this.firstFrame){ styleElem.pElem.setAttribute('stroke-opacity',viewData.o.v); } if(viewData.w.mdf || this.firstFrame){ styleElem.pElem.setAttribute('stroke-width',viewData.w.v); if(styleElem.msElem){ styleElem.msElem.setAttribute('stroke-width',viewData.w.v); } ////styleElem.pElem.style.strokeWidth = viewData.w.v; } }; IShapeElement.prototype.destroy = function(){ this._parent.destroy.call(this._parent); this.shapeData = null; this.viewData = null; this.parentContainer = null; this.placeholder = null; }; function ISolidElement(data,parentContainer,globalData,comp, placeholder){ this._parent.constructor.call(this,data,parentContainer,globalData,comp, placeholder); } createElement(SVGBaseElement, ISolidElement); ISolidElement.prototype.createElements = function(){ this._parent.createElements.call(this); var rect = document.createElementNS(svgNS,'rect'); ////rect.style.width = this.data.sw; ////rect.style.height = this.data.sh; ////rect.style.fill = this.data.sc; rect.setAttribute('width',this.data.sw); rect.setAttribute('height',this.data.sh); rect.setAttribute('fill',this.data.sc); this.layerElement.appendChild(rect); this.innerElem = rect; if(this.data.ln){ this.layerElement.setAttribute('id',this.data.ln); } if(this.data.cl){ this.layerElement.setAttribute('class',this.data.cl); } }; ISolidElement.prototype.hide = IImageElement.prototype.hide; ISolidElement.prototype.renderFrame = IImageElement.prototype.renderFrame; ISolidElement.prototype.destroy = IImageElement.prototype.destroy; var animationManager = (function(){ var moduleOb = {}; var registeredAnimations = []; var initTime = 0; var len = 0; var idled = true; var playingAnimationsNum = 0; function removeElement(ev){ var i = 0; var animItem = ev.target; while(i=0;i-=1){ registeredAnimations[i].animation.destroy(animation); } } function searchAnimations(animationData, standalone, renderer){ var animElements = document.getElementsByClassName('bodymovin'); var i, len = animElements.length; for(i=0;i this.animationData.op){ this.animationData.op = data.op; this.totalFrames = Math.floor(data.op - this.animationData.ip); this.animationData.tf = this.totalFrames; } var layers = this.animationData.layers; var i, len = layers.length; var newLayers = data.layers; var j, jLen = newLayers.length; for(j=0;j this.timeCompleted){ this.currentFrame = this.timeCompleted; } this.trigger('enterFrame'); this.renderFrame(); }; AnimationItem.prototype.renderFrame = function () { if(this.isLoaded === false){ return; } //console.log('this.currentFrame:',this.currentFrame + this.firstFrame); this.renderer.renderFrame(this.currentFrame + this.firstFrame); }; AnimationItem.prototype.play = function (name) { if(name && this.name != name){ return; } if(this.isPaused === true){ this.isPaused = false; if(this._idle){ this._idle = false; this.trigger('_active'); } } }; AnimationItem.prototype.pause = function (name) { if(name && this.name != name){ return; } if(this.isPaused === false){ this.isPaused = true; if(!this.pendingSegment){ this._idle = true; this.trigger('_idle'); } } }; AnimationItem.prototype.togglePause = function (name) { if(name && this.name != name){ return; } if(this.isPaused === true){ this.play(); }else{ this.pause(); } }; AnimationItem.prototype.stop = function (name) { if(name && this.name != name){ return; } this.pause(); this.currentFrame = this.currentRawFrame = 0; this.playCount = 0; this.gotoFrame(); }; AnimationItem.prototype.goToAndStop = function (value, isFrame, name) { if(name && this.name != name){ return; } if(isFrame){ this.setCurrentRawFrameValue(value); }else{ this.setCurrentRawFrameValue(value * this.frameModifier); } this.pause(); }; AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) { this.goToAndStop(value, isFrame, name); this.play(); }; AnimationItem.prototype.advanceTime = function (value) { if(this.pendingSegment){ this.pendingSegment = false; this.adjustSegment(this.segments.shift()); if(this.isPaused){ this.play(); } return; } if (this.isPaused === true || this.isLoaded === false) { return; } this.setCurrentRawFrameValue(this.currentRawFrame + value * this.frameModifier); }; AnimationItem.prototype.updateAnimation = function (perc) { this.setCurrentRawFrameValue(this.totalFrames * perc); }; AnimationItem.prototype.moveFrame = function (value, name) { if(name && this.name != name){ return; } this.setCurrentRawFrameValue(this.currentRawFrame+value); }; AnimationItem.prototype.adjustSegment = function(arr){ this.playCount = 0; if(arr[1] < arr[0]){ if(this.frameModifier > 0){ if(this.playSpeed < 0){ this.setSpeed(-this.playSpeed); } else { this.setDirection(-1); } } this.totalFrames = arr[0] - arr[1]; this.firstFrame = arr[1]; this.setCurrentRawFrameValue(this.totalFrames - 0.01); } else if(arr[1] > arr[0]){ if(this.frameModifier < 0){ if(this.playSpeed < 0){ this.setSpeed(-this.playSpeed); } else { this.setDirection(1); } } this.totalFrames = arr[1] - arr[0]; this.firstFrame = arr[0]; this.setCurrentRawFrameValue(0); } this.trigger('segmentStart'); }; AnimationItem.prototype.setSegment = function (init,end) { var pendingFrame = -1; if(this.isPaused) { if (this.currentRawFrame + this.firstFrame < init) { pendingFrame = init; } else if (this.currentRawFrame + this.firstFrame > end) { pendingFrame = end - init - 0.01; } } this.firstFrame = init; this.totalFrames = end - init; if(pendingFrame !== -1) { this.goToAndStop(pendingFrame,true); } } AnimationItem.prototype.playSegments = function (arr,forceFlag) { if(typeof arr[0] === 'object'){ var i, len = arr.length; for(i=0;i= this.totalFrames) { this.checkSegments(); if(this.loop === false){ this.currentRawFrame = this.totalFrames - 0.01; this.gotoFrame(); this.pause(); this.trigger('complete'); return; }else{ this.trigger('loopComplete'); this.playCount += 1; if((this.loop !== true && this.playCount == this.loop) || this.pendingSegment){ this.currentRawFrame = this.totalFrames - 0.01; this.gotoFrame(); this.pause(); this.trigger('complete'); return; } else { this.currentRawFrame = this.currentRawFrame % this.totalFrames; } } } else if (this.currentRawFrame < 0) { this.checkSegments(); this.playCount -= 1; if(this.playCount < 0){ this.playCount = 0; } if(this.loop === false || this.pendingSegment){ this.currentRawFrame = 0; this.gotoFrame(); this.pause(); this.trigger('complete'); return; }else{ this.trigger('loopComplete'); this.currentRawFrame = (this.totalFrames + this.currentRawFrame) % this.totalFrames; this.gotoFrame(); return; } } this.gotoFrame(); }; AnimationItem.prototype.setSpeed = function (val) { this.playSpeed = val; this.updaFrameModifier(); }; AnimationItem.prototype.setDirection = function (val) { this.playDirection = val < 0 ? -1 : 1; this.updaFrameModifier(); }; AnimationItem.prototype.updaFrameModifier = function () { this.frameModifier = this.frameMult * this.playSpeed * this.playDirection; }; AnimationItem.prototype.getPath = function () { return this.path; }; AnimationItem.prototype.getAssetsPath = function (assetData) { var path = ''; if(this.assetsPath){ var imagePath = assetData.p; if(imagePath.indexOf('images/') !== -1){ imagePath = imagePath.split('/')[1]; } path = this.assetsPath + imagePath; } else { path = this.path; path += assetData.u ? assetData.u : ''; path += assetData.p; } return path; }; AnimationItem.prototype.getAssetData = function (id) { var i = 0, len = this.assets.length; while (i < len) { if(id == this.assets[i].id){ return this.assets[i]; } i += 1; } }; AnimationItem.prototype.hide = function () { this.renderer.hide(); }; AnimationItem.prototype.show = function () { this.renderer.show(); }; AnimationItem.prototype.getAssets = function () { return this.assets; }; AnimationItem.prototype.trigger = function(name){ if(this._cbs && this._cbs[name]){ switch(name){ case 'enterFrame': this.triggerEvent(name,new BMEnterFrameEvent(name,this.currentFrame,this.totalFrames,this.frameMult)); break; case 'loopComplete': this.triggerEvent(name,new BMCompleteLoopEvent(name,this.loop,this.playCount,this.frameMult)); break; case 'complete': this.triggerEvent(name,new BMCompleteEvent(name,this.frameMult)); break; case 'segmentStart': this.triggerEvent(name,new BMSegmentStartEvent(name,this.firstFrame,this.totalFrames)); break; case 'destroy': this.triggerEvent(name,new BMDestroyEvent(name,this)); break; default: this.triggerEvent(name); } } if(name === 'enterFrame' && this.onEnterFrame){ this.onEnterFrame.call(this,new BMEnterFrameEvent(name,this.currentFrame,this.totalFrames,this.frameMult)); } if(name === 'loopComplete' && this.onLoopComplete){ this.onLoopComplete.call(this,new BMCompleteLoopEvent(name,this.loop,this.playCount,this.frameMult)); } if(name === 'complete' && this.onComplete){ this.onComplete.call(this,new BMCompleteEvent(name,this.frameMult)); } if(name === 'segmentStart' && this.onSegmentStart){ this.onSegmentStart.call(this,new BMSegmentStartEvent(name,this.firstFrame,this.totalFrames)); } if(name === 'destroy' && this.onDestroy){ this.onDestroy.call(this,new BMDestroyEvent(name,this)); } }; AnimationItem.prototype.addEventListener = _addEventListener; AnimationItem.prototype.removeEventListener = _removeEventListener; AnimationItem.prototype.triggerEvent = _triggerEvent; function CanvasRenderer(animationItem, config){ this.animationItem = animationItem; this.renderConfig = { clearCanvas: (config && config.clearCanvas !== undefined) ? config.clearCanvas : true, context: (config && config.context) || null, progressiveLoad: (config && config.progressiveLoad) || false, preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet' }; this.renderConfig.dpr = (config && config.dpr) || 1; if (this.animationItem.wrapper) { this.renderConfig.dpr = (config && config.dpr) || window.devicePixelRatio || 1; } this.renderedFrame = -1; this.globalData = { frameNum: -1 }; this.contextData = { saved : Array.apply(null,{length:15}), savedOp: Array.apply(null,{length:15}), cArrPos : 0, cTr : new Matrix(), cO : 1 }; var i, len = 15; for(i=0;ielementRel && fillType === 'meet' || animationRelelementRel && fillType === 'slice'))){ this.transformCanvas.tx = (elementWidth-this.transformCanvas.w*(elementHeight/this.transformCanvas.h))/2*this.renderConfig.dpr; } else if(xPos === 'xMax' && ((animationRelelementRel && fillType === 'slice'))){ this.transformCanvas.tx = (elementWidth-this.transformCanvas.w*(elementHeight/this.transformCanvas.h))*this.renderConfig.dpr; } else { this.transformCanvas.tx = 0; } if(yPos === 'YMid' && ((animationRel>elementRel && fillType==='meet') || (animationRelelementRel && fillType==='meet') || (animationRel= 0; i-=1) { this.elements[i].destroy(); } this.elements.length = 0; this.globalData.canvasContext = null; this.animationItem.container = null; this.destroyed = true; }; CanvasRenderer.prototype.renderFrame = function(num){ if((this.renderedFrame == num && this.renderConfig.clearCanvas === true) || this.destroyed || num === null){ return; } this.renderedFrame = num; this.globalData.frameNum = num - this.animationItem.firstFrame; this.globalData.frameId += 1; this.globalData.projectInterface.currentFrame = num; if(this.renderConfig.clearCanvas === true){ this.reset(); this.canvasContext.save(); //this.canvasContext.canvas.width = this.canvasContext.canvas.width; this.canvasContext.clearRect(this.transformCanvas.tx, this.transformCanvas.ty, this.transformCanvas.w*this.transformCanvas.sx, this.transformCanvas.h*this.transformCanvas.sy); }else{ this.save(); } this.ctxTransform(this.transformCanvas.props); this.canvasContext.beginPath(); this.canvasContext.rect(0,0,this.transformCanvas.w,this.transformCanvas.h); this.canvasContext.closePath(); this.canvasContext.clip(); //console.log('--------'); //console.log('NEW: ',num); var i, len = this.layers.length; if(!this.completeLayers){ this.checkLayers(num); } for (i = 0; i < len; i++) { if(this.completeLayers || this.elements[i]){ this.elements[i].prepareFrame(num - this.layers[i].st); } } for (i = len - 1; i >= 0; i-=1) { if(this.completeLayers || this.elements[i]){ this.elements[i].renderFrame(); } } if(this.renderConfig.clearCanvas !== true){ this.restore(); } else { this.canvasContext.restore(); } }; CanvasRenderer.prototype.buildItem = function(pos){ var elements = this.elements; if(elements[pos] || this.layers[pos].ty == 99){ return; } var element = this.createItem(this.layers[pos], this,this.globalData); elements[pos] = element; element.initExpressions(); if(this.layers[pos].ty === 0){ element.resize(this.globalData.transformCanvas); } }; CanvasRenderer.prototype.checkPendingElements = function(){ while(this.pendingElements.length){ var element = this.pendingElements.pop(); element.checkParenting(); } }; CanvasRenderer.prototype.hide = function(){ this.animationItem.container.style.display = 'none'; }; CanvasRenderer.prototype.show = function(){ this.animationItem.container.style.display = 'block'; }; CanvasRenderer.prototype.searchExtraCompositions = function(assets){ var i, len = assets.length; var floatingContainer = document.createElementNS(svgNS,'g'); for(i=0;ielementRel){ sx = elementWidth/(this.globalData.compSize.w); sy = elementWidth/(this.globalData.compSize.w); tx = 0; ty = ((elementHeight-this.globalData.compSize.h*(elementWidth/this.globalData.compSize.w))/2); }else{ sx = elementHeight/(this.globalData.compSize.h); sy = elementHeight/(this.globalData.compSize.h); tx = (elementWidth-this.globalData.compSize.w*(elementHeight/this.globalData.compSize.h))/2; ty = 0; } this.resizerElem.style.transform = this.resizerElem.style.webkitTransform = 'matrix3d(' + sx + ',0,0,0,0,'+sy+',0,0,0,0,1,0,'+tx+','+ty+',0,1)'; }; HybridRenderer.prototype.renderFrame = SVGRenderer.prototype.renderFrame; HybridRenderer.prototype.hide = function(){ this.resizerElem.style.display = 'none'; }; HybridRenderer.prototype.show = function(){ this.resizerElem.style.display = 'block'; }; HybridRenderer.prototype.initItems = function(){ this.buildAllItems(); if(this.camera){ this.camera.setup(); } else { var cWidth = this.globalData.compSize.w; var cHeight = this.globalData.compSize.h; var i, len = this.threeDElements.length; for(i=0;i= 0; i -= 1 ){ if(this.completeLayers || this.elements[i]){ this.elements[i].renderFrame(); } } } if(this.data.hasMask){ this.globalData.renderer.restore(true); } if(this.firstFrame){ this.firstFrame = false; } this.parentGlobalData.renderer.save(); this.parentGlobalData.renderer.ctxTransform(this.finalTransform.mat.props); this.parentGlobalData.renderer.ctxOpacity(this.finalTransform.opacity); this.parentGlobalData.renderer.canvasContext.drawImage(this.canvas,0,0,this.data.w,this.data.h); this.parentGlobalData.renderer.restore(); if(this.globalData.mdf){ this.reset(); } }; CVCompElement.prototype.setElements = function(elems){ this.elements = elems; }; CVCompElement.prototype.getElements = function(){ return this.elements; }; CVCompElement.prototype.destroy = function(){ var i,len = this.layers.length; for( i = len - 1; i >= 0; i -= 1 ){ this.elements[i].destroy(); } this.layers = null; this.elements = null; this._parent.destroy.call(this._parent); }; CVCompElement.prototype.checkLayers = CanvasRenderer.prototype.checkLayers; CVCompElement.prototype.buildItem = CanvasRenderer.prototype.buildItem; CVCompElement.prototype.checkPendingElements = CanvasRenderer.prototype.checkPendingElements; CVCompElement.prototype.addPendingElement = CanvasRenderer.prototype.addPendingElement; CVCompElement.prototype.buildAllItems = CanvasRenderer.prototype.buildAllItems; CVCompElement.prototype.createItem = CanvasRenderer.prototype.createItem; CVCompElement.prototype.createImage = CanvasRenderer.prototype.createImage; CVCompElement.prototype.createComp = CanvasRenderer.prototype.createComp; CVCompElement.prototype.createSolid = CanvasRenderer.prototype.createSolid; CVCompElement.prototype.createShape = CanvasRenderer.prototype.createShape; CVCompElement.prototype.createText = CanvasRenderer.prototype.createText; CVCompElement.prototype.createBase = CanvasRenderer.prototype.createBase; CVCompElement.prototype.buildElementParenting = CanvasRenderer.prototype.buildElementParenting; function CVImageElement(data, comp,globalData){ this.assetData = globalData.getAssetData(data.refId); this._parent.constructor.call(this,data, comp,globalData); this.globalData.addPendingElement(); } createElement(CVBaseElement, CVImageElement); CVImageElement.prototype.createElements = function(){ var imageLoaded = function(){ this.globalData.elementLoaded(); if(this.assetData.w !== this.img.width || this.assetData.h !== this.img.height){ var canvas = document.createElement('canvas'); canvas.width = this.assetData.w; canvas.height = this.assetData.h; var ctx = canvas.getContext('2d'); var imgW = this.img.width; var imgH = this.img.height; var imgRel = imgW / imgH; var canvasRel = this.assetData.w/this.assetData.h; var widthCrop, heightCrop; if(imgRel>canvasRel){ heightCrop = imgH; widthCrop = heightCrop*canvasRel; } else { widthCrop = imgW; heightCrop = widthCrop/canvasRel; } ctx.drawImage(this.img,(imgW-widthCrop)/2,(imgH-heightCrop)/2,widthCrop,heightCrop,0,0,this.assetData.w,this.assetData.h); this.img = canvas; } }.bind(this); var imageFailed = function(){ this.failed = true; this.globalData.elementLoaded(); }.bind(this); this.img = new Image(); this.img.addEventListener('load', imageLoaded, false); this.img.addEventListener('error', imageFailed, false); var assetPath = this.globalData.getAssetsPath(this.assetData); this.img.src = assetPath; this._parent.createElements.call(this); }; CVImageElement.prototype.renderFrame = function(parentMatrix){ if(this.failed){ return; } if(this._parent.renderFrame.call(this,parentMatrix)===false){ return; } var ctx = this.canvasContext; this.globalData.renderer.save(); var finalMat = this.finalTransform.mat.props; this.globalData.renderer.ctxTransform(finalMat); this.globalData.renderer.ctxOpacity(this.finalTransform.opacity); ctx.drawImage(this.img,0,0); this.globalData.renderer.restore(this.data.hasMask); if(this.firstFrame){ this.firstFrame = false; } }; CVImageElement.prototype.destroy = function(){ this.img = null; this._parent.destroy.call(this._parent); }; function CVMaskElement(data,element){ this.data = data; this.element = element; this.dynamicProperties = []; this.masksProperties = this.data.masksProperties; this.viewData = new Array(this.masksProperties.length); var i, len = this.masksProperties.length; for (i = 0; i < len; i++) { this.viewData[i] = ShapePropertyFactory.getShapeProp(this.element,this.masksProperties[i],3,this.dynamicProperties,null); } } CVMaskElement.prototype.getMaskProperty = function(pos){ return this.viewData[pos]; }; CVMaskElement.prototype.prepareFrame = function(num){ var i, len = this.dynamicProperties.length; for(i=0;i=0;i-=1){ if(arr[i].ty == 'fl' || arr[i].ty == 'st'){ styleElem = { type: arr[i].ty, elements: [] }; data[i] = {}; if(arr[i].ty == 'fl' || arr[i].ty == 'st'){ data[i].c = PropertyFactory.getProp(this,arr[i].c,1,255,dynamicProperties); if(!data[i].c.k){ styleElem.co = 'rgb('+bm_floor(data[i].c.v[0])+','+bm_floor(data[i].c.v[1])+','+bm_floor(data[i].c.v[2])+')'; } } data[i].o = PropertyFactory.getProp(this,arr[i].o,0,0.01,dynamicProperties); if(arr[i].ty == 'st') { styleElem.lc = this.lcEnum[arr[i].lc] || 'round'; styleElem.lj = this.ljEnum[arr[i].lj] || 'round'; if(arr[i].lj == 1) { styleElem.ml = arr[i].ml; } data[i].w = PropertyFactory.getProp(this,arr[i].w,0,null,dynamicProperties); if(!data[i].w.k){ styleElem.wi = data[i].w.v; } if(arr[i].d){ var d = PropertyFactory.getDashProp(this,arr[i].d,'canvas',dynamicProperties); data[i].d = d; if(!data[i].d.k){ styleElem.da = data[i].d.dasharray; styleElem.do = data[i].d.dashoffset; } } } else { styleElem.r = arr[i].r === 2 ? 'evenodd' : 'nonzero'; } this.stylesList.push(styleElem); data[i].style = styleElem; ownArrays.push(data[i].style); }else if(arr[i].ty == 'gr'){ data[i] = { it: [] }; this.searchShapes(arr[i].it,data[i].it,dynamicProperties); }else if(arr[i].ty == 'tr'){ data[i] = { transform : { mat: new Matrix(), opacity: 1, matMdf:false, opMdf:false, op: PropertyFactory.getProp(this,arr[i].o,0,0.01,dynamicProperties), mProps: PropertyFactory.getProp(this,arr[i],2,null,dynamicProperties) }, elements: [] }; }else if(arr[i].ty == 'sh' || arr[i].ty == 'rc' || arr[i].ty == 'el' || arr[i].ty == 'sr'){ data[i] = { nodes:[], trNodes:[], tr:[0,0,0,0,0,0] }; var ty = 4; if(arr[i].ty == 'rc'){ ty = 5; }else if(arr[i].ty == 'el'){ ty = 6; }else if(arr[i].ty == 'sr'){ ty = 7; } data[i].sh = ShapePropertyFactory.getShapeProp(this,arr[i],ty,dynamicProperties); this.shapes.push(data[i].sh); this.addShapeToModifiers(data[i]); jLen = this.stylesList.length; var hasStrokes = false, hasFills = false; for(j=0;j=0;i-=1){ if(items[i].ty == 'tr'){ groupTransform = data[i].transform; var mtArr = data[i].transform.mProps.v.props; groupTransform.matMdf = groupTransform.mProps.mdf; groupTransform.opMdf = groupTransform.op.mdf; groupMatrix = groupTransform.mat; groupMatrix.cloneFromProps(mtArr); if(parentTransform){ var props = parentTransform.mat.props; groupTransform.opacity = parentTransform.opacity; groupTransform.opacity *= data[i].transform.op.v; groupTransform.matMdf = parentTransform.matMdf ? true : groupTransform.matMdf; groupTransform.opMdf = parentTransform.opMdf ? true : groupTransform.opMdf; groupMatrix.transform(props[0],props[1],props[2],props[3],props[4],props[5],props[6],props[7],props[8],props[9],props[10],props[11],props[12],props[13],props[14],props[15]); }else{ groupTransform.opacity = groupTransform.op.o; } }else if(items[i].ty == 'sh' || items[i].ty == 'el' || items[i].ty == 'rc' || items[i].ty == 'sr'){ this.renderPath(items[i],data[i],groupTransform); }else if(items[i].ty == 'fl'){ this.renderFill(items[i],data[i],groupTransform); }else if(items[i].ty == 'st'){ this.renderStroke(items[i],data[i],groupTransform); }else if(items[i].ty == 'gr'){ this.renderShape(groupTransform,items[i].it,data[i].it); }else if(items[i].ty == 'tm'){ // } } if(!isMain){ return; } len = this.stylesList.length; var j, jLen, k, kLen,elems,nodes, renderer = this.globalData.renderer, ctx = this.globalData.canvasContext, type; renderer.save(); renderer.ctxTransform(this.finalTransform.mat.props); for(i=0;i= nextKeyData.t - offsetTime){ if(keyData.h){ keyData = nextKeyData; } break; } if((nextKeyData.t - offsetTime) > frameNum){ break; } if(i < len - 1){ i += dir; }else{ flag = false; } } var k, kLen,perc,jLen, j = 0, fnc; if (keyData.to) { if (!keyData.bezierData) { bez.buildBezierData(keyData); } var bezierData = keyData.bezierData; if (frameNum >= nextKeyData.t-offsetTime || frameNum < keyData.t-offsetTime) { var ind = frameNum >= nextKeyData.t-offsetTime ? bezierData.points.length - 1 : 0; kLen = bezierData.points[ind].point.length; for(k = 0; k < kLen; k += 1){ retVal[k] = bezierData.points[ind].point[k]; } } else { if (keyData.__fnct) { fnc = keyData.__fnct; } else { //fnc = bez.getEasingCurve(keyData.o.x,keyData.o.y,keyData.i.x,keyData.i.y,keyData.n); fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get; keyData.__fnct = fnc; } perc = fnc((frameNum - (keyData.t - offsetTime)) / ((nextKeyData.t - offsetTime) - (keyData.t - offsetTime))); var distanceInLine = bezierData.segmentLength * perc; var segmentPerc; var addedLength = 0; dir = 1; flag = true; jLen = bezierData.points.length; while(flag) { addedLength += bezierData.points[j].partialLength*dir; if (distanceInLine === 0 || perc === 0 || j == bezierData.points.length - 1) { kLen = bezierData.points[j].point.length; for (k = 0; k < kLen; k += 1) { retVal[k] = bezierData.points[j].point[k]; } break; } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j+1].partialLength){ segmentPerc = (distanceInLine - addedLength) / (bezierData.points[j + 1].partialLength); kLen = bezierData.points[j].point.length; for (k = 0; k < kLen; k += 1) { retVal[k] = bezierData.points[j].point[k] + (bezierData.points[j+1].point[k] - bezierData.points[j].point[k]) * segmentPerc; } break; } if (j < jLen - 1 && dir == 1 || j > 0 && dir == -1) { j += dir; } else { flag = false; } } } } else { var outX,outY,inX,inY, isArray = false, keyValue; len = keyData.s.length; for(i=0;i= nextKeyData.t-offsetTime){ perc = 1; }else if(frameNum < keyData.t-offsetTime){ perc = 0; }else{ perc = fnc((frameNum-(keyData.t-offsetTime))/((nextKeyData.t-offsetTime)-(keyData.t-offsetTime))); } } if(this.sh && keyData.h !== 1){ var initP = keyData.s[i]; var endP = keyData.e[i]; if(initP-endP < -180){ initP += 360; } else if(initP-endP > 180){ initP -= 360; } keyValue = initP+(endP-initP)*perc; } else { keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i]+(keyData.e[i]-keyData.s[i])*perc; } if(len === 1){ retVal = keyValue; }else{ retVal[i] = keyValue; } } } return retVal; } function getVelocityAtTime(frameNum) { if(this.vel !== undefined){ return this.vel; } var delta = -0.01; //frameNum += this.elem.data.st; var v1 = this.getValueAtTime(frameNum, 0); var v2 = this.getValueAtTime(frameNum + delta, 0); var velocity; if(v1.length){ velocity = Array.apply(null,{length:v1.length}); var i; for(i=0;i max){ var mm = max; max = min; min = mm; } return Math.min(Math.max(num, min), max); } function radiansToDegrees(val) { return val/degToRads; } var radians_to_degrees = radiansToDegrees; function degreesToRadians(val) { return val*degToRads; } var degrees_to_radians = radiansToDegrees; var helperLengthArray = [0,0,0,0,0,0]; function length(arr1,arr2){ if(typeof arr1 === "number"){ arr2 = arr2 || 0; return Math.abs(arr1 - arr2); } if(!arr2){ arr2 = helperLengthArray; } var i,len = Math.min(arr1.length,arr2.length); var addedLength = 0; for(i=0;i 0.5 ? d / (2 - max - min) : d / (max + min); switch(max){ case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } return [h, s, l,val[3]]; } function hslToRgb(val){ var h = val[0]; var s = val[1]; var l = val[2]; var r, g, b; if(s == 0){ r = g = b = l; // achromatic }else{ function hue2rgb(p, q, t){ if(t < 0) t += 1; if(t > 1) t -= 1; if(t < 1/6) return p + (q - p) * 6 * t; if(t < 1/2) return q; if(t < 2/3) return p + (q - p) * (2/3 - t) * 6; return p; } var q = l < 0.5 ? l * (1 + s) : l + s - l * s; var p = 2 * l - q; r = hue2rgb(p, q, h + 1/3); g = hue2rgb(p, q, h); b = hue2rgb(p, q, h - 1/3); } return [r, g , b, val[3]]; } function linear(t, tMin, tMax, value1, value2){ if(value1 === undefined || value2 === undefined){ return linear(t,0,1,tMin,tMax); } if(t <= tMin) { return value1; }else if(t >= tMax){ return value2; } var perc = tMax === tMin ? 0 : (t-tMin)/(tMax-tMin); if(!value1.length){ return value1 + (value2-value1)*perc; } var i, len = value1.length; var arr = Array.apply( null, { length: len } ); for(i=0;i=firstKeyFrame){ return this.pv; }else{ var cycleDuration, lastKeyFrame; if(!durationFlag){ if(!duration || duration > keyframes.length - 1){ duration = keyframes.length - 1; } lastKeyFrame = keyframes[duration].t; cycleDuration = lastKeyFrame - firstKeyFrame; } else { if(!duration){ cycleDuration = Math.max(0,this.elem.data.op - firstKeyFrame); } else { cycleDuration = Math.abs(elem.comp.globalData.frameRate*duration); } lastKeyFrame = firstKeyFrame + cycleDuration; } var i, len, ret; if(type === 'pingpong') { var iterations = Math.floor((firstKeyFrame - currentFrame)/cycleDuration); if(iterations % 2 === 0){ return this.getValueAtTime(((firstKeyFrame - currentFrame)%cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); } } else if(type === 'offset'){ var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0); var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0); var current = this.getValueAtTime((cycleDuration - (firstKeyFrame - currentFrame)%cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); var repeats = Math.floor((firstKeyFrame - currentFrame)/cycleDuration)+1; if(this.pv.length){ ret = new Array(initV.length); len = ret.length; for(i=0;i keyframes.length - 1){ duration = keyframes.length - 1; } firstKeyFrame = keyframes[keyframes.length - 1 - duration].t; cycleDuration = lastKeyFrame - firstKeyFrame; } else { if(!duration){ cycleDuration = Math.max(0,lastKeyFrame - this.elem.data.ip); } else { cycleDuration = Math.abs(lastKeyFrame - elem.comp.globalData.frameRate*duration); } firstKeyFrame = lastKeyFrame - cycleDuration; } var i, len, ret; if(type === 'pingpong') { var iterations = Math.floor((currentFrame - firstKeyFrame)/cycleDuration); if(iterations % 2 !== 0){ return this.getValueAtTime((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); } } else if(type === 'offset'){ var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0); var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0); var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); var repeats = Math.floor((currentFrame - firstKeyFrame)/cycleDuration); if(this.pv.length){ ret = new Array(initV.length); len = ret.length; for(i=0;idata.k[i].t && time data.k[i+1].t - time){ index = i + 2; keyTime = data.k[i+1].t; } else { index = i + 1; keyTime = data.k[i].t; } break; } } if(index === -1){ index = i + 1; keyTime = data.k[i].t; } } var ob = {}; ob.index = index; ob.time = keyTime/elem.comp.globalData.frameRate; return ob; } function key(ind){ if(!data.k.length || typeof(data.k[0]) === 'number'){ return {time:0}; } ind -= 1; var ob = { time: data.k[ind].t/elem.comp.globalData.frameRate }; var arr; if(ind === data.k.length - 1 && !data.k[ind].h){ arr = data.k[ind-1].e; }else{ arr = data.k[ind].s; } var i, len = arr.length; for(i=0;i 1){ defaultCurveSegments = value; } if(defaultCurveSegments >= 50){ roundValues(false); }else{ roundValues(true); } } function installPlugin(type,plugin){ if(type==='expressions'){ expressionsPlugin = plugin; } } function getFactory(name){ switch(name){ case "propertyFactory": return PropertyFactory;case "shapePropertyFactory": return ShapePropertyFactory; case "matrix": return Matrix; } } bodymovinjs.play = play; bodymovinjs.pause = pause; bodymovinjs.togglePause = togglePause; bodymovinjs.setSpeed = setSpeed; bodymovinjs.setDirection = setDirection; bodymovinjs.stop = stop; bodymovinjs.moveFrame = moveFrame; bodymovinjs.searchAnimations = searchAnimations; bodymovinjs.registerAnimation = registerAnimation; bodymovinjs.loadAnimation = loadAnimation; bodymovinjs.setSubframeRendering = setSubframeRendering; bodymovinjs.resize = resize; bodymovinjs.start = start; bodymovinjs.goToAndStop = goToAndStop; bodymovinjs.destroy = destroy; bodymovinjs.setQuality = setQuality; bodymovinjs.installPlugin = installPlugin; bodymovinjs.__getFactory = getFactory; bodymovinjs.version = '4.6.3'; function checkReady(){ if (document.readyState === "complete") { clearInterval(readyStateCheckInterval); searchAnimations(); } } function getQueryVariable(variable) { var vars = queryString.split('&'); for (var i = 0; i < vars.length; i++) { var pair = vars[i].split('='); if (decodeURIComponent(pair[0]) == variable) { return decodeURIComponent(pair[1]); } } } var standalone = '__[STANDALONE]__'; var animationData = '__[ANIMATIONDATA]__'; var renderer = ''; if(standalone) { var scripts = document.getElementsByTagName('script'); var index = scripts.length - 1; var myScript = scripts[index]; var queryString = myScript.src.replace(/^[^\?]+\??/,''); renderer = getQueryVariable('renderer'); } var readyStateCheckInterval = setInterval(checkReady, 100); return bodymovinjs; }));