| import { |
| extendPrototype, |
| } from '../../utils/functionExtensions'; |
| import { |
| createSizedArray, |
| } from '../../utils/helpers/arrays'; |
| import createNS from '../../utils/helpers/svg_elements'; |
| import BaseElement from '../BaseElement'; |
| import TransformElement from '../helpers/TransformElement'; |
| import SVGBaseElement from './SVGBaseElement'; |
| import HierarchyElement from '../helpers/HierarchyElement'; |
| import FrameElement from '../helpers/FrameElement'; |
| import RenderableDOMElement from '../helpers/RenderableDOMElement'; |
| import ITextElement from '../TextElement'; |
| import SVGCompElement from './SVGCompElement'; // eslint-disable-line |
| import SVGShapeElement from './SVGShapeElement'; |
| |
| function SVGTextLottieElement(data, globalData, comp) { |
| this.textSpans = []; |
| this.renderType = 'svg'; |
| this.initElement(data, globalData, comp); |
| } |
| |
| extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement); |
| |
| SVGTextLottieElement.prototype.createContent = function () { |
| if (this.data.singleShape && !this.globalData.fontManager.chars) { |
| this.textContainer = createNS('text'); |
| } |
| }; |
| |
| SVGTextLottieElement.prototype.buildTextContents = function (textArray) { |
| var i = 0; |
| var len = textArray.length; |
| var textContents = []; |
| var currentTextContent = ''; |
| while (i < len) { |
| if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) { |
| textContents.push(currentTextContent); |
| currentTextContent = ''; |
| } else { |
| currentTextContent += textArray[i]; |
| } |
| i += 1; |
| } |
| textContents.push(currentTextContent); |
| return textContents; |
| }; |
| |
| SVGTextLottieElement.prototype.buildNewText = function () { |
| this.addDynamicProperty(this); |
| var i; |
| var len; |
| |
| var documentData = this.textProperty.currentData; |
| this.renderedLetters = createSizedArray(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.finalSize); |
| 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; |
| var fStyle = documentData.fStyle; |
| this.layerElement.setAttribute('font-style', fStyle); |
| this.layerElement.setAttribute('font-weight', fWeight); |
| } |
| this.layerElement.setAttribute('aria-label', documentData.t); |
| |
| var letters = documentData.l || []; |
| var usesGlyphs = !!this.globalData.fontManager.chars; |
| len = letters.length; |
| |
| var tSpan; |
| var matrixHelper = this.mHelper; |
| var shapeStr = ''; |
| var singleShape = this.data.singleShape; |
| var xPos = 0; |
| var yPos = 0; |
| var firstLine = true; |
| var trackingOffset = documentData.tr * 0.001 * documentData.finalSize; |
| if (singleShape && !usesGlyphs && !documentData.sz) { |
| var tElement = this.textContainer; |
| var justify = 'start'; |
| switch (documentData.j) { |
| case 1: |
| justify = 'end'; |
| break; |
| case 2: |
| justify = 'middle'; |
| break; |
| default: |
| justify = 'start'; |
| break; |
| } |
| tElement.setAttribute('text-anchor', justify); |
| tElement.setAttribute('letter-spacing', trackingOffset); |
| var textContent = this.buildTextContents(documentData.finalText); |
| len = textContent.length; |
| yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0; |
| for (i = 0; i < len; i += 1) { |
| tSpan = this.textSpans[i].span || createNS('tspan'); |
| tSpan.textContent = textContent[i]; |
| tSpan.setAttribute('x', 0); |
| tSpan.setAttribute('y', yPos); |
| tSpan.style.display = 'inherit'; |
| tElement.appendChild(tSpan); |
| if (!this.textSpans[i]) { |
| this.textSpans[i] = { |
| span: null, |
| glyph: null, |
| }; |
| } |
| this.textSpans[i].span = tSpan; |
| yPos += documentData.finalLineHeight; |
| } |
| |
| this.layerElement.appendChild(tElement); |
| } else { |
| var cachedSpansLength = this.textSpans.length; |
| var charData; |
| for (i = 0; i < len; i += 1) { |
| if (!this.textSpans[i]) { |
| this.textSpans[i] = { |
| span: null, |
| childSpan: null, |
| glyph: null, |
| }; |
| } |
| if (!usesGlyphs || !singleShape || i === 0) { |
| tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text'); |
| if (cachedSpansLength <= i) { |
| tSpan.setAttribute('stroke-linecap', 'butt'); |
| tSpan.setAttribute('stroke-linejoin', 'round'); |
| tSpan.setAttribute('stroke-miterlimit', '4'); |
| this.textSpans[i].span = tSpan; |
| if (usesGlyphs) { |
| var childSpan = createNS('g'); |
| tSpan.appendChild(childSpan); |
| this.textSpans[i].childSpan = childSpan; |
| } |
| this.textSpans[i].span = tSpan; |
| this.layerElement.appendChild(tSpan); |
| } |
| tSpan.style.display = 'inherit'; |
| } |
| |
| matrixHelper.reset(); |
| matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 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; |
| } |
| if (usesGlyphs) { |
| charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily); |
| var glyphElement; |
| if (charData.t === 1) { |
| glyphElement = new SVGCompElement(charData.data, this.globalData, this); |
| } else { |
| glyphElement = new SVGShapeElement(charData.data, this.globalData, this); |
| } |
| this.textSpans[i].glyph = glyphElement; |
| glyphElement._debug = true; |
| glyphElement.prepareFrame(0); |
| glyphElement.renderFrame(); |
| this.textSpans[i].childSpan.appendChild(glyphElement.layerElement); |
| this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')'); |
| } else { |
| if (singleShape) { |
| tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')'); |
| } |
| tSpan.textContent = letters[i].val; |
| tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve'); |
| } |
| // |
| } |
| if (singleShape && tSpan) { |
| tSpan.setAttribute('d', shapeStr); |
| } |
| } |
| while (i < this.textSpans.length) { |
| this.textSpans[i].span.style.display = 'none'; |
| i += 1; |
| } |
| |
| this._sizeChanged = true; |
| }; |
| |
| SVGTextLottieElement.prototype.sourceRectAtTime = function () { |
| this.prepareFrame(this.comp.renderedFrame - this.data.st); |
| this.renderInnerContent(); |
| 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; |
| }; |
| |
| SVGTextLottieElement.prototype.getValue = function () { |
| var i; |
| var len = this.textSpans.length; |
| var glyphElement; |
| this.renderedFrame = this.comp.renderedFrame; |
| for (i = 0; i < len; i += 1) { |
| glyphElement = this.textSpans[i].glyph; |
| glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st); |
| if (glyphElement._mdf) { |
| this._mdf = true; |
| } |
| } |
| }; |
| |
| SVGTextLottieElement.prototype.renderInnerContent = function () { |
| if (!this.data.singleShape || this._mdf) { |
| this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag); |
| if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) { |
| this._sizeChanged = true; |
| var i; |
| var len; |
| var renderedLetters = this.textAnimator.renderedLetters; |
| |
| var letters = this.textProperty.currentData.l; |
| |
| len = letters.length; |
| var renderedLetter; |
| var textSpan; |
| var glyphElement; |
| for (i = 0; i < len; i += 1) { |
| if (!letters[i].n) { |
| renderedLetter = renderedLetters[i]; |
| textSpan = this.textSpans[i].span; |
| glyphElement = this.textSpans[i].glyph; |
| glyphElement.renderFrame(); |
| 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); |
| } |
| } |
| } |
| } |
| } |
| }; |
| |
| export default SVGTextLottieElement; |