UNPKG

bodymovin

Version:

After Effects plugin for exporting animations to SVG + JavaScript or canvas + JavaScript

237 lines (214 loc) 8.48 kB
function SVGRenderer(animationItem, config){ this.animationItem = animationItem; this.layers = null; this.renderedFrame = -1; this.globalData = { frameNum: -1 }; this.renderConfig = { preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet', progressiveLoad: (config && config.progressiveLoad) || false, hideOnTransparent: (config && config.hideOnTransparent === false) ? false : true, viewBoxOnly: (config && config.viewBoxOnly) || false, className: (config && config.className) || '' }; this.globalData.renderConfig = this.renderConfig; this.elements = []; this.pendingElements = []; this.destroyed = false; } extendPrototype(BaseRenderer,SVGRenderer); SVGRenderer.prototype.createBase = function (data) { return new SVGBaseElement(data, this.layerElement,this.globalData,this); }; SVGRenderer.prototype.createShape = function (data) { return new IShapeElement(data, this.layerElement,this.globalData,this); }; SVGRenderer.prototype.createText = function (data) { return new SVGTextElement(data, this.layerElement,this.globalData,this); }; SVGRenderer.prototype.createImage = function (data) { return new IImageElement(data, this.layerElement,this.globalData,this); }; SVGRenderer.prototype.createComp = function (data) { return new ICompElement(data, this.layerElement,this.globalData,this); }; SVGRenderer.prototype.createSolid = function (data) { return new ISolidElement(data, this.layerElement,this.globalData,this); }; SVGRenderer.prototype.configAnimation = function(animData){ this.layerElement = document.createElementNS(svgNS,'svg'); this.layerElement.setAttribute('xmlns','http://www.w3.org/2000/svg'); this.layerElement.setAttribute('viewBox','0 0 '+animData.w+' '+animData.h); if(!this.renderConfig.viewBoxOnly) { this.layerElement.setAttribute('width',animData.w); this.layerElement.setAttribute('height',animData.h); this.layerElement.style.width = '100%'; this.layerElement.style.height = '100%'; } if(this.renderConfig.className) { this.layerElement.setAttribute('class', this.renderConfig.className); } this.layerElement.setAttribute('preserveAspectRatio',this.renderConfig.preserveAspectRatio); //this.layerElement.style.transform = 'translate3d(0,0,0)'; //this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px"; this.animationItem.wrapper.appendChild(this.layerElement); //Mask animation var defs = document.createElementNS(svgNS, 'defs'); this.globalData.defs = defs; this.layerElement.appendChild(defs); this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem); this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem); this.globalData.progressiveLoad = this.renderConfig.progressiveLoad; this.globalData.frameId = 0; this.globalData.nm = animData.nm; this.globalData.compSize = { w: animData.w, h: animData.h }; this.data = animData; this.globalData.frameRate = animData.fr; var maskElement = document.createElementNS(svgNS, 'clipPath'); var rect = document.createElementNS(svgNS,'rect'); rect.setAttribute('width',animData.w); rect.setAttribute('height',animData.h); rect.setAttribute('x',0); rect.setAttribute('y',0); var maskId = 'animationMask_'+randomString(10); maskElement.setAttribute('id', maskId); maskElement.appendChild(rect); var maskedElement = document.createElementNS(svgNS,'g'); maskedElement.setAttribute("clip-path", "url(" + locationHref + "#"+maskId+")"); this.layerElement.appendChild(maskedElement); defs.appendChild(maskElement); this.layerElement = maskedElement; this.layers = animData.layers; this.globalData.fontManager = new FontManager(); this.globalData.fontManager.addChars(animData.chars); this.globalData.fontManager.addFonts(animData.fonts,defs); this.elements = Array.apply(null,{length:animData.layers.length}); }; SVGRenderer.prototype.destroy = function () { this.animationItem.wrapper.innerHTML = ''; this.layerElement = null; this.globalData.defs = null; var i, len = this.layers ? this.layers.length : 0; for (i = 0; i < len; i++) { if(this.elements[i]){ this.elements[i].destroy(); } } this.elements.length = 0; this.destroyed = true; this.animationItem = null; }; SVGRenderer.prototype.updateContainerSize = function () { }; SVGRenderer.prototype.buildItem = function(pos){ var elements = this.elements; if(elements[pos] || this.layers[pos].ty == 99){ return; } elements[pos] = true; var element = this.createItem(this.layers[pos]); elements[pos] = element; if(expressionsPlugin){ if(this.layers[pos].ty === 0){ this.globalData.projectInterface.registerComposition(element); } element.initExpressions(); } this.appendElementInPos(element,pos); if(this.layers[pos].tt){ if(!this.elements[pos - 1] || this.elements[pos - 1] === true){ this.buildItem(pos - 1); this.addPendingElement(element); } else { element.setMatte(elements[pos - 1].layerId); } } }; SVGRenderer.prototype.checkPendingElements = function(){ while(this.pendingElements.length){ var element = this.pendingElements.pop(); element.checkParenting(); if(element.data.tt){ var i = 0, len = this.elements.length; while(i<len){ if(this.elements[i] === element){ element.setMatte(this.elements[i - 1].layerId); break; } i += 1; } } } }; SVGRenderer.prototype.renderFrame = function(num){ if(this.renderedFrame == num || this.destroyed){ return; } if(num === null){ num = this.renderedFrame; }else{ this.renderedFrame = num; } //clearPoints(); /*console.log('-------'); console.log('FRAME ',num);*/ this.globalData.frameNum = num; this.globalData.frameId += 1; this.globalData.projectInterface.currentFrame = num; var i, len = this.layers.length; if(!this.completeLayers){ this.checkLayers(num); } for (i = len - 1; 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<pos){ if(this.elements[i] && this.elements[i]!== true && this.elements[i].getBaseElement()){ nextElement = this.elements[i].getBaseElement(); } i += 1; } if(nextElement){ this.layerElement.insertBefore(newElement, nextElement); } else { this.layerElement.appendChild(newElement); } }; SVGRenderer.prototype.hide = function(){ this.layerElement.style.display = 'none'; }; SVGRenderer.prototype.show = function(){ this.layerElement.style.display = 'block'; }; SVGRenderer.prototype.searchExtraCompositions = function(assets){ var i, len = assets.length; var floatingContainer = document.createElementNS(svgNS,'g'); for(i=0;i<len;i+=1){ if(assets[i].xt){ var comp = this.createComp(assets[i],floatingContainer,this.globalData.comp,null); comp.initExpressions(); //comp.compInterface = CompExpressionInterface(comp); //Expressions.addLayersInterface(comp.elements, this.globalData.projectInterface); this.globalData.projectInterface.registerComposition(comp); } } };