| import { |
| extendPrototype, |
| } from '../utils/functionExtensions'; |
| import createNS from '../utils/helpers/svg_elements'; |
| import createTag from '../utils/helpers/html_elements'; |
| import SVGRenderer from './SVGRenderer'; |
| import HSolidElement from '../elements/htmlElements/HSolidElement'; |
| import { |
| styleDiv, |
| } from '../utils/common'; |
| import BaseRenderer from './BaseRenderer'; |
| import IImageElement from '../elements/ImageElement'; |
| import SVGShapeElement from '../elements/svgElements/SVGShapeElement'; |
| import HShapeElement from '../elements/htmlElements/HShapeElement'; |
| import HTextElement from '../elements/htmlElements/HTextElement'; |
| import HCameraElement from '../elements/htmlElements/HCameraElement'; |
| import HImageElement from '../elements/htmlElements/HImageElement'; |
| import ISolidElement from '../elements/SolidElement'; |
| import SVGTextLottieElement from '../elements/svgElements/SVGTextElement'; |
| |
| function HybridRendererBase(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], HybridRendererBase); |
| |
| HybridRendererBase.prototype.buildItem = SVGRenderer.prototype.buildItem; |
| |
| HybridRendererBase.prototype.checkPendingElements = function () { |
| while (this.pendingElements.length) { |
| var element = this.pendingElements.pop(); |
| element.checkParenting(); |
| } |
| }; |
| |
| HybridRendererBase.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; |
| var nextLayer; |
| var 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); |
| } |
| }; |
| |
| HybridRendererBase.prototype.createShape = function (data) { |
| if (!this.supports3d) { |
| return new SVGShapeElement(data, this.globalData, this); |
| } |
| return new HShapeElement(data, this.globalData, this); |
| }; |
| |
| HybridRendererBase.prototype.createText = function (data) { |
| if (!this.supports3d) { |
| return new SVGTextLottieElement(data, this.globalData, this); |
| } |
| return new HTextElement(data, this.globalData, this); |
| }; |
| |
| HybridRendererBase.prototype.createCamera = function (data) { |
| this.camera = new HCameraElement(data, this.globalData, this); |
| return this.camera; |
| }; |
| |
| HybridRendererBase.prototype.createImage = function (data) { |
| if (!this.supports3d) { |
| return new IImageElement(data, this.globalData, this); |
| } |
| return new HImageElement(data, this.globalData, this); |
| }; |
| |
| HybridRendererBase.prototype.createSolid = function (data) { |
| if (!this.supports3d) { |
| return new ISolidElement(data, this.globalData, this); |
| } |
| return new HSolidElement(data, this.globalData, this); |
| }; |
| |
| HybridRendererBase.prototype.createNull = SVGRenderer.prototype.createNull; |
| |
| HybridRendererBase.prototype.getThreeDContainerByPos = function (pos) { |
| var i = 0; |
| var 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; |
| }; |
| |
| HybridRendererBase.prototype.createThreeDContainer = function (pos, type) { |
| var perspectiveElem = createTag('div'); |
| var style; |
| var containerStyle; |
| styleDiv(perspectiveElem); |
| var container = createTag('div'); |
| styleDiv(container); |
| if (type === '3d') { |
| style = perspectiveElem.style; |
| style.width = this.globalData.compSize.w + 'px'; |
| style.height = this.globalData.compSize.h + 'px'; |
| var center = '50% 50%'; |
| style.webkitTransformOrigin = center; |
| style.mozTransformOrigin = center; |
| style.transformOrigin = center; |
| containerStyle = container.style; |
| var matrix = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)'; |
| containerStyle.transform = matrix; |
| containerStyle.webkitTransform = matrix; |
| } |
| |
| 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; |
| }; |
| |
| HybridRendererBase.prototype.build3dContainers = function () { |
| var i; |
| var 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 -= 1) { |
| this.resizerElem.appendChild(this.threeDElements[i].perspectiveElem); |
| } |
| }; |
| |
| HybridRendererBase.prototype.addTo3dContainer = function (elem, pos) { |
| var i = 0; |
| var 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; |
| } |
| }; |
| |
| HybridRendererBase.prototype.configAnimation = function (animData) { |
| var resizerElem = createTag('div'); |
| var wrapper = this.animationItem.wrapper; |
| var style = resizerElem.style; |
| style.width = animData.w + 'px'; |
| style.height = animData.h + 'px'; |
| this.resizerElem = resizerElem; |
| styleDiv(resizerElem); |
| style.transformStyle = 'flat'; |
| style.mozTransformStyle = 'flat'; |
| style.webkitTransformStyle = 'flat'; |
| if (this.renderConfig.className) { |
| resizerElem.setAttribute('class', this.renderConfig.className); |
| } |
| wrapper.appendChild(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(); |
| }; |
| |
| HybridRendererBase.prototype.destroy = function () { |
| if (this.animationItem.wrapper) { |
| this.animationItem.wrapper.innerText = ''; |
| } |
| this.animationItem.container = null; |
| this.globalData.defs = null; |
| var i; |
| var len = this.layers ? this.layers.length : 0; |
| for (i = 0; i < len; i += 1) { |
| if (this.elements[i] && this.elements[i].destroy) { |
| this.elements[i].destroy(); |
| } |
| } |
| this.elements.length = 0; |
| this.destroyed = true; |
| this.animationItem = null; |
| }; |
| |
| HybridRendererBase.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; |
| var sy; |
| var tx; |
| var 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; |
| } |
| var style = this.resizerElem.style; |
| style.webkitTransform = 'matrix3d(' + sx + ',0,0,0,0,' + sy + ',0,0,0,0,1,0,' + tx + ',' + ty + ',0,1)'; |
| style.transform = style.webkitTransform; |
| }; |
| |
| HybridRendererBase.prototype.renderFrame = SVGRenderer.prototype.renderFrame; |
| |
| HybridRendererBase.prototype.hide = function () { |
| this.resizerElem.style.display = 'none'; |
| }; |
| |
| HybridRendererBase.prototype.show = function () { |
| this.resizerElem.style.display = 'block'; |
| }; |
| |
| HybridRendererBase.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; |
| var len = this.threeDElements.length; |
| for (i = 0; i < len; i += 1) { |
| var style = this.threeDElements[i].perspectiveElem.style; |
| style.webkitPerspective = Math.sqrt(Math.pow(cWidth, 2) + Math.pow(cHeight, 2)) + 'px'; |
| style.perspective = style.webkitPerspective; |
| } |
| } |
| }; |
| |
| HybridRendererBase.prototype.searchExtraCompositions = function (assets) { |
| var i; |
| var 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); |
| } |
| } |
| }; |
| |
| export default HybridRendererBase; |