UNPKG

bodymovin

Version:

After Effects plugin for exporting animations to SVG + JavaScript or canvas + JavaScript

219 lines (201 loc) 8.38 kB
function SVGTextElement(data,parentContainer,globalData,comp, placeholder){ this.textSpans = []; this.renderType = 'svg'; this._parent.constructor.call(this,data,parentContainer,globalData,comp, placeholder); } createElement(SVGBaseElement, SVGTextElement); extendPrototype(ITextElement, SVGTextElement); SVGTextElement.prototype.createElements = function(){ this._parent.createElements.call(this); if(this.data.ln){ this.layerElement.setAttribute('id',this.data.ln); } if(this.data.cl){ this.layerElement.setAttribute('class',this.data.cl); } if (this.data.singleShape && !this.globalData.fontManager.chars) { this.textContainer = document.createElementNS(svgNS,'text'); } }; SVGTextElement.prototype.buildNewText = function(){ var i, len; var documentData = this.textProperty.currentData; this.renderedLetters = Array.apply(null,{length:documentData ? documentData.l.length : 0}); if(documentData.fc) { this.layerElement.setAttribute('fill', this.buildColor(documentData.fc)); }else{ this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)'); } if(documentData.sc){ this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc)); this.layerElement.setAttribute('stroke-width', documentData.sw); } this.layerElement.setAttribute('font-size', documentData.s); var fontData = this.globalData.fontManager.getFontByName(documentData.f); if(fontData.fClass){ this.layerElement.setAttribute('class',fontData.fClass); } else { this.layerElement.setAttribute('font-family', fontData.fFamily); var fWeight = documentData.fWeight, fStyle = documentData.fStyle; this.layerElement.setAttribute('font-style', fStyle); this.layerElement.setAttribute('font-weight', fWeight); } var letters = documentData.l || []; var usesGlyphs = this.globalData.fontManager.chars; len = letters.length; if(!len){ return; } var tSpan; var matrixHelper = this.mHelper; var shapes, shapeStr = '', singleShape = this.data.singleShape; var xPos = 0, yPos = 0, firstLine = true; var trackingOffset = documentData.tr/1000*documentData.s; if(singleShape && !usesGlyphs) { var tElement = this.textContainer; var justify = ''; switch(documentData.j) { case 1: justify = 'end'; break; case 2: justify = 'middle'; break; case 2: justify = 'start'; break; } tElement.setAttribute('text-anchor',justify); tElement.setAttribute('letter-spacing',trackingOffset); var textContent = documentData.t.split(String.fromCharCode(13)); len = textContent.length; var yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0; for ( i = 0; i < len; i += 1) { tSpan = this.textSpans[i] || document.createElementNS(svgNS,'tspan'); tSpan.textContent = textContent[i]; tSpan.setAttribute('x', 0); tSpan.setAttribute('y', yPos); tSpan.style.display = 'inherit'; tElement.appendChild(tSpan); this.textSpans[i] = tSpan; yPos += documentData.lh; } this.layerElement.appendChild(tElement); } else { var cachedSpansLength = this.textSpans.length; var shapeData, charData; for (i = 0; i < len; i += 1) { if(!usesGlyphs || !singleShape || i === 0){ tSpan = cachedSpansLength > i ? this.textSpans[i] : document.createElementNS(svgNS,usesGlyphs?'path':'text'); if (cachedSpansLength <= i) { tSpan.setAttribute('stroke-linecap', 'butt'); tSpan.setAttribute('stroke-linejoin','round'); tSpan.setAttribute('stroke-miterlimit','4'); this.textSpans[i] = tSpan; this.layerElement.appendChild(tSpan); } tSpan.style.display = 'inherit'; } matrixHelper.reset(); if(usesGlyphs) { matrixHelper.scale(documentData.s / 100, documentData.s / 100); if (singleShape) { if(letters[i].n) { xPos = -trackingOffset; yPos += documentData.yOffset; yPos += firstLine ? 1 : 0; firstLine = false; } this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos); xPos += letters[i].l || 0; //xPos += letters[i].val === ' ' ? 0 : trackingOffset; xPos += trackingOffset; } charData = this.globalData.fontManager.getCharData(documentData.t.charAt(i), fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily); shapeData = charData && charData.data || {}; shapes = shapeData.shapes ? shapeData.shapes[0].it : []; if(!singleShape){ tSpan.setAttribute('d',this.createPathShape(matrixHelper,shapes)); } else { shapeStr += this.createPathShape(matrixHelper,shapes); } } else { tSpan.textContent = letters[i].val; tSpan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space","preserve"); } // } if (singleShape) { tSpan.setAttribute('d',shapeStr); } } while (i < this.textSpans.length){ this.textSpans[i].style.display = 'none'; i += 1; } this._sizeChanged = true; } SVGTextElement.prototype.sourceRectAtTime = function(time){ this.prepareFrame(this.comp.renderedFrame - this.data.st); this.renderLetters(); if(this._sizeChanged){ this._sizeChanged = false; var textBox = this.layerElement.getBBox(); this.bbox = { top: textBox.y, left: textBox.x, width: textBox.width, height: textBox.height } } return this.bbox; } SVGTextElement.prototype.renderLetters = function(){ if(!this.data.singleShape){ this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag); if(this.lettersChangedFlag || this.textAnimator.lettersChangedFlag){ this._sizeChanged = true; var i,len; var renderedLetters = this.textAnimator.renderedLetters; var letters = this.textProperty.currentData.l; len = letters.length; var renderedLetter, textSpan; for(i=0;i<len;i+=1){ if(letters[i].n){ continue; } renderedLetter = renderedLetters[i]; textSpan = this.textSpans[i]; if(renderedLetter.mdf.m) { textSpan.setAttribute('transform',renderedLetter.m); } if(renderedLetter.mdf.o) { textSpan.setAttribute('opacity',renderedLetter.o); } if(renderedLetter.mdf.sw){ textSpan.setAttribute('stroke-width',renderedLetter.sw); } if(renderedLetter.mdf.sc){ textSpan.setAttribute('stroke',renderedLetter.sc); } if(renderedLetter.mdf.fc){ textSpan.setAttribute('fill',renderedLetter.fc); } } } } } SVGTextElement.prototype.renderFrame = function(parentMatrix){ var renderParent = this._parent.renderFrame.call(this,parentMatrix); if(renderParent===false){ this.hide(); return; } if(this.hidden){ this.show(); } if(this.firstFrame) { this.firstFrame = false; } this.renderLetters(); }