blob: 0949a1752e4ee72062b6e722c9bc9628432553c2 [file] [log] [blame]
function HybridRenderer(animationItem){
this.animationItem = animationItem;
this.layers = null;
this.renderedFrame = -1;
this.globalData = {
frameNum: -1
};
this.elements = [];
this.threeDElements = [];
this.destroyed = false;
this.camera = null;
}
HybridRenderer.prototype.createItem = function(layer,parentContainer,comp, placeholder){
switch(layer.ty){
case 2:
return this.createImage(layer,parentContainer,comp, placeholder);
case 0:
return this.createComp(layer,parentContainer,comp, placeholder);
case 1:
return this.createSolid(layer,parentContainer,comp, placeholder);
case 4:
return this.createShape(layer,parentContainer,comp, placeholder);
case 5:
return this.createText(layer,parentContainer,comp, placeholder);
case 13:
return this.createCamera(layer,parentContainer,comp, placeholder);
case 99:
return this.createPlaceHolder(layer,parentContainer);
}
return this.createBase(layer,parentContainer,comp);
};
HybridRenderer.prototype.buildItems = function(layers,parentContainer,elements,comp, placeholder){
var i, len = layers.length;
if(!elements){
elements = this.elements;
}
if(!comp){
comp = this;
}
var currentContainer, is3d = false;
var elems;
for (i = len - 1; i >= 0; i--) {
if(!parentContainer) {
if(layers[i].ddd) {
if(!is3d){
is3d = true;
currentContainer = this.getThreeDContainer();
}
elements[i] = this.createItem(layers[i],currentContainer,comp, placeholder);
} else {
is3d = false;
elements[i] = this.createItem(layers[i],this.animationItem.resizerElem,comp, placeholder);
}
} else{
elements[i] = this.createItem(layers[i],parentContainer,comp, placeholder);
}
if (layers[i].ty === 0) {
elems = [];
this.buildItems(layers[i].layers,elements[i].getDomElement(),elems,elements[i], elements[i].placeholder);
elements[i].setElements(elems);
}
if(layers[i].td){
elements[i+1].setMatte(elements[i].layerId);
}
//NullLayer
}
this.currentContainer = this.animationItem.resizerElem;
if(!parentContainer){
if(this.threeDElements.length){
if(!this.camera){
var cWidth = this.globalData.compSize.w;
var cHeight = this.globalData.compSize.h;
len = this.threeDElements.length;
for(i=0;i<len;i+=1){
this.threeDElements[0][i].style.perspective = this.threeDElements[0][i].style.webkitPerspective = Math.sqrt(Math.pow(cWidth,2) + Math.pow(cHeight,2)) + 'px';
}
} else {
this.camera.setup();
}
}
}
};
HybridRenderer.prototype.includeLayers = function(layers,parentContainer,elements){
var i, len = layers.length;
if(!elements){
elements = this.elements;
}
if(!parentContainer){
parentContainer = this.currentContainer;
}
var j, jLen = elements.length, elems, placeholder;
for(i=0;i<len;i+=1){
if(!layers[i].id){
var elem = this.createItem(layers[i],parentContainer, this);
elements.push(elem);
if (layers[i].ty === 0) {
elems = [];
this.buildItems(layers[i].layers,elem.getDomElement(),elems, elem);
elem.setElements(elems);
}
}else {
j = 0;
while(j<jLen){
if(elements[j].data.id == layers[i].id){
placeholder = elements[j];
elements[j] = this.createItem(layers[i],parentContainer,this, placeholder);
if (layers[i].ty === 0) {
elems = [];
this.buildItems(layers[i].layers,elements[j].getDomElement(),elems,elements[j], elements[i].placeholder);
elements[j].setElements(elems);
}
}
j += 1;
}
}
}
for(i=0;i<len;i+=1){
if(layers[i].td){
elements[i+1].setMatte(elements[i].layerId);
}
}
};
HybridRenderer.prototype.createBase = function (data,parentContainer,comp, placeholder) {
return new SVGBaseElement(data, parentContainer,this.globalData,comp, placeholder);
};
HybridRenderer.prototype.createPlaceHolder = function (data,parentContainer) {
return new PlaceHolderElement(data, parentContainer,this.globalData);
};
HybridRenderer.prototype.createShape = function (data,parentContainer,comp, placeholder) {
if(comp.isSvg){
return new IShapeElement(data, parentContainer,this.globalData,comp, placeholder);
}
return new HShapeElement(data, parentContainer,this.globalData,comp, placeholder);
};
HybridRenderer.prototype.createText = function (data,parentContainer,comp, placeholder) {
if(comp.isSvg){
return new SVGTextElement(data, parentContainer,this.globalData,comp, placeholder);
}
return new HTextElement(data, parentContainer,this.globalData,comp, placeholder);
};
HybridRenderer.prototype.createCamera = function (data,parentContainer,comp, placeholder) {
this.camera = new HCameraElement(data, parentContainer,this.globalData,comp, placeholder);
return this.camera;
};
HybridRenderer.prototype.createImage = function (data,parentContainer,comp, placeholder) {
if(comp.isSvg){
return new IImageElement(data, parentContainer,this.globalData,comp, placeholder);
}
return new HImageElement(data, parentContainer,this.globalData,comp, placeholder);
};
HybridRenderer.prototype.createComp = function (data,parentContainer,comp, placeholder) {
if(comp.isSvg){
return new ICompElement(data, parentContainer,this.globalData,comp, placeholder);
}
return new HCompElement(data, parentContainer,this.globalData,comp, placeholder);
};
HybridRenderer.prototype.createSolid = function (data,parentContainer,comp, placeholder) {
if(comp.isSvg){
return new ISolidElement(data, parentContainer,this.globalData,comp, placeholder);
}
return new HSolidElement(data, parentContainer,this.globalData,comp, placeholder);
};
HybridRenderer.prototype.getThreeDContainer = function(){
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.animationItem.resizerElem.appendChild(perspectiveElem);
this.threeDElements.push([perspectiveElem,container]);
return container;
}
HybridRenderer.prototype.configAnimation = function(animData){
var resizerElem = document.createElement('div');
var wrapper = this.animationItem.wrapper;
resizerElem.style.width = animData.w+'px';
resizerElem.style.height = animData.h+'px';
this.animationItem.resizerElem = resizerElem;
styleDiv(resizerElem);
resizerElem.style.transformStyle = resizerElem.style.webkitTransformStyle = resizerElem.style.mozTransformStyle = "flat";
wrapper.appendChild(resizerElem);
resizerElem.style.overflow = 'hidden';
var svg = document.createElementNS(svgNS,'svg');
svg.setAttribute('width','1');
svg.setAttribute('height','1');
styleDiv(svg);
this.animationItem.resizerElem.appendChild(svg);
var defs = document.createElementNS(svgNS,'defs');
svg.appendChild(defs);
this.globalData.defs = defs;
//Mask animation
this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
this.globalData.getPath = this.animationItem.getPath.bind(this.animationItem);
this.globalData.elementLoaded = this.animationItem.elementLoaded.bind(this.animationItem);
this.globalData.frameId = 0;
this.globalData.compSize = {
w: animData.w,
h: animData.h
};
this.globalData.frameRate = animData.fr;
this.layers = animData.layers;
this.globalData.fontManager = new FontManager();
this.globalData.fontManager.addChars(animData.chars);
this.globalData.fontManager.addFonts(animData.fonts,svg);
this.updateContainerSize();
};
HybridRenderer.prototype.buildStage = function (container, layers,elements) {
var i, len = layers.length, layerData;
if(!elements){
elements = this.elements;
}
for (i = len - 1; i >= 0; i--) {
layerData = layers[i];
if (layerData.parent !== undefined) {
this.buildItemParenting(layerData,elements[i],layers,layerData.parent,elements, true);
}
if (layerData.ty === 0) {
this.buildStage(elements[i].getComposingElement(), layerData.layers, elements[i].getElements());
}
}
};
HybridRenderer.prototype.buildItemParenting = function (layerData,element,layers,parentName,elements, resetHierarchyFlag) {
if(!layerData.parents){
layerData.parents = [];
}
if(resetHierarchyFlag){
element.resetHierarchy();
}
var i=0, len = layers.length;
while(i<len){
if(layers[i].ind == parentName){
element.getHierarchy().push(elements[i]);
if(element.data.ty === 13){
elements[i].finalTransform.mProp.setInverted();
}
if(layers[i].parent !== undefined){
this.buildItemParenting(layerData,element,layers,layers[i].parent,elements, false);
}
}
i += 1;
}
};
HybridRenderer.prototype.destroy = function () {
this.animationItem.wrapper.innerHTML = '';
this.animationItem.container = null;
this.globalData.defs = null;
var i, len = this.layers ? this.layers.length : 0;
for (i = 0; i < len; i++) {
this.elements[i].destroy();
}
this.elements.length = 0;
this.destroyed = true;
};
HybridRenderer.prototype.updateContainerSize = function () {
var elementWidth = this.animationItem.wrapper.offsetWidth;
var elementHeight = this.animationItem.wrapper.offsetHeight;
var elementRel = elementWidth/elementHeight;
var animationRel = this.globalData.compSize.w/this.globalData.compSize.h;
var sx,sy,tx,ty;
if(animationRel>elementRel){
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.animationItem.resizerElem.style.transform = this.animationItem.resizerElem.style.webkitTransform = 'matrix3d(' + sx + ',0,0,0,0,'+sy+',0,0,0,0,1,0,'+tx+','+ty+',0,1)';
};
HybridRenderer.prototype.renderFrame = function(num){
if(this.renderedFrame == num || this.destroyed){
return;
}
if(num === null){
num = this.renderedFrame;
}else{
this.renderedFrame = num;
}
//console.log('-------');
//console.log('FRAME ',num);
this.globalData.frameNum = num;
this.globalData.frameId += 1;
var i, len = this.layers.length;
for (i = 0; i < len; i++) {
this.elements[i].prepareFrame(num - this.layers[i].st);
}
for (i = 0; i < len; i++) {
this.elements[i].renderFrame();
}
};
HybridRenderer.prototype.hide = function(){
this.animationItem.resizerElem.style.display = 'none';
};
HybridRenderer.prototype.show = function(){
this.animationItem.resizerElem.style.display = 'block';
};