blob: 20047de4d79871c0715bc6ea4c9307d884b87410 [file] [log] [blame]
function SVGRenderer(animationItem, config) {
this.animationItem = animationItem;
this.layers = null;
this.renderedFrame = -1;
this.svgElement = createNS('svg');
var ariaLabel = '';
if (config && config.title) {
var titleElement = createNS('title');
var titleId = createElementID();
titleElement.setAttribute('id', titleId);
titleElement.textContent = config.title;
this.svgElement.appendChild(titleElement);
ariaLabel += titleId;
}
if (config && config.description) {
var descElement = createNS('desc');
var descId = createElementID();
descElement.setAttribute('id', descId);
descElement.textContent = config.description;
this.svgElement.appendChild(descElement);
ariaLabel += ' ' + descId;
}
if (ariaLabel) {
this.svgElement.setAttribute('aria-labelledby', ariaLabel)
}
var defs = createNS( 'defs');
this.svgElement.appendChild(defs);
var maskElement = createNS('g');
this.svgElement.appendChild(maskElement);
this.layerElement = maskElement;
this.renderConfig = {
preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
progressiveLoad: (config && config.progressiveLoad) || false,
hideOnTransparent: (config && config.hideOnTransparent === false) ? false : true,
viewBoxOnly: (config && config.viewBoxOnly) || false,
viewBoxSize: (config && config.viewBoxSize) || false,
className: (config && config.className) || '',
id: (config && config.id) || '',
focusable: config && config.focusable,
filterSize: {
width: config && config.filterSize && config.filterSize.width || '100%',
height: config && config.filterSize && config.filterSize.height || '100%',
x: config && config.filterSize && config.filterSize.x || '0%',
y: config && config.filterSize && config.filterSize.y || '0%',
}
};
this.globalData = {
_mdf: false,
frameNum: -1,
defs: defs,
renderConfig: this.renderConfig
};
this.elements = [];
this.pendingElements = [];
this.destroyed = false;
this.rendererType = 'svg';
}
extendPrototype([BaseRenderer], SVGRenderer);
SVGRenderer.prototype.createNull = function (data) {
return new NullElement(data, this.globalData, this);
};
SVGRenderer.prototype.createShape = function (data) {
return new SVGShapeElement(data, this.globalData, this);
};
SVGRenderer.prototype.createText = function (data) {
return new SVGTextElement(data, this.globalData, this);
};
SVGRenderer.prototype.createImage = function (data) {
return new IImageElement(data, this.globalData, this);
};
SVGRenderer.prototype.createComp = function (data) {
return new SVGCompElement(data, this.globalData, this);
};
SVGRenderer.prototype.createSolid = function (data) {
return new ISolidElement(data, this.globalData, this);
};
SVGRenderer.prototype.configAnimation = function (animData) {
this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
if(this.renderConfig.viewBoxSize) {
this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
} else {
this.svgElement.setAttribute('viewBox', '0 0 '+animData.w+' '+animData.h);
}
if(!this.renderConfig.viewBoxOnly) {
this.svgElement.setAttribute('width', animData.w);
this.svgElement.setAttribute('height', animData.h);
this.svgElement.style.width = '100%';
this.svgElement.style.height = '100%';
this.svgElement.style.transform = 'translate3d(0,0,0)';
}
if (this.renderConfig.className) {
this.svgElement.setAttribute('class', this.renderConfig.className);
}
if (this.renderConfig.id) {
this.svgElement.setAttribute('id', this.renderConfig.id);
}
if (this.renderConfig.focusable !== undefined) {
this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
}
this.svgElement.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.svgElement);
// Mask animation
var defs = this.globalData.defs;
this.setupGlobalData(animData, defs);
this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
this.data = animData;
var maskElement = createNS( 'clipPath');
var rect = createNS('rect');
rect.setAttribute('width', animData.w);
rect.setAttribute('height', animData.h);
rect.setAttribute('x', 0);
rect.setAttribute('y', 0);
var maskId = createElementID();
maskElement.setAttribute('id', maskId);
maskElement.appendChild(rect);
this.layerElement.setAttribute('clip-path', 'url(' + locationHref + '#'+maskId+')');
defs.appendChild(maskElement);
this.layers = animData.layers;
this.elements = createSizedArray(animData.layers.length);
};
SVGRenderer.prototype.destroy = function () {
if (this.animationItem.wrapper) {
this.animationItem.wrapper.innerText = '';
}
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;
}
// console.log('-------');
// console.log('FRAME ',num);
this.globalData.frameNum = num;
this.globalData.frameId += 1;
this.globalData.projectInterface.currentFrame = num;
this.globalData._mdf = false;
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);
}
}
if(this.globalData._mdf) {
for (i = 0; i < len; i += 1) {
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';
};