// from https://github.com/Alhadis/Accordion (function(){ "use strict"; var touchEnabled = "ontouchstart" in document.documentElement; var pressEvent = touchEnabled ? "touchend" : "click"; var each = [].forEach; // Name of the onTransitionEnd event supported by this browser var transitionEnd = (function(){ for(var names = "transitionend webkitTransitionEnd oTransitionEnd otransitionend".split(" "), i = 0; i < 4; ++i) if("on"+names[i].toLowerCase() in window) return names[i]; return names[0]; }()); /** * Conditionally add or remove a token from a token-list. * * @param {DOMTokenList} list * @param {String} token * @param {Boolean} enabled */ function setToken(list, token, enabled){ enabled ? list.add(token) : list.remove(token); } /** * Stop a function from firing too quickly. * * Returns a copy of the original function that runs only after the designated * number of milliseconds have elapsed. Useful for throttling onResize handlers. * * @param {Number} limit - Threshold to stall execution by, in milliseconds. * @param {Boolean} soon - If TRUE, will call the function *before* the threshold's elapsed, rather than after. * @return {Function} */ function debounce(fn, limit, soon){ var limit = limit < 0 ? 0 : limit, started, context, args, timer, delayed = function(){ // Get the time between now and when the function was first fired var timeSince = Date.now() - started; if(timeSince >= limit){ if(!soon) fn.apply(context, args); if(timer) clearTimeout(timer); timer = context = args = null; } else timer = setTimeout(delayed, limit - timeSince); }; // Debounced copy of the original function return function(){ context = this, args = arguments; if(!limit) return fn.apply(context, args); started = Date.now(); if(!timer){ if(soon) fn.apply(context, args); timer = setTimeout(delayed, limit); } }; }; var uniqueID = (function(){ var IDs = {}; var indexes = {}; /** * Generate a unique ID for a DOM element. * * By default, minimalist IDs like "_1" or "_2" are generated using internally * tracked incrementation. Uglier, more collision-proof IDs can be generated by * passing a truthy value to the function's first argument. * * Irrespective of whether values are being generated simply or randomly, the * document tree is always consulted first to ensure a duplicate ID is never * returned. * * @param {String} prefix - Prefix prepended to result. Default: "_" * @param {Boolean} random - Generate collision-proof IDs using random symbols * @param {Number} length - Length of random passwords. Default: 6 * @return {String} */ function uniqueID(prefix, complex, length){ length = +(length || 6); var result = (prefix = prefix || "_"); // Simple IDs if(!complex){ // Set this prefix's starting index if it's not been used yet if(!indexes[prefix]) indexes[prefix] = 0; result += ++indexes[prefix]; } // Uglier/safer IDs else{ var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; chars += chars.toLowerCase(); result += chars[ Math.round(Math.random() * (chars.length - 1)) ]; chars += "0123456789"; while(result.length < length) result += chars[ Math.round(Math.random() * (chars.length - 1))]; } return IDs[result] || document.getElementById(result) ? uniqueID(prefix, complex) : (IDs[result] = true, result); } return uniqueID; }()); // Name of the CSSOM property used by this browser for CSS transforms var cssTransform = (function(n){ s = document.documentElement.style; if((prop = n.toLowerCase()) in s) return prop; for(var prop, s, p = "Webkit Moz Ms O Khtml", p = (p.toLowerCase() + p).split(" "), i = 0; i < 10; ++i) if((prop = p[i]+n) in s) return prop; return ""; }("Transform")); // Whether 3D transforms are supported by this browser var css3DSupported = (function(propName){ var e = document.createElement("div"), s = e.style, v = [["translateY(", ")"], ["translate3d(0,", ",0)"]] try{ s[propName] = v[1].join("1px"); } catch(e){} return v[+!!s[propName]] === v[1]; }(cssTransform)); var folds = []; /** * Represents a single panel of togglable content inside an Accordion. * * @param {Accordion} accordion * @param {HTMLElement} el * @constructor */ var Fold = function(accordion, el){ var THIS = this; var heading = el.firstElementChild; var content = el.lastElementChild; var elClasses = el.classList; var openClass = accordion.openClass; var closeClass = accordion.closeClass; var keysEnabled = !accordion.noKeys; var useBorders = accordion.useBorders; var useTransforms = !accordion.noTransforms && cssTransform; var onToggle = accordion.onToggle; var _disabled = false; var _open, _y, _height, _ariaEnabled; var scrollX, scrollY; var onTouchStart; var onKeyDown; var onPress; Object.defineProperties(THIS, { fit: {value: fit}, // Add or remove relevant ARIA attributes from the fold's elements ariaEnabled: { get: function(){ return _ariaEnabled; }, set: function(input){ if((input = !!input) !== !!_ariaEnabled){ _ariaEnabled = input; // Enable ARIA-attribute management if(input){ heading.setAttribute("role", "tab"); content.setAttribute("role", "tabpanel"); checkIDs(); // Update the attributes that're controlled by .open's setter heading.setAttribute("aria-selected", !!_open); heading.setAttribute("aria-expanded", !!_open); content.setAttribute("aria-hidden", !_open); } // Disabling; remove all relevant attributes else{ heading.removeAttribute("role"); heading.removeAttribute("aria-controls"); heading.removeAttribute("aria-selected"); heading.removeAttribute("aria-expanded"); content.removeAttribute("role"); content.removeAttribute("aria-labelledby"); content.removeAttribute("aria-hidden"); } } } }, // Whether or not the fold's currently opened open: { get: function(){ // Derive the fold's opened state from the DOM if it's not been determined yet if(undefined === _open){ _open = elClasses.contains(openClass); setToken(elClasses, closeClass, !_open); } return _open; }, set: function(input){ if((input = !!input) !== _open){ // If an onToggle callback was specified, run it. Avoid doing anything if it returns false. if("function" === typeof onToggle && false === onToggle.call(null, THIS, input)) return; setToken(elClasses, openClass, input); setToken(elClasses, closeClass, !input); _open = input; // Update ARIA attributes if(_ariaEnabled){ heading.setAttribute("aria-selected", input); heading.setAttribute("aria-expanded", input); content.setAttribute("aria-hidden", !input); } // If this fold was closed when the screen resized, run a full update in case its contents were juggled around if(THIS.needsRefresh){ delete THIS.needsRefresh; accordion.refresh(); } else accordion.update(); // Close other folds if accordion is modal if(accordion.modal && _open){ for(var fold, i = 0, l = accordion.folds.length; i < l; ++i){ if(THIS !== (fold = accordion.folds[i])) fold.open = false; } } } } }, // Whether the fold's been deactivated disabled: { get: function(){ return _disabled }, set: function(input){ if((input = !!input) !== _disabled){ var style = el.style; // Deactivated if(_disabled = input){ style.height = null; useTransforms ? (style[cssTransform] = null) : (style.top = null); touchEnabled && heading.removeEventListener("touchstart", onTouchStart); heading.removeEventListener(pressEvent, onPress); elClasses.remove(openClass, closeClass); if(onKeyDown){ heading.removeEventListener("keydown", onKeyDown); heading.removeAttribute("tabindex"); } if(_ariaEnabled){ THIS.ariaEnabled = false; _ariaEnabled = true; } } // Reactivated else{ style.height = _height + "px"; useTransforms ? style[cssTransform] = css3DSupported ? ("translate3D(0," + _y + "px,0)") : ("translateY(" + _y + "px)") : (style.top = _y + "px"); touchEnabled && heading.addEventListener("touchstart", onTouchStart); heading.addEventListener(pressEvent, onPress); if(onKeyDown){ heading.addEventListener("keydown", onKeyDown); heading.tabIndex = 0; } } } } }, // Vertical position of the fold within an accordion's container y: { get: function(){ if(undefined === _y) return (_y = parseInt(el.style.top) || 0); return _y; }, set: function(input){ if((input = +input) !== _y){ _y = input; useTransforms ? el.style[cssTransform] = css3DSupported ? ("translate3D(0," + input + "px,0)") : ("translateY(" + input + "px)") : (el.style.top = input + "px"); } } }, // Height of the fold's outermost container height: { get: function(){ if(undefined === _height){ _height = THIS.headingHeight + content.scrollHeight; el.style.height = _height + "px"; } return _height; }, set: function(input){ if(input && (input = +input) !== _height){ el.style.height = input + "px" _height = input; } } }, // Current height of the fold's heading headingHeight: { get: function(){ return heading.scrollHeight + THIS.heightOffset + (useBorders ? THIS.headingBorder : 0) } }, // Total height consumed by the heading element's CSS borders, if any headingBorder: { get: function(){ return (heading.offsetHeight || 0) - (heading.clientHeight || 0); } }, // Total height of the fold's container element elHeight: { get: function(){ return el.scrollHeight + (useBorders ? THIS.elBorder : 0); } }, // Total height consumed by container element's CSS borders, if any elBorder: { get: function(){ return (el.offsetHeight || 0) - (el.clientHeight || 0); } }, // Whether the fold's container has been resized incorrectly wrongSize: { get: function(){ return THIS.headingHeight + content.scrollHeight !== el.scrollHeight; } } }); THIS.index = folds.push(THIS) - 1; THIS.accordion = accordion; THIS.el = el; THIS.heading = heading; THIS.content = content; THIS.ariaEnabled = !accordion.noAria; THIS.heightOffset = accordion.heightOffset; el.accordionFold = THIS.index; useBorders = "auto" === useBorders ? (0 !== THIS.elBorder + THIS.headingBorder) : useBorders; function checkIDs(){ var headingSuffix = "-heading"; var contentSuffix = "-content"; var elID = el.id; var id; // Neither of the fold's elements have an ID attribute if(!heading.id && !content.id){ id = elID || uniqueID("a"); heading.id = id + headingSuffix; content.id = id + contentSuffix; } // Either the heading or element lack an ID else if(!content.id) content.id = (elID || heading.id) + contentSuffix; else if(!heading.id) heading.id = (elID || content.id) + headingSuffix; // Finally, double-check each element's ID is really unique var $ = function(s){return document.querySelectorAll("#"+s)}; while($(content.id).length > 1 || $(heading.id).length > 1){ id = uniqueID("a"); content.id = id + contentSuffix; heading.id = id + headingSuffix; } // Update ARIA attributes heading.setAttribute("aria-controls", content.id); content.setAttribute("aria-labelledby", heading.id); } // Keyboard navigation if(keysEnabled){ heading.tabIndex = 0; heading.addEventListener("keydown", onKeyDown = function(e){ var key = e.keyCode; var fold; switch(key){ // Spacebar: Toggle case 32: e.preventDefault(); // Fall-through // Enter: Toggle case 13: THIS.open = !THIS.open; if("A" === e.target.tagName) e.preventDefault(); break; // Escape: Clear focus case 27: e.target.blur(); break; // Up arrow: Previous section case 38:{ // Is there a previous sibling to navigate up to? if(fold = THIS.previousFold){ var children = fold.childAccordions; // Is it open, and does it have nested accordions? if(fold.open && children){ var lastAcc; var lastFold; // Locate the deepest/nearest accordion that's currently exposed while(children){ lastAcc = children[children.length - 1]; lastFold = lastAcc.folds[lastAcc.folds.length - 1]; if(!lastFold.open) break; children = lastFold.childAccordions; } lastFold.heading.focus(); } // Nope else fold.heading.focus(); } // Is there a higher level we can jump back up to? else if(accordion.parent) accordion.parentFold.heading.focus(); // There's nothing to move back to, so just let the browser run its usual behaviour else return true; e.preventDefault(); return false; } // Down arrow: Next section case 40:{ var children = THIS.childAccordions; // Is there a nested accordion to jump into? if(THIS.open && children) children[0].folds[0].heading.focus(); // No, there isn't. Is there another sibling to move down to? else if(fold = THIS.nextFold) fold.heading.focus(); // Is there a containing accordion we can navigate back up to? else if(THIS.accordion.parent){ var parent = THIS; while(parent = parent.accordion.parentFold) if(fold = parent.nextFold){ fold.heading.focus(); break; } // Nowhere left to go... if(!parent) return true; } // Nah. Just scroll the window normally, as per browser default else return true; e.preventDefault(); return false; } // Left arrow case 37:{ // Close an opened section if(THIS.open) THIS.open = false; // Switch focus back to parent else if(accordion.parent) accordion.parentFold.heading.focus(); break; } // Right arrow case 39:{ var children = THIS.childAccordions; // Open a closed section if(!THIS.open) THIS.open = true; // Switch focus to a nested accordion else if(children) children[0].folds[0].heading.focus(); break; } } }); } // Listener to record the viewport's scroll offsets at the beginning of a touch touchEnabled && heading.addEventListener("touchstart", onTouchStart = function(e){ scrollX = window.pageXOffset; scrollY = window.pageYOffset; }, {passive: true}); heading.addEventListener(pressEvent, onPress = function(e){ // Pressed on something inside the header if(e.target !== heading && heading.contains(e.target)){ // Cancel fold-toggle if user clicked on an anchor-link if("A" === e.target.tagName && e.target.href) return true; } if(e.type !== "touchend" || (e.cancelable && window.pageXOffset === scrollX && window.pageYOffset === scrollY)){ THIS.open = !THIS.open; e.preventDefault(); } return false; }); /** * Adjust a fold's container to fit its content. */ function fit(){ var height = THIS.headingHeight; if(THIS.open) height += content.scrollHeight; if(useBorders) height += THIS.elBorder; THIS.height = height; } } var accordions = []; var activeAccordions = 0; var lastResizeRate; /** * Represents a column of collapsible content regions. * * @param {HTMLElement} el - Container wrapped around each immediate fold * @param {Object} options - Optional hash of settings * @param {String} options.openClass - CSS class controlling each fold's "open" state * @param {String} options.closeClass - CSS class used to mark a fold as closed * @param {String} options.edgeClass - CSS class toggled based on whether the bottom-edge is visible * @param {String} options.snapClass - CSS class for disabling transitions between window resizes * @param {String} options.enabledClass - CSS class marking an accordion as enabled * @param {String} options.disabledClass - CSS class marking an accordion as disabled * @param {Boolean} options.disabled - Whether to disable the accordion on creation * @param {Boolean} options.modal - Whether to close the current fold when opening another * @param {Boolean} options.noAria - Disable the addition and management of ARIA attributes * @param {Boolean} options.noKeys - Disable keyboard navigation * @param {Boolean} options.noTransforms - Disable CSS transforms; positioning will be used instead * @param {Number} options.heightOffset - Distance to offset each fold by * @param {Boolean} options.useBorders - Consider borders when calculating fold heights * @param {Function} options.onToggle - Callback executed when opening or closing a fold * @constructor */ var Accordion = function(el, options){ var THIS = this; var elClasses = el.classList; var options = options || {}; var edgeClass = (undefined === options.edgeClass ? "edge-visible" : options.edgeClass); var snapClass = (undefined === options.snapClass ? "snap" : options.snapClass); var enabledClass = (undefined === options.enabledClass ? "accordion" : options.enabledClass); var disabledClass = options.disabledClass; var _height, _disabled, _parent, _parentFold, _modal; Object.defineProperties(THIS, { update: {value: update}, updateFold: {value: updateFold}, refresh: {value: refresh}, // Whether the accordion's been deactivated disabled: { get: function(){ return _disabled; }, set: function(input){ if((input = !!input) !== _disabled){ var style = el.style; var folds = THIS.folds; enabledClass && setToken(elClasses, enabledClass, !input); disabledClass && setToken(elClasses, disabledClass, input); // Deactivating if(_disabled = input){ style.height = null; snapClass && elClasses.remove(snapClass); if(edgeClass){ el.removeEventListener(transitionEnd, THIS.onTransitionEnd); elClasses.remove(edgeClass); } for(var i = 0, l = folds.length; i < l; ++i) folds[i].disabled = true; THIS.noAria || el.removeAttribute("role"); --activeAccordions; } // Reactivating else{ for(var i = 0, l = folds.length; i < l; ++i) folds[i].disabled = false; THIS.noAria || el.setAttribute("role", "tablist"); ++activeAccordions; update(); } // If there're no more active accordions, disable the onResize handler if(activeAccordions <= 0){ activeAccordions = 0; Accordion.setResizeRate(false); } // Otherwise, reactivate the onResize handler, assuming it was previously active else if(lastResizeRate) Accordion.setResizeRate(lastResizeRate); } } }, // Get or set the accordion enclosing this one parent: { set: function(input){ _parent = input; }, get: function(){ var result = _parent; if(!result) return null; // Search for the first ancestor that *isn't* disabled while(result){ if(!result.disabled) return result; result = result.parent; } return null; } }, // Get or set the fold of the accordion enclosing this one parentFold: { set: function(input){ _parentFold = input; }, get: function(){ var fold = _parentFold; if(!fold) return null; var accordion = fold.accordion; // Search for the first ancestor that *isn't* disabled while(fold && accordion){ if(!accordion.disabled) return fold; if(accordion = accordion.parent) fold = accordion.parentFold; } return null; } }, // Height of the accordion's container element height: { get: function(){ return _height; }, set: function(input){ if(input && (input = +input) !== _height){ el.style.height = input + "px"; _height = input; } } }, // Whether one of the Accordion's folds has been resized incorrectly wrongSize: { get: function(){ var a = this.folds; var l = a.length; var i = 0; for(; i < l; ++i) if(a[i].wrongSize) return true; if(a = this.childAccordions) for(; i < l; ++i) if(a[i].wrongSize) return true; return false; } }, // Top-level ancestor this accordion's nested inside root: { get: function(){ var result = this; while(result){ if(!result.parent) return result; result = result.parent; } } } }); // Assign options as properties THIS.openClass = options.openClass || "open"; THIS.closeClass = options.closeClass || "closed"; THIS.modal = !!options.modal; THIS.noAria = !!options.noAria; THIS.noKeys = !!options.noKeys; THIS.noTransforms = !!options.noTransforms; THIS.index = accordions.push(THIS) - 1; THIS.heightOffset = +options.heightOffset || 0; THIS.useBorders = undefined === options.useBorders ? "auto" : options.useBorders; THIS.onToggle = options.onToggle; // Create a fold for each immediate descendant of the Accordion's container var folds = []; each.call(el.children, function(i){ var fold = new Fold(THIS, i); folds.push(fold); // Connect the fold to its previous sibling, if it's not the first to be added var prev = folds[folds.length - 2]; if(prev){ prev.nextFold = fold; fold.previousFold = prev; } }); el.accordion = THIS.index; THIS.noAria || el.setAttribute("role", "tablist"); THIS.el = el; THIS.folds = folds; // Add .enabledClass early - it might affect the heights of each fold if(!options.disabled && enabledClass) elClasses.add(enabledClass); update(); // Find out if this accordion's nested inside another var next = el; while((next = next.parentNode) && 1 === next.nodeType){ var fold = Accordion.getFold(next); if(fold){ var accordion = fold.accordion; THIS.parent = accordion; THIS.parentFold = fold; edgeClass && elClasses.remove(edgeClass); (accordion.childAccordions = accordion.childAccordions || []).push(THIS); (fold.childAccordions = fold.childAccordions || []).push(THIS); // Adjust the height of the containing fold's element if(fold.open){ var scrollHeight = fold.el.scrollHeight; var distance = (fold.headingHeight + fold.content.scrollHeight) - scrollHeight || (scrollHeight - fold.el.clientHeight); accordion.updateFold(fold, distance); } break; } } edgeClass && el.addEventListener(transitionEnd, this.onTransitionEnd = function(e){ if(!THIS.parent && e.target === el && "height" === e.propertyName && el.getBoundingClientRect().bottom > window.innerHeight) elClasses.remove(edgeClass); }); this.disabled = !!options.disabled; /** * Internal method to check if an accordion's bottom-edge is visible to the user (or about to be). * * @param {Number} offset * @private */ function edgeCheck(offset){ if(edgeClass){ var box = el.getBoundingClientRect(); var windowEdge = window.innerHeight; // If the bottom-edge is visible (or about to be), enable height animation if(box.bottom + (offset || 0) < windowEdge) elClasses.add(edgeClass) // If the bottom-edge isn't visible anyway, disable height animation immediately else if(box.bottom > windowEdge) elClasses.remove(edgeClass); } } /** * Update the vertical ordinate of each sibling for a particular fold. * * @param {Fold} fold * @param {Number} offset - Pixel distance to adjust by */ function updateFold(fold, offset){ var next = fold; var parentFold = THIS.parentFold; while(next = next.nextFold) next.y += offset; parentFold || edgeCheck(offset); fold.height += offset; THIS.height += offset; parentFold && parentFold.open && THIS.parent.updateFold(parentFold, offset); } /** * Update the height of each fold to fit its content. */ function update(){ var y = 0; var height = 0; var i = 0; var l = folds.length; var parentFold = THIS.parentFold; var fold, diff; for(; i < l; ++i){ fold = folds[i]; fold.y = y; fold.fit(); y += fold.height; height += fold.height; } diff = height - _height; parentFold ? (parentFold.open && THIS.parent.updateFold(parentFold, diff)) : edgeCheck(diff); THIS.height = height; } /** * Recalculate the boundaries of an Accordion and its descendants. * * This method should only be called if the width of a container changes, * or a fold's contents have resized unexpectedly (such as when images load). * * @param {Boolean} allowSnap - Snap folds instantly into place without transitioning */ function refresh(allowSnap){ var snap = allowSnap ? snapClass : false; snap && elClasses.add(snap); THIS.update(); THIS.childAccordions && THIS.childAccordions.forEach(function(a){ a.parentFold.open ? a.refresh(allowSnap) : (a.parentFold.needsRefresh = true); }); snap && setTimeout(function(e){elClasses.remove(snap)}, 20); } } // If IE8PP exists, it means the author wants/needs IE8 support. See also: tinyurl.com/fixIE8-9 if("function" === typeof IE8PP) Accordion = IE8PP(Accordion), Fold = IE8PP(Fold); /** * Alter the rate at which screen-resize events update accordion widths. * * @param {Number} delay - Rate expressed in milliseconds */ Accordion.setResizeRate = function(delay){ var fn = function(e){ for(var a, i = 0, l = accordions.length; i < l; ++i){ a = accordions[i]; a.parent || a.disabled || a.refresh(true); } }; var THIS = Accordion; THIS.onResize && window.removeEventListener("resize", THIS.onResize); // Make sure we weren't passed an explicit value of FALSE, or a negative value if(false !== delay && (delay = +delay || 0) >= 0){ THIS.onResize = delay ? debounce(fn, delay) : fn; window.addEventListener("resize", THIS.onResize); if(delay) lastResizeRate = delay; } } /** * Return the closest (most deeply-nested) accordion enclosing an element. * * @param {Node} node * @return {Accordion} */ Accordion.getAccordion = function(node){ while(node){ if("accordion" in node) return accordions[node.accordion]; node = node.parentNode; if(!node || node.nodeType !== 1) return null; } } /** * Return the closest (most deeply-nested) fold enclosing an element. * * @param {Node} node * @return {Fold} */ Accordion.getFold = function(node){ while(node){ if("accordionFold" in node) return folds[node.accordionFold]; node = node.parentNode; if(!node || node.nodeType !== 1) return null; } } Accordion.setResizeRate(25); // Browser export window.Accordion = Accordion; // CommonJS/Node.js if("object" === typeof module && "object" === typeof module.exports) module.exports.Accordion = Accordion; // AMD/UMD-like systems return Accordion; }()); (function(root, factory) { if (typeof define === "function" && define.amd) { define(function() { return factory(root); }); } else if (typeof module === "object" && module.exports) { module.exports = factory(root); } else { root.bodymovin = factory(root); } }((window || {}), function(window) { var svgNS = "http://www.w3.org/2000/svg"; var locationHref = ''; 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 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 () { 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 = 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){ if(z1 === 0 && z2 === 0 && z3 === 0) { return pointOnLine2D(x1,y1, x2,y2, x3,y3); } var dist1 = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2) + Math.pow(z2 - z1, 2)); var dist2 = Math.sqrt(Math.pow(x3 - x1, 2) + Math.pow(y3 - y1, 2) + Math.pow(z3 - z1, 2)); var dist3 = Math.sqrt(Math.pow(x3 - x2, 2) + Math.pow(y3 - y2, 2) + Math.pow(z3 - z2, 2)); var diffDist; if(dist1 > dist2){ if(dist1 > dist3){ diffDist = dist1 - dist2 - dist3; } else { diffDist = dist3 - dist2 - dist1; } } else if(dist3 > dist2){ diffDist = dist3 - dist2 - dist1; } else { diffDist = dist2 - dist1 - dist3; } return diffDist > -0.0001 && diffDist < 0.0001; } /*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 getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) { var t1 = getDistancePerc(percent,bezierData); var u0 = 1; var u1 = 1 - t1; var ptX = Math.round((u1*u1*u1* pt1[0] + (t1*u1*u1 + u1*t1*u1 + u1*u1*t1)* pt3[0] + (t1*t1*u1 + u1*t1*t1 + t1*u1*t1)*pt4[0] + t1*t1*t1* pt2[0])* 1000) / 1000; var ptY = Math.round((u1*u1*u1* pt1[1] + (t1*u1*u1 + u1*t1*u1 + u1*u1*t1)* pt3[1] + (t1*t1*u1 + u1*t1*t1 + t1*u1*t1)*pt4[1] + t1*t1*t1* pt2[1])* 1000) / 1000; return [ptX, ptY]; } 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 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' || fontArr[i].origin === 2){ // 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= nextKeyData.t - offsetTime){ if(keyData.h){ keyData = nextKeyData; } iterationIndex = 0; break; } if((nextKeyData.t - offsetTime) > frameNum){ iterationIndex = i; break; } if(i < len - 1){ i += 1; }else{ iterationIndex = 0; flag = false; } } var k, kLen,perc,jLen, j, 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){ newValue[k] = bezierData.points[ind].point[k]; } caching._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-offsetTime))/((nextKeyData.t-offsetTime)-(keyData.t-offsetTime))); var distanceInLine = bezierData.segmentLength*perc; var segmentPerc; var addedLength = (caching.lastFrame < frameNum && caching._lastBezierData === bezierData) ? caching._lastAddedLength : 0; j = (caching.lastFrame < frameNum && caching._lastBezierData === bezierData) ? caching._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-offsetTime){ perc = 1; }else if(frameNum < keyData.t-offsetTime){ perc = 0; }else{ if(keyData.o.x.constructor === 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-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){ newValue = keyValue; }else{ newValue[i] = keyValue; } } } return { value: newValue, iterationIndex: iterationIndex } } function getValueAtCurrentTime(){ if(this.elem.globalData.frameId === this.frameId){ return; } this.mdf = false; var frameNum = this.comp.renderedFrame - this.offsetTime; var initTime = this.keyframes[0].t-this.offsetTime; var endTime = this.keyframes[this.keyframes.length- 1].t-this.offsetTime; if(!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))){ var i = this._caching.lastFrame < frameNum ? this._caching.lastIndex : 0; var renderResult = this.interpolateValue(frameNum, i, this.pv, this._caching); this._caching.lastIndex = renderResult.iterationIndex; if(this.pv.constructor === Array){ i = 0; while(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._caching.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]); } } 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); //sh Indicates it needs to be capped between -180 and 180 this.or.sh = true; } 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,this.dynamicProperties); } 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.elem = elem; 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: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 = { getProp: getProp, getDashProp: getDashProp, getTextSelectorProp: getTextSelectorProp, 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; this.setLength(len); 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; } }; ShapePath.prototype.setLength = function(len) { while(this._maxLength < len) { this.doubleArrayLength(); } 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(frameNum, iterationIndex, previousValue, isCurrentRender) { var keyPropS,keyPropE,isHold; if(frameNum < this.keyframes[0].t-this.offsetTime){ keyPropS = this.keyframes[0].s[0]; isHold = true; iterationIndex = 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 = iterationIndex; 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; iterationIndex = 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 = previousValue._length; kLen = keyPropS.i[0].length; var hasModified = false; var vertexValue; for(j=0;j endTime && frameNum > endTime)))){ //// var i = this.lastFrame < frameNum ? this._lastIndex : 0; var renderResult = this.interpolateShape(frameNum, i, this.v, true); //// this._lastIndex = renderResult.iterationIndex; this.mdf = renderResult.hasModified; if(renderResult.hasModified) { this.paths = this.localShapeCollection; } } this.lastFrame = frameNum; this.frameId = this.elem.globalData.frameId; } function getShapeValue(){ return this.v; } function resetShape(){ this.paths = this.localShapeCollection; if(!this.k){ this.mdf = false; } } function ShapeProperty(elem, data, type){ this.__shapeObject = 1; this.comp = elem.comp; this.k = false; this.mdf = false; var pathData = type === 3 ? data.pt.k : data.ks.k; this.v = shape_pool.clone(pathData); this.pv = shape_pool.clone(this.v); this.localShapeCollection = shapeCollection_pool.newShapeCollection(); this.paths = this.localShapeCollection; this.paths.addShape(this.v); this.reset = resetShape; } ShapeProperty.prototype.interpolateShape = interpolateShape; ShapeProperty.prototype.getValue = getShapeValue; function KeyframedShapeProperty(elem,data,type){ this.__shapeObject = 1; this.comp = elem.comp; this.elem = elem; this.offsetTime = elem.data.st; this._lastIndex = 0; this.keyframes = type === 3 ? data.pt.k : data.ks.k; this.k = true; this.kf = true; var i, len = this.keyframes[0].s[0].i.length; var jLen = this.keyframes[0].s[0].i[0].length; this.v = shape_pool.newShape(); this.v.setPathData(this.keyframes[0].s[0].c, len); this.pv = shape_pool.clone(this.v); this.localShapeCollection = shapeCollection_pool.newShapeCollection(); this.paths = this.localShapeCollection; this.paths.addShape(this.v); this.lastFrame = initFrame; this.reset = resetShape; } KeyframedShapeProperty.prototype.getValue = interpolateShapeCurrentTime; KeyframedShapeProperty.prototype.interpolateShape = interpolateShape; var EllShapeProperty = (function(){ var cPoint = roundCorner; function convertEllToPath(){ var p0 = this.p.v[0], p1 = this.p.v[1], s0 = this.s.v[0]/2, s1 = this.s.v[1]/2; if(this.d !== 3){ this.v.v[0][0] = p0; this.v.v[0][1] = p1-s1; this.v.v[1][0] = p0 + s0; this.v.v[1][1] = p1; this.v.v[2][0] = p0; this.v.v[2][1] = p1+s1; this.v.v[3][0] = p0 - s0; this.v.v[3][1] = p1; this.v.i[0][0] = p0 - s0*cPoint; this.v.i[0][1] = p1 - s1; this.v.i[1][0] = p0 + s0; this.v.i[1][1] = p1 - s1*cPoint; this.v.i[2][0] = p0 + s0*cPoint; this.v.i[2][1] = p1 + s1; this.v.i[3][0] = p0 - s0; this.v.i[3][1] = p1 + s1*cPoint; this.v.o[0][0] = p0 + s0*cPoint; this.v.o[0][1] = p1 - s1; this.v.o[1][0] = p0 + s0; this.v.o[1][1] = p1 + s1*cPoint; this.v.o[2][0] = p0 - s0*cPoint; this.v.o[2][1] = p1 + s1; this.v.o[3][0] = p0 - s0; this.v.o[3][1] = p1 - s1*cPoint; }else{ this.v.v[0][0] = p0; this.v.v[0][1] = p1-s1; this.v.v[1][0] = p0 - s0; this.v.v[1][1] = p1; this.v.v[2][0] = p0; this.v.v[2][1] = p1+s1; this.v.v[3][0] = p0 + s0; this.v.v[3][1] = p1; this.v.i[0][0] = p0 + s0*cPoint; this.v.i[0][1] = p1 - s1; this.v.i[1][0] = p0 - s0; this.v.i[1][1] = p1 - s1*cPoint; this.v.i[2][0] = p0 - s0*cPoint; this.v.i[2][1] = p1 + s1; this.v.i[3][0] = p0 + s0; this.v.i[3][1] = p1 + s1*cPoint; this.v.o[0][0] = p0 - s0*cPoint; this.v.o[0][1] = p1 - s1; this.v.o[1][0] = p0 - s0; this.v.o[1][1] = p1 + s1*cPoint; this.v.o[2][0] = p0 + s0*cPoint; this.v.o[2][1] = p1 + s1; this.v.o[3][0] = p0 + s0; this.v.o[3][1] = p1 - s1*cPoint; } } function processKeys(frameNum){ var i, len = this.dynamicProperties.length; if(this.elem.globalData.frameId === this.frameId){ return; } this.mdf = false; this.frameId = this.elem.globalData.frameId; for(i=0;ie){ 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.calculateShapeEdges = function(s, e, shapeLength, addedLength, totalModifierLength) { var segments = [] if(e <= 1){ segments.push({ s: s, e: e }) }else if(s >= 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; } } } else if(this.mdf){ 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(i0){ pos -= 1; //this._elements.unshift(arr.splice(pos,1)[0]); this._elements.unshift(arr[pos]); cont += 1; } if(this.dynamicProperties.length){ this.k = true; dynamicProperties.push(this); }else{ this.getValue(true); } } RepeaterModifier.prototype.resetElements = function(elements){ var i, len = elements.length; for(i = 0; i < len; i += 1) { elements[i]._processed = false; if(elements[i].ty === 'gr'){ this.resetElements(elements[i].it); } } } RepeaterModifier.prototype.cloneElements = function(elements){ var i, len = elements.length; var newElements = JSON.parse(JSON.stringify(elements)); this.resetElements(newElements); return newElements; } RepeaterModifier.prototype.changeGroupRender = function(elements, renderFlag) { var i, len = elements.length; for(i = 0; i < len ; i += 1) { elements[i]._render = renderFlag; if(elements[i].ty === 'gr') { this.changeGroupRender(elements[i].it, renderFlag); } } } RepeaterModifier.prototype.processShapes = function(firstFrame){ if(this.elem.globalData.frameId === this.frameId){ return; } this.frameId = this.elem.globalData.frameId; if(!this.dynamicProperties.length && !firstFrame){ this.mdf = false; } if(this.mdf){ var copies = Math.ceil(this.c.v); if(this._groups.length < copies){ while(this._groups.length < copies){ var group = { it:this.cloneElements(this._elements), ty:'gr' } group.it.push({"a":{"a":0,"ix":1,"k":[0,0]},"nm":"Transform","o":{"a":0,"ix":7,"k":100},"p":{"a":0,"ix":2,"k":[0,0]},"r":{"a":0,"ix":6,"k":0},"s":{"a":0,"ix":3,"k":[100,100]},"sa":{"a":0,"ix":5,"k":0},"sk":{"a":0,"ix":4,"k":0},"ty":"tr"}); this.arr.splice(0,0,group); this._groups.splice(0,0,group); this._currentCopies += 1; } this.elem.reloadShapes(); } var i, cont = 0, renderFlag; for(i = 0; i <= this._groups.length - 1; i += 1){ renderFlag = cont < copies; this._groups[i]._render = renderFlag; this.changeGroupRender(this._groups[i].it, renderFlag); cont += 1; } this._currentCopies = copies; this.elem.firstFrame = true; //// var offset = this.o.v; var offsetModulo = offset%1; var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset); var k; var tMat = this.tr.v.props; var pProps = this.pMatrix.props; var rProps = this.rMatrix.props; var sProps = this.sMatrix.props; this.pMatrix.reset(); this.rMatrix.reset(); this.sMatrix.reset(); this.tMatrix.reset(); this.matrix.reset(); var iteration = 0; if(offset > 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; } } i = this.data.m === 1 ? 0 : this._currentCopies - 1; var dir = this.data.m === 1 ? 1 : -1; cont = this._currentCopies; while(cont){ if(iteration !== 0){ if((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)){ this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false); } 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]); var items = this.elemsData[i].it; var itemsTransform = items[items.length - 1].transform.mProps.v.props; var j, jLen = itemsTransform.length; 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(-alignment[0]*letters[i].an/200, -(alignment[1] * yOff / 100)); 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(-alignment[0]*letters[i].an/200, -alignment[1]*yOff/100, 0); } lineLength += letters[i].l/2; for(j=0;j 1; return this.kf; } TextProperty.prototype.getValue = function() { this.mdf = false; var frameId = this.elem.globalData.frameId; if((frameId === this._frameId || !this.kf) && !this.firstFrame) { return; } var textKeys = this.data.d.k, textDocumentData; var i = 0, len = textKeys.length; while(i <= len - 1) { textDocumentData = textKeys[i].s; if(i === len - 1 || textKeys[i+1].t > frameId){ break; } i += 1; } if(this.keysIndex !== i) { if(!textDocumentData.__complete) { this.completeTextData(textDocumentData); } this.setCurrentData(textDocumentData); this.mdf = this.firstFrame ? false : true; this.pv = this.v = this.currentData.t; this.keysIndex = i; } this._frameId = frameId; } TextProperty.prototype.completeTextData = function(documentData) { documentData.__complete = true; var fontManager = this.elem.globalData.fontManager; var data = this.data; var letters = []; var i, len; var newLineFlag, index = 0, val; var anchorGrouping = data.m.g; var currentSize = 0, currentPos = 0, currentLine = 0, lineWidths = []; var lineWidth = 0; var maxLineWidth = 0; var j, jLen; var fontData = fontManager.getFontByName(documentData.f); var charData, cLength = 0; var styles = fontData.fStyle.split(' '); var fWeight = 'normal', fStyle = 'normal'; len = styles.length; var styleName; for(i=0;i boxWidth && documentData.t.charAt(i) !== ' '){ if(lastSpaceIndex === -1){ len += 1; } else { i = lastSpaceIndex; } documentData.t = documentData.t.substr(0,i) + "\r" + documentData.t.substr(i === lastSpaceIndex ? i + 1 : i); lastSpaceIndex = -1; lineWidth = 0; }else { lineWidth += cLength; lineWidth += trackingOffset; } } len = documentData.t.length; } lineWidth = - trackingOffset; cLength = 0; var uncollapsedSpaces = 0; var currentChar; for (i = 0;i < len ;i += 1) { newLineFlag = false; currentChar = documentData.t.charAt(i); if(currentChar === ' '){ val = '\u00A0'; }else if(currentChar.charCodeAt(0) === 13){ uncollapsedSpaces = 0; lineWidths.push(lineWidth); maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth; lineWidth = - 2 * trackingOffset; val = ''; newLineFlag = true; currentLine += 1; }else{ val = documentData.t.charAt(i); } if(fontManager.chars){ charData = fontManager.getCharData(currentChar, 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); } // if(currentChar === ' '){ uncollapsedSpaces += cLength + trackingOffset; } else { lineWidth += cLength + trackingOffset + uncollapsedSpaces; uncollapsedSpaces = 0; } 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.a, animatorData, letterData; jLen = animators.length; var based, ind, indexes = []; for(j=0;j= 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 13: return this.createCamera(layer); case 99: return null; } return this.createBase(layer); }; BaseRenderer.prototype.createCamera = function(){ throw new Error('You\'re using a 3d camera. Try the html renderer.'); } 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(" + locationHref + "#" + 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.destroy = function(){ this.element = null; this.globalData = null; this.maskElement = null; this.data = null; this.masksProperties = null; }; function BaseElement(){ }; BaseElement.prototype.checkMasks = function(){ if(!this.data.hasMask){ return false; } var i = 0, len = this.data.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 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){ processedPos = this.searchProcessedElement(arr[i]); if(!processedPos){ arr[i]._render = render; } else { itemsData[i] = prevViewData[processedPos - 1]; } if(arr[i].ty == 'fl' || arr[i].ty == 'st' || arr[i].ty == 'gf' || arr[i].ty == 'gs'){ if(!processedPos){ itemsData[i] = this.createStyleElement(arr[i], level, dynamicProperties); } else { itemsData[i].style.closed = false; } if(arr[i]._render){ container.appendChild(itemsData[i].elem); } ownStyles.push(itemsData[i].style); }else if(arr[i].ty == 'gr'){ if(!processedPos){ itemsData[i] = this.createGroupElement(arr[i]); } else { jLen = itemsData[i].it.length; for(j=0;j=0;i-=1){ this.shapeModifiers[i].processShapes(this.firstFrame); } }; IShapeElement.prototype.renderFrame = function(parentMatrix){ //this.reloadShapes(); var renderParent = this._parent.renderFrame.call(this,parentMatrix); if(renderParent===false){ this.hide(); return; } if(this.hidden){ this.layerElement.style.display = 'block'; this.hidden = false; } this.renderModifiers(); var i, len = this.stylesList.length; for(i=0;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, container){ var i, len = items.length - 1; var ty; for(i=len;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, data[i].gr); }else if(ty == 'tm'){ // } } }; IShapeElement.prototype.buildShapeString = function(pathNodes, length, closed, mat) { var i, shapeString = ''; for(i = 1; i < length; i += 1) { if (i === 1) { shapeString += " M" + mat.applyToPointStringified(pathNodes.v[0][0], pathNodes.v[0][1]); } shapeString += " C" + mat.applyToPointStringified(pathNodes.o[i - 1][0], pathNodes.o[i - 1][1]) + " " + mat.applyToPointStringified(pathNodes.i[i][0], pathNodes.i[i][1]) + " " + mat.applyToPointStringified(pathNodes.v[i][0], pathNodes.v[i][1]); } if (length === 1) { shapeString += " M" + mat.applyToPointStringified(pathNodes.v[0][0], pathNodes.v[0][1]); } if (closed && length) { shapeString += " C" + mat.applyToPointStringified(pathNodes.o[i - 1][0], pathNodes.o[i - 1][1]) + " " + mat.applyToPointStringified(pathNodes.i[0][0], pathNodes.i[0][1]) + " " + mat.applyToPointStringified(pathNodes.v[0][0], pathNodes.v[0][1]); shapeString += 'z'; } return shapeString; }; IShapeElement.prototype.renderPath = function(pathData,itemData){ var len, i, j, jLen,pathStringTransformed,redraw,pathNodes,l, lLen = itemData.elements.length; var lvl = itemData.lvl; if(!pathData._render){ return; } for(l=0;l 0) { redraw = itemData.transformers[k].mProps.mdf || redraw; props = itemData.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 : itemData.h.v <= -1 ? -0.99:itemData.h.v; var dist = rad*percent; var x = Math.cos(ang + itemData.a.v)*dist + pt1[0]; var y = Math.sin(ang + itemData.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,itemData){ var styleElem = itemData.style; //TODO fix dashes var d = itemData.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(itemData.c && (itemData.c.mdf || this.firstFrame)){ styleElem.pElem.setAttribute('stroke','rgb('+bm_floor(itemData.c.v[0])+','+bm_floor(itemData.c.v[1])+','+bm_floor(itemData.c.v[2])+')'); ////styleElem.pElem.style.stroke = 'rgb('+bm_floor(itemData.c.v[0])+','+bm_floor(itemData.c.v[1])+','+bm_floor(itemData.c.v[2])+')'; } if(itemData.o.mdf || this.firstFrame){ styleElem.pElem.setAttribute('stroke-opacity',itemData.o.v); } if(itemData.w.mdf || this.firstFrame){ styleElem.pElem.setAttribute('stroke-width',itemData.w.v); if(styleElem.msElem){ styleElem.msElem.setAttribute('stroke-width',itemData.w.v); } ////styleElem.pElem.style.strokeWidth = itemData.w.v; } }; IShapeElement.prototype.destroy = function(){ this._parent.destroy.call(this._parent); this.shapeData = null; this.itemsData = null; this.parentContainer = null; this.placeholder = null; }; function ITextElement(data, animationItem,parentContainer,globalData){ } ITextElement.prototype.init = function(){ this.lettersChangedFlag = true; this.dynamicProperties = this.dynamicProperties || []; this.textAnimator = new TextAnimatorProperty(this.data.t, this.renderType, this); this.textProperty = new TextProperty(this, this.data.t, this.dynamicProperties); this._parent.init.call(this); this.textAnimator.searchProperties(this.dynamicProperties); }; ITextElement.prototype.prepareFrame = function(num) { this._parent.prepareFrame.call(this, num); if(this.textProperty.mdf || this.textProperty.firstFrame) { this.buildNewText(); this.textProperty.firstFrame = false; } } ITextElement.prototype.createPathShape = function(matrixHelper, shapes) { var j,jLen = shapes.length; var k, kLen, pathNodes; var shapeStr = ''; for(j=0;j i ? this.textSpans[i] : document.createElementNS(svgNS,usesGlyphs?'path':'text'); if (cachedSpansLength <= i) { tSpan.setAttribute('stroke-linecap', 'butt'); tSpan.setAttribute('stroke-linejoin','round'); tSpan.setAttribute('stroke-miterlimit','4'); this.textSpans[i] = tSpan; this.layerElement.appendChild(tSpan); } tSpan.style.display = 'inherit'; } matrixHelper.reset(); if(usesGlyphs) { matrixHelper.scale(documentData.s / 100, documentData.s / 100); if (singleShape) { if(letters[i].n) { xPos = -trackingOffset; yPos += documentData.yOffset; yPos += firstLine ? 1 : 0; firstLine = false; } this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos); xPos += letters[i].l || 0; //xPos += letters[i].val === ' ' ? 0 : trackingOffset; xPos += trackingOffset; } charData = this.globalData.fontManager.getCharData(documentData.t.charAt(i), fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily); shapeData = charData && charData.data || {}; shapes = shapeData.shapes ? shapeData.shapes[0].it : []; if(!singleShape){ tSpan.setAttribute('d',this.createPathShape(matrixHelper,shapes)); } else { shapeStr += this.createPathShape(matrixHelper,shapes); } } else { tSpan.textContent = letters[i].val; tSpan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space","preserve"); } // } if (singleShape) { tSpan.setAttribute('d',shapeStr); } } while (i < this.textSpans.length){ this.textSpans[i].style.display = 'none'; i += 1; } this._sizeChanged = true; } SVGTextElement.prototype.sourceRectAtTime = function(time){ this.prepareFrame(this.comp.renderedFrame - this.data.st); this.renderLetters(); if(this._sizeChanged){ this._sizeChanged = false; var textBox = this.layerElement.getBBox(); this.bbox = { top: textBox.y, left: textBox.x, width: textBox.width, height: textBox.height } } return this.bbox; } SVGTextElement.prototype.renderLetters = function(){ if(!this.data.singleShape){ this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag); if(this.lettersChangedFlag || this.textAnimator.lettersChangedFlag){ this._sizeChanged = true; var i,len; var renderedLetters = this.textAnimator.renderedLetters; var letters = this.textProperty.currentData.l; len = letters.length; var renderedLetter, textSpan; for(i=0;i= 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 SVGMatte3Effect(filterElem, filterManager, elem){ this.initialized = false; this.filterManager = filterManager; this.filterElem = filterElem; this.elem = elem; elem.matteElement = document.createElementNS(svgNS,'g'); elem.matteElement.appendChild(elem.layerElement); elem.matteElement.appendChild(elem.transformedElement); elem.baseElement = elem.matteElement; } SVGMatte3Effect.prototype.setElementAsMask = function(elem, mask) { var masker = document.createElementNS(svgNS,'mask'); masker.setAttribute('id',mask.layerId); masker.setAttribute('mask-type','alpha'); masker.appendChild(mask.layerElement); elem.setMatte(mask.layerId); mask.data.hd = false; var defs = elem.globalData.defs; defs.appendChild(masker); } SVGMatte3Effect.prototype.initialize = function() { var ind = this.filterManager.effectElements[0].p.v; var i = 0, len = this.elem.comp.elements.length; while(i < len) { if(this.elem.comp.elements[i].data.ind === ind) { this.setElementAsMask(this.elem, this.elem.comp.elements[i]); } i += 1; } this.initialized = true; } SVGMatte3Effect.prototype.renderFrame = function() { if(!this.initialized) { this.initialize(); } } 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=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', className: (config && config.className) || '' }; 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) { if(this.elements[i]) { 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;i= pos) { return this.threeDElements[i].perspectiveElem; } i += 1; } } HybridRenderer.prototype.createThreeDContainer = function(pos){ var perspectiveElem = document.createElement('div'); styleDiv(perspectiveElem); perspectiveElem.style.width = this.globalData.compSize.w+'px'; perspectiveElem.style.height = this.globalData.compSize.h+'px'; perspectiveElem.style.transformOrigin = perspectiveElem.style.mozTransformOrigin = perspectiveElem.style.webkitTransformOrigin = "50% 50%"; var container = document.createElement('div'); styleDiv(container); container.style.transform = container.style.webkitTransform = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)'; perspectiveElem.appendChild(container); this.resizerElem.appendChild(perspectiveElem); var threeDContainerData = { container:container, perspectiveElem:perspectiveElem, startPos: pos, endPos: pos }; this.threeDElements.push(threeDContainerData); return threeDContainerData; }; HybridRenderer.prototype.build3dContainers = function(){ var i, len = this.layers.length; var lastThreeDContainerData; 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 = Array.apply(null,{length: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.prepareFrame = function(num){ var i, len = this.dynamicProperties.length; for(i=0;i=0;i-=1){ processedPos = this.searchProcessedElement(arr[i]); if(!processedPos){ arr[i]._render = render; } else { itemsData[i] = prevViewData[processedPos - 1]; } if(arr[i].ty == 'fl' || arr[i].ty == 'st'){ if(!processedPos){ itemsData[i] = this.createStyleElement(arr[i], dynamicProperties); } else { itemsData[i].style.closed = false; } ownArrays.push(itemsData[i].style); }else if(arr[i].ty == 'gr'){ if(!processedPos){ itemsData[i] = this.createGroupElement(arr[i]); } else { jLen = itemsData[i].it.length; 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 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 offsetTime = this.offsetTime || 0; var i, len, ret; if(type.toLowerCase() === 'pingpong') { var iterations = Math.floor((currentFrame - firstKeyFrame)/cycleDuration); if(iterations % 2 !== 0){ return this.getValueAtTime(((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) - offsetTime) / 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;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) - offsetTime) / 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 lengthPos) { segments = lengths[i].segments; var initIndex = i; var endIndex = (shapePath.c && i === len - 1) ? 0 : i + 1; var segmentPerc = (lengthPos - accumulatedLength)/lengths[i].addedLength; var pt = bez.getPointInSegment(shapePath.v[initIndex], shapePath.v[endIndex], shapePath.o[initIndex], shapePath.i[endIndex], segmentPerc, lengths[i]) break; } else { accumulatedLength += lengths[i].addedLength; } i += 1; } if(!pt){ pt = shapePath.c ? [shapePath.v[0][0],shapePath.v[0][1]]:[shapePath.v[shapePath._length-1][0],shapePath.v[shapePath._length-1][1]] } return pt; } ShapePropertyConstructorFunction.prototype.vectorOnPath = function(perc, time, vectorType){ //perc doesn't use triple equality because can be a Number object, not a primitive. perc = perc == 1 ? this.v.c ? 0 : 0.999 : perc; var pt1 = this.pointOnPath(perc, time); var pt2 = this.pointOnPath(perc + 0.001, time); var xLength = pt2[0] - pt1[0]; var yLength = pt2[1] - pt1[1]; var magnitude = Math.sqrt(Math.pow(xLength,2) + Math.pow(yLength,2)); var unitVector = vectorType === 'tangent' ? [xLength/magnitude, yLength/magnitude] : [-yLength/magnitude, xLength/magnitude]; return unitVector; } ShapePropertyConstructorFunction.prototype.tangentOnPath = function(perc, time){ return this.vectorOnPath(perc, time, 'tangent'); } ShapePropertyConstructorFunction.prototype.normalOnPath = function(perc, time){ return this.vectorOnPath(perc, time, 'normal'); } ShapePropertyConstructorFunction.prototype.setGroupProperty = setGroupProperty; ShapePropertyConstructorFunction.prototype.getValueAtTime = getStaticValueAtTime; KeyframedShapePropertyConstructorFunction.prototype.vertices = ShapePropertyConstructorFunction.prototype.vertices; KeyframedShapePropertyConstructorFunction.prototype.points = ShapePropertyConstructorFunction.prototype.points; KeyframedShapePropertyConstructorFunction.prototype.inTangents = ShapePropertyConstructorFunction.prototype.inTangents; KeyframedShapePropertyConstructorFunction.prototype.outTangents = ShapePropertyConstructorFunction.prototype.outTangents; KeyframedShapePropertyConstructorFunction.prototype.isClosed = ShapePropertyConstructorFunction.prototype.isClosed; KeyframedShapePropertyConstructorFunction.prototype.pointOnPath = ShapePropertyConstructorFunction.prototype.pointOnPath; KeyframedShapePropertyConstructorFunction.prototype.vectorOnPath = ShapePropertyConstructorFunction.prototype.vectorOnPath; KeyframedShapePropertyConstructorFunction.prototype.tangentOnPath = ShapePropertyConstructorFunction.prototype.tangentOnPath; KeyframedShapePropertyConstructorFunction.prototype.normalOnPath = ShapePropertyConstructorFunction.prototype.normalOnPath; KeyframedShapePropertyConstructorFunction.prototype.setGroupProperty = ShapePropertyConstructorFunction.prototype.setGroupProperty; KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime; var propertyGetShapeProp = ShapePropertyFactory.getShapeProp; ShapePropertyFactory.getShapeProp = function(elem,data,type, arr, trims){ var prop = propertyGetShapeProp(elem,data,type, arr, trims); var isAdded = prop.k; if(data.ix !== undefined){ Object.defineProperty(prop,'propertyIndex',{ get: function(){ return data.ix; } }) } if(type === 3){ searchExpressions(elem,data.pt,prop); } else if(type === 4){ searchExpressions(elem,data.ks,prop); } if(!isAdded && prop.x){ arr.push(prop); } return prop; } var propertyGetTextProp = PropertyFactory.getTextSelectorProp; PropertyFactory.getTextSelectorProp = function(elem, data,arr){ if(data.t === 1){ return new TextExpressionSelectorProp(elem, data,arr); } else { return propertyGetTextProp(elem,data,arr); } } }()); (function addTextPropertyDecorator() { function searchExpressions(){ if(this.data.d.x){ this.comp = this.elem.comp; if(this.getValue) { this.getPreValue = this.getValue; } this.calculateExpression = ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this); this.getValue = this.getExpressionValue; return true; } return false; } TextProperty.prototype.searchProperty = function(){ this.kf = this.searchExpressions() || this.data.d.k.length > 1; return this.kf; } TextProperty.prototype.getExpressionValue = function(num){ this.calculateExpression(); if(this.mdf) { this.currentData.t = this.v.toString(); this.completeTextData(this.currentData); } } TextProperty.prototype.searchExpressions = searchExpressions; }()); var ExpressionManager = (function(){ var ob = {}; var Math = BMMath; var window = null; var document = null; function duplicatePropertyValue(value, mult){ mult = mult || 1; if(typeof value === 'number' || value instanceof Number){ return value*mult; }else if(value.i){ return JSON.parse(JSON.stringify(value)); }else{ var arr = Array.apply(null,{length:value.length}); var i, len = value.length; 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' || arr1 instanceof 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;i1){ for(j=0;jdata.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){ var ob, i, len; if(!data.k.length || typeof(data.k[0]) === 'number'){ throw new Error('The property has no keyframe at index ' + ind); } ind -= 1; 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; } len = arr.length; for(i=0;i 1) { defaultCurveSegments = value; } if (defaultCurveSegments >= 50) { roundValues(false); } else { roundValues(true); } } function inBrowser() { return typeof navigator !== 'undefined'; } 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.setLocationHref = setLocationHref; 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.inBrowser = inBrowser; bodymovinjs.installPlugin = installPlugin; bodymovinjs.__getFactory = getFactory; bodymovinjs.version = '4.13.0'; 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] || { src: '' }; var queryString = myScript.src.replace(/^[^\?]+\??/, ''); renderer = getQueryVariable('renderer'); } var readyStateCheckInterval = setInterval(checkReady, 100); return bodymovinjs; })); (function($) { // Modernizr 2.7.2 supportsInlineSVG = function() { var div = document.createElement('div'); div.innerHTML = ''; return (div.firstChild && div.firstChild.namespaceURI) == 'http://www.w3.org/2000/svg'; }; // Modernizr 2.7.2 supportsSVG = function () { return !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect; }; $.fn.inlinesvg = function (options) { if (supportsInlineSVG()) { this.each(function(index){ var $img = $(this), imgID = $img.attr('id'), imgClass = $img.attr('class'), imgURL = $img.attr('src'); $.get(imgURL, function(data) { // Get the SVG tag, ignore the rest var $svg = $(data).find('svg'); // Copy properties from IMG tag to SVG tag $.each($img.prop('attributes'), function() { $svg.attr(this.name, this.value); }); // Remove any invalid XML tags as per http://validator.w3.org $svg.removeAttr('xmlns:a'); // Replace image with new SVG $img.replaceWith($svg); }); }); return; } // No SVG Support? Replace with PNGs. if (!supportsSVG()) { this.attr('src', function() { return $(this).attr('src').replace('.svg', '.png'); }).removeClass('svg'); } } }(jQuery)); /*! * jQuery.scrollTo * Copyright (c) 2007-2015 Ariel Flesler - afleslergmailcom | http://flesler.blogspot.com * Licensed under MIT * http://flesler.blogspot.com/2007/10/jqueryscrollto.html * @projectDescription Lightweight, cross-browser and highly customizable animated scrolling with jQuery * @author Ariel Flesler * @version 2.1.2 */ ;(function(factory) { 'use strict'; if (typeof define === 'function' && define.amd) { // AMD define(['jquery'], factory); } else if (typeof module !== 'undefined' && module.exports) { // CommonJS module.exports = factory(require('jquery')); } else { // Global factory(jQuery); } })(function($) { 'use strict'; var $scrollTo = $.scrollTo = function(target, duration, settings) { return $(window).scrollTo(target, duration, settings); }; $scrollTo.defaults = { axis:'xy', duration: 0, limit:true }; function isWin(elem) { return !elem.nodeName || $.inArray(elem.nodeName.toLowerCase(), ['iframe','#document','html','body']) !== -1; } $.fn.scrollTo = function(target, duration, settings) { if (typeof duration === 'object') { settings = duration; duration = 0; } if (typeof settings === 'function') { settings = { onAfter:settings }; } if (target === 'max') { target = 9e9; } settings = $.extend({}, $scrollTo.defaults, settings); // Speed is still recognized for backwards compatibility duration = duration || settings.duration; // Make sure the settings are given right var queue = settings.queue && settings.axis.length > 1; if (queue) { // Let's keep the overall duration duration /= 2; } settings.offset = both(settings.offset); settings.over = both(settings.over); return this.each(function() { // Null target yields nothing, just like jQuery does if (target === null) return; var win = isWin(this), elem = win ? this.contentWindow || window : this, $elem = $(elem), targ = target, attr = {}, toff; switch (typeof targ) { // A number will pass the regex case 'number': case 'string': if (/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(targ)) { targ = both(targ); // We are done break; } // Relative/Absolute selector targ = win ? $(targ) : $(targ, elem); /* falls through */ case 'object': if (targ.length === 0) return; // DOMElement / jQuery if (targ.is || targ.style) { // Get the real position of the target toff = (targ = $(targ)).offset(); } } var offset = $.isFunction(settings.offset) && settings.offset(elem, targ) || settings.offset; $.each(settings.axis.split(''), function(i, axis) { var Pos = axis === 'x' ? 'Left' : 'Top', pos = Pos.toLowerCase(), key = 'scroll' + Pos, prev = $elem[key](), max = $scrollTo.max(elem, axis); if (toff) {// jQuery / DOMElement attr[key] = toff[pos] + (win ? 0 : prev - $elem.offset()[pos]); // If it's a dom element, reduce the margin if (settings.margin) { attr[key] -= parseInt(targ.css('margin'+Pos), 10) || 0; attr[key] -= parseInt(targ.css('border'+Pos+'Width'), 10) || 0; } attr[key] += offset[pos] || 0; if (settings.over[pos]) { // Scroll to a fraction of its width/height attr[key] += targ[axis === 'x'?'width':'height']() * settings.over[pos]; } } else { var val = targ[pos]; // Handle percentage values attr[key] = val.slice && val.slice(-1) === '%' ? parseFloat(val) / 100 * max : val; } // Number or 'number' if (settings.limit && /^\d+$/.test(attr[key])) { // Check the limits attr[key] = attr[key] <= 0 ? 0 : Math.min(attr[key], max); } // Don't waste time animating, if there's no need. if (!i && settings.axis.length > 1) { if (prev === attr[key]) { // No animation needed attr = {}; } else if (queue) { // Intermediate animation animate(settings.onAfterFirst); // Don't animate this axis again in the next iteration. attr = {}; } } }); animate(settings.onAfter); function animate(callback) { var opts = $.extend({}, settings, { // The queue setting conflicts with animate() // Force it to always be true queue: true, duration: duration, complete: callback && function() { callback.call(elem, targ, settings); } }); $elem.animate(attr, opts); } }); }; // Max scrolling position, works on quirks mode // It only fails (not too badly) on IE, quirks mode. $scrollTo.max = function(elem, axis) { var Dim = axis === 'x' ? 'Width' : 'Height', scroll = 'scroll'+Dim; if (!isWin(elem)) return elem[scroll] - $(elem)[Dim.toLowerCase()](); var size = 'client' + Dim, doc = elem.ownerDocument || elem.document, html = doc.documentElement, body = doc.body; return Math.max(html[scroll], body[scroll]) - Math.min(html[size], body[size]); }; function both(val) { return $.isFunction(val) || $.isPlainObject(val) ? val : { top:val, left:val }; } // Add special hooks so that window scroll properties can be animated $.Tween.propHooks.scrollLeft = $.Tween.propHooks.scrollTop = { get: function(t) { return $(t.elem)[t.prop](); }, set: function(t) { var curr = this.get(t); // If interrupt is true and user scrolled, stop animating if (t.options.interrupt && t._last && t._last !== curr) { return $(t.elem).stop(); } var next = Math.round(t.now); // Don't waste CPU // Browsers don't render floating point scroll if (curr !== next) { $(t.elem)[t.prop](next); t._last = this.get(t); } } }; // AMD requirement return $scrollTo; }); /* _ _ _ _ ___| (_) ___| | __ (_)___ / __| | |/ __| |/ / | / __| \__ \ | | (__| < _ | \__ \ |___/_|_|\___|_|\_(_)/ |___/ |__/ Version: 1.8.0 Author: Ken Wheeler Website: http://kenwheeler.github.io Docs: http://kenwheeler.github.io/slick Repo: http://github.com/kenwheeler/slick Issues: http://github.com/kenwheeler/slick/issues */ /* global window, document, define, jQuery, setInterval, clearInterval */ ;(function(factory) { 'use strict'; if (typeof define === 'function' && define.amd) { define(['jquery'], factory); } else if (typeof exports !== 'undefined') { module.exports = factory(require('jquery')); } else { factory(jQuery); } }(function($) { 'use strict'; var Slick = window.Slick || {}; Slick = (function() { var instanceUid = 0; function Slick(element, settings) { var _ = this, dataSettings; _.defaults = { accessibility: true, adaptiveHeight: false, appendArrows: $(element), appendDots: $(element), arrows: true, asNavFor: null, prevArrow: '', nextArrow: '', autoplay: false, autoplaySpeed: 3000, centerMode: false, centerPadding: '50px', cssEase: 'ease', customPaging: function(slider, i) { return $('