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;