blob: aaca5b7d6b126abc265d5daa9a2f95446f4ba597 [file] [log] [blame]
function HybridRenderer(animationItem, config) {
this.animationItem = animationItem;
this.layers = null;
this.renderedFrame = -1;
this.renderConfig = {
className: (config && config.className) || '',
imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
hideOnTransparent: !(config && config.hideOnTransparent === false),
filterSize: {
width: (config && config.filterSize && config.filterSize.width) || '400%',
height: (config && config.filterSize && config.filterSize.height) || '400%',
x: (config && config.filterSize && config.filterSize.x) || '-100%',
y: (config && config.filterSize && config.filterSize.y) || '-100%',
},
};
this.globalData = {
_mdf: false,
frameNum: -1,
renderConfig: this.renderConfig,
};
this.pendingElements = [];
this.elements = [];
this.threeDElements = [];
this.destroyed = false;
this.camera = null;
this.supports3d = true;
this.rendererType = 'html';
}
extendPrototype([BaseRenderer], HybridRenderer);
HybridRenderer.prototype.buildItem = SVGRenderer.prototype.buildItem;
HybridRenderer.prototype.checkPendingElements = function () {
while (this.pendingElements.length) {
var element = this.pendingElements.pop();
element.checkParenting();
}
};
HybridRenderer.prototype.appendElementInPos = function (element, pos) {
var newDOMElement = element.getBaseElement();
if (!newDOMElement) {
return;
}
var layer = this.layers[pos];
if (!layer.ddd || !this.supports3d) {
if (this.threeDElements) {
this.addTo3dContainer(newDOMElement, pos);
} else {
var i = 0;
var nextDOMElement,
nextLayer,
tmpDOMElement;
while (i < pos) {
if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement) {
nextLayer = this.elements[i];
tmpDOMElement = this.layers[i].ddd ? this.getThreeDContainerByPos(i) : nextLayer.getBaseElement();
nextDOMElement = tmpDOMElement || nextDOMElement;
}
i += 1;
}
if (nextDOMElement) {
if (!layer.ddd || !this.supports3d) {
this.layerElement.insertBefore(newDOMElement, nextDOMElement);
}
} else if (!layer.ddd || !this.supports3d) {
this.layerElement.appendChild(newDOMElement);
}
}
} else {
this.addTo3dContainer(newDOMElement, pos);
}
};
HybridRenderer.prototype.createShape = function (data) {
if (!this.supports3d) {
return new SVGShapeElement(data, this.globalData, this);
}
return new HShapeElement(data, this.globalData, this);
};
HybridRenderer.prototype.createText = function (data) {
if (!this.supports3d) {
return new SVGTextElement(data, this.globalData, this);
}
return new HTextElement(data, this.globalData, this);
};
HybridRenderer.prototype.createCamera = function (data) {
this.camera = new HCameraElement(data, this.globalData, this);
return this.camera;
};
HybridRenderer.prototype.createImage = function (data) {
if (!this.supports3d) {
return new IImageElement(data, this.globalData, this);
}
return new HImageElement(data, this.globalData, this);
};
HybridRenderer.prototype.createComp = function (data) {
if (!this.supports3d) {
return new SVGCompElement(data, this.globalData, this);
}
return new HCompElement(data, this.globalData, this);
};
HybridRenderer.prototype.createSolid = function (data) {
if (!this.supports3d) {
return new ISolidElement(data, this.globalData, this);
}
return new HSolidElement(data, this.globalData, this);
};
HybridRenderer.prototype.createNull = SVGRenderer.prototype.createNull;
HybridRenderer.prototype.getThreeDContainerByPos = function (pos) {
var i = 0,
len = this.threeDElements.length;
while (i < len) {
if (this.threeDElements[i].startPos <= pos && this.threeDElements[i].endPos >= pos) {
return this.threeDElements[i].perspectiveElem;
}
i += 1;
}
return null;
};
HybridRenderer.prototype.createThreeDContainer = function (pos, type) {
var perspectiveElem = createTag('div');
styleDiv(perspectiveElem);
var container = createTag('div');
styleDiv(container);
if (type === '3d') {
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%';
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,
type: type,
};
this.threeDElements.push(threeDContainerData);
return threeDContainerData;
};
HybridRenderer.prototype.build3dContainers = function () {
var i,
len = this.layers.length;
var lastThreeDContainerData;
var currentContainer = '';
for (i = 0; i < len; i += 1) {
if (this.layers[i].ddd && this.layers[i].ty !== 3) {
if (currentContainer !== '3d') {
currentContainer = '3d';
lastThreeDContainerData = this.createThreeDContainer(i, '3d');
}
lastThreeDContainerData.endPos = Math.max(lastThreeDContainerData.endPos, i);
} else {
if (currentContainer !== '2d') {
currentContainer = '2d';
lastThreeDContainerData = this.createThreeDContainer(i, '2d');
}
lastThreeDContainerData.endPos = Math.max(lastThreeDContainerData.endPos, i);
}
}
len = this.threeDElements.length;
for (i = len - 1; i >= 0; i--) {
this.resizerElem.appendChild(this.threeDElements[i].perspectiveElem);
}
};
HybridRenderer.prototype.addTo3dContainer = function (elem, pos) {
var i = 0,
len = this.threeDElements.length;
while (i < len) {
if (pos <= this.threeDElements[i].endPos) {
var j = this.threeDElements[i].startPos;
var nextElement;
while (j < pos) {
if (this.elements[j] && this.elements[j].getBaseElement) {
nextElement = this.elements[j].getBaseElement();
}
j += 1;
}
if (nextElement) {
this.threeDElements[i].container.insertBefore(elem, nextElement);
} else {
this.threeDElements[i].container.appendChild(elem);
}
break;
}
i += 1;
}
};
HybridRenderer.prototype.configAnimation = function (animData) {
var resizerElem = createTag('div');
var wrapper = this.animationItem.wrapper;
resizerElem.style.width = animData.w + 'px';
resizerElem.style.height = animData.h + 'px';
this.resizerElem = resizerElem;
styleDiv(resizerElem);
resizerElem.style.transformStyle = resizerElem.style.webkitTransformStyle = resizerElem.style.mozTransformStyle = 'flat';
if (this.renderConfig.className) {
resizerElem.setAttribute('class', this.renderConfig.className);
}
wrapper.appendChild(resizerElem);
resizerElem.style.overflow = 'hidden';
var svg = createNS('svg');
svg.setAttribute('width', '1');
svg.setAttribute('height', '1');
styleDiv(svg);
this.resizerElem.appendChild(svg);
var defs = createNS('defs');
svg.appendChild(defs);
this.data = animData;
// Mask animation
this.setupGlobalData(animData, svg);
this.globalData.defs = defs;
this.layers = animData.layers;
this.layerElement = this.resizerElem;
this.build3dContainers();
this.updateContainerSize();
};
HybridRenderer.prototype.destroy = function () {
if (this.animationItem.wrapper) {
this.animationItem.wrapper.innerText = '';
}
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;
this.animationItem = null;
};
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.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 < len; i += 1) {
this.threeDElements[i].perspectiveElem.style.perspective = this.threeDElements[i].perspectiveElem.style.webkitPerspective = Math.sqrt(Math.pow(cWidth, 2) + Math.pow(cHeight, 2)) + 'px';
}
}
};
HybridRenderer.prototype.searchExtraCompositions = function (assets) {
var i,
len = assets.length;
var floatingContainer = createTag('div');
for (i = 0; i < len; i += 1) {
if (assets[i].xt) {
var comp = this.createComp(assets[i], floatingContainer, this.globalData.comp, null);
comp.initExpressions();
this.globalData.projectInterface.registerComposition(comp);
}
}
};