feat: 第一次上传代码

This commit is contained in:
2025-06-29 23:41:37 +08:00
commit 875c60d3ec
478 changed files with 385642 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
function LetterProps(o, sw, sc, fc, m, p) {
this.o = o;
this.sw = sw;
this.sc = sc;
this.fc = fc;
this.m = m;
this.p = p;
this._mdf = {
o: true,
sw: !!sw,
sc: !!sc,
fc: !!fc,
m: true,
p: true,
};
}
LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
this._mdf.o = false;
this._mdf.sw = false;
this._mdf.sc = false;
this._mdf.fc = false;
this._mdf.m = false;
this._mdf.p = false;
var updated = false;
if (this.o !== o) {
this.o = o;
this._mdf.o = true;
updated = true;
}
if (this.sw !== sw) {
this.sw = sw;
this._mdf.sw = true;
updated = true;
}
if (this.sc !== sc) {
this.sc = sc;
this._mdf.sc = true;
updated = true;
}
if (this.fc !== fc) {
this.fc = fc;
this._mdf.fc = true;
updated = true;
}
if (this.m !== m) {
this.m = m;
this._mdf.m = true;
updated = true;
}
if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
this.p = p;
this._mdf.p = true;
updated = true;
}
return updated;
};
export default LetterProps;

View File

@@ -0,0 +1,34 @@
import {
degToRads,
} from '../common';
import PropertyFactory from '../PropertyFactory';
import TextSelectorProp from './TextSelectorProperty';
function TextAnimatorDataProperty(elem, animatorProps, container) {
var defaultData = { propType: false };
var getProp = PropertyFactory.getProp;
var textAnimatorAnimatables = animatorProps.a;
this.a = {
r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData,
rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData,
ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData,
sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData,
sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData,
s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData,
a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData,
o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData,
p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData,
sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData,
sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData,
fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData,
fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData,
fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData,
fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData,
t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData,
};
this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container);
this.s.t = animatorProps.s.t;
}
export default TextAnimatorDataProperty;

View File

@@ -0,0 +1,610 @@
import {
addSaturationToRGB,
addBrightnessToRGB,
addHueToRGB,
} from '../common';
import {
extendPrototype,
} from '../functionExtensions';
import DynamicPropertyContainer from '../helpers/dynamicProperties';
import {
createSizedArray,
} from '../helpers/arrays';
import PropertyFactory from '../PropertyFactory';
import bez from '../bez';
import Matrix from '../../3rd_party/transformation-matrix';
import TextAnimatorDataProperty from './TextAnimatorDataProperty';
import LetterProps from './LetterProps';
function TextAnimatorProperty(textData, renderType, elem) {
this._isFirstFrame = true;
this._hasMaskedPath = false;
this._frameId = -1;
this._textData = textData;
this._renderType = renderType;
this._elem = elem;
this._animatorsData = createSizedArray(this._textData.a.length);
this._pathData = {};
this._moreOptions = {
alignment: {},
};
this.renderedLetters = [];
this.lettersChangedFlag = false;
this.initDynamicPropertyContainer(elem);
}
TextAnimatorProperty.prototype.searchProperties = function () {
var i;
var len = this._textData.a.length;
var animatorProps;
var getProp = PropertyFactory.getProp;
for (i = 0; i < len; i += 1) {
animatorProps = this._textData.a[i];
this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
}
if (this._textData.p && 'm' in this._textData.p) {
this._pathData = {
a: getProp(this._elem, this._textData.p.a, 0, 0, this),
f: getProp(this._elem, this._textData.p.f, 0, 0, this),
l: getProp(this._elem, this._textData.p.l, 0, 0, this),
r: getProp(this._elem, this._textData.p.r, 0, 0, this),
p: getProp(this._elem, this._textData.p.p, 0, 0, this),
m: this._elem.maskManager.getMaskProperty(this._textData.p.m),
};
this._hasMaskedPath = true;
} else {
this._hasMaskedPath = false;
}
this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
};
TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
this.lettersChangedFlag = lettersChangedFlag;
if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
return;
}
this._isFirstFrame = false;
var alignment = this._moreOptions.alignment.v;
var animators = this._animatorsData;
var textData = this._textData;
var matrixHelper = this.mHelper;
var renderType = this._renderType;
var renderedLettersCount = this.renderedLetters.length;
var xPos;
var yPos;
var i;
var len;
var letters = documentData.l;
var pathInfo;
var currentLength;
var currentPoint;
var segmentLength;
var flag;
var pointInd;
var segmentInd;
var prevPoint;
var points;
var segments;
var partialLength;
var totalLength;
var perc;
var tanAngle;
var mask;
if (this._hasMaskedPath) {
mask = this._pathData.m;
if (!this._pathData.n || this._pathData._mdf) {
var paths = mask.v;
if (this._pathData.r.v) {
paths = paths.reverse();
}
// TODO: release bezier data cached from previous pathInfo: this._pathData.pi
pathInfo = {
tLength: 0,
segments: [],
};
len = paths._length - 1;
var bezierData;
totalLength = 0;
for (i = 0; i < len; i += 1) {
bezierData = bez.buildBezierData(paths.v[i],
paths.v[i + 1],
[paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
[paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
pathInfo.tLength += bezierData.segmentLength;
pathInfo.segments.push(bezierData);
totalLength += bezierData.segmentLength;
}
i = len;
if (mask.v.c) {
bezierData = bez.buildBezierData(paths.v[i],
paths.v[0],
[paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
[paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
pathInfo.tLength += bezierData.segmentLength;
pathInfo.segments.push(bezierData);
totalLength += bezierData.segmentLength;
}
this._pathData.pi = pathInfo;
}
pathInfo = this._pathData.pi;
currentLength = this._pathData.f.v;
segmentInd = 0;
pointInd = 1;
segmentLength = 0;
flag = true;
segments = pathInfo.segments;
if (currentLength < 0 && mask.v.c) {
if (pathInfo.tLength < Math.abs(currentLength)) {
currentLength = -Math.abs(currentLength) % pathInfo.tLength;
}
segmentInd = segments.length - 1;
points = segments[segmentInd].points;
pointInd = points.length - 1;
while (currentLength < 0) {
currentLength += points[pointInd].partialLength;
pointInd -= 1;
if (pointInd < 0) {
segmentInd -= 1;
points = segments[segmentInd].points;
pointInd = points.length - 1;
}
}
}
points = segments[segmentInd].points;
prevPoint = points[pointInd - 1];
currentPoint = points[pointInd];
partialLength = currentPoint.partialLength;
}
len = letters.length;
xPos = 0;
yPos = 0;
var yOff = documentData.finalSize * 1.2 * 0.714;
var firstLine = true;
var animatorProps;
var animatorSelector;
var j;
var jLen;
var letterValue;
jLen = animators.length;
var mult;
var ind = -1;
var offf;
var xPathPos;
var yPathPos;
var initPathPos = currentLength;
var initSegmentInd = segmentInd;
var initPointInd = pointInd;
var currentLine = -1;
var elemOpacity;
var sc;
var sw;
var fc;
var k;
var letterSw;
var letterSc;
var letterFc;
var letterM = '';
var letterP = this.defaultPropsArray;
var letterO;
//
if (documentData.j === 2 || documentData.j === 1) {
var animatorJustifyOffset = 0;
var animatorFirstCharOffset = 0;
var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
var lastIndex = 0;
var isNewLine = true;
for (i = 0; i < len; i += 1) {
if (letters[i].n) {
if (animatorJustifyOffset) {
animatorJustifyOffset += animatorFirstCharOffset;
}
while (lastIndex < i) {
letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
lastIndex += 1;
}
animatorJustifyOffset = 0;
isNewLine = true;
} else {
for (j = 0; j < jLen; j += 1) {
animatorProps = animators[j].a;
if (animatorProps.t.propType) {
if (isNewLine && documentData.j === 2) {
animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
}
animatorSelector = animators[j].s;
mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
if (mult.length) {
animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
} else {
animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult;
}
}
}
isNewLine = false;
}
}
if (animatorJustifyOffset) {
animatorJustifyOffset += animatorFirstCharOffset;
}
while (lastIndex < i) {
letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
lastIndex += 1;
}
}
//
for (i = 0; i < len; i += 1) {
matrixHelper.reset();
elemOpacity = 1;
if (letters[i].n) {
xPos = 0;
yPos += documentData.yOffset;
yPos += firstLine ? 1 : 0;
currentLength = initPathPos;
firstLine = false;
if (this._hasMaskedPath) {
segmentInd = initSegmentInd;
pointInd = initPointInd;
points = segments[segmentInd].points;
prevPoint = points[pointInd - 1];
currentPoint = points[pointInd];
partialLength = currentPoint.partialLength;
segmentLength = 0;
}
letterM = '';
letterFc = '';
letterSw = '';
letterO = '';
letterP = this.defaultPropsArray;
} else {
if (this._hasMaskedPath) {
if (currentLine !== letters[i].line) {
switch (documentData.j) {
case 1:
currentLength += totalLength - documentData.lineWidths[letters[i].line];
break;
case 2:
currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
break;
default:
break;
}
currentLine = letters[i].line;
}
if (ind !== letters[i].ind) {
if (letters[ind]) {
currentLength += letters[ind].extra;
}
currentLength += letters[i].an / 2;
ind = letters[i].ind;
}
currentLength += (alignment[0] * letters[i].an) * 0.005;
var animatorOffset = 0;
for (j = 0; j < jLen; j += 1) {
animatorProps = animators[j].a;
if (animatorProps.p.propType) {
animatorSelector = animators[j].s;
mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
if (mult.length) {
animatorOffset += animatorProps.p.v[0] * mult[0];
} else {
animatorOffset += animatorProps.p.v[0] * mult;
}
}
if (animatorProps.a.propType) {
animatorSelector = animators[j].s;
mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
if (mult.length) {
animatorOffset += animatorProps.a.v[0] * mult[0];
} else {
animatorOffset += animatorProps.a.v[0] * mult;
}
}
}
flag = true;
// Force alignment only works with a single line for now
if (this._pathData.a.v) {
currentLength = letters[0].an * 0.5 + ((totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind) / (len - 1);
currentLength += this._pathData.f.v;
}
while (flag) {
if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, -(alignment[1] * yOff) * 0.01);
flag = false;
} else if (points) {
segmentLength += currentPoint.partialLength;
pointInd += 1;
if (pointInd >= points.length) {
pointInd = 0;
segmentInd += 1;
if (!segments[segmentInd]) {
if (mask.v.c) {
pointInd = 0;
segmentInd = 0;
points = segments[segmentInd].points;
} else {
segmentLength -= currentPoint.partialLength;
points = null;
}
} else {
points = segments[segmentInd].points;
}
}
if (points) {
prevPoint = currentPoint;
currentPoint = points[pointInd];
partialLength = currentPoint.partialLength;
}
}
}
offf = letters[i].an / 2 - letters[i].add;
matrixHelper.translate(-offf, 0, 0);
} else {
offf = letters[i].an / 2 - letters[i].add;
matrixHelper.translate(-offf, 0, 0);
// Grouping alignment
matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, (-alignment[1] * yOff) * 0.01, 0);
}
for (j = 0; j < jLen; j += 1) {
animatorProps = animators[j].a;
if (animatorProps.t.propType) {
animatorSelector = animators[j].s;
mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
// This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
if (xPos !== 0 || documentData.j !== 0) {
if (this._hasMaskedPath) {
if (mult.length) {
currentLength += animatorProps.t.v * mult[0];
} else {
currentLength += animatorProps.t.v * mult;
}
} else if (mult.length) {
xPos += animatorProps.t.v * mult[0];
} else {
xPos += animatorProps.t.v * mult;
}
}
}
}
if (documentData.strokeWidthAnim) {
sw = documentData.sw || 0;
}
if (documentData.strokeColorAnim) {
if (documentData.sc) {
sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
} else {
sc = [0, 0, 0];
}
}
if (documentData.fillColorAnim && documentData.fc) {
fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
}
for (j = 0; j < jLen; j += 1) {
animatorProps = animators[j].a;
if (animatorProps.a.propType) {
animatorSelector = animators[j].s;
mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
if (mult.length) {
matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
} else {
matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult);
}
}
}
for (j = 0; j < jLen; j += 1) {
animatorProps = animators[j].a;
if (animatorProps.s.propType) {
animatorSelector = animators[j].s;
mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
if (mult.length) {
matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult[0]), 1 + ((animatorProps.s.v[1] - 1) * mult[1]), 1);
} else {
matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult), 1 + ((animatorProps.s.v[1] - 1) * mult), 1);
}
}
}
for (j = 0; j < jLen; j += 1) {
animatorProps = animators[j].a;
animatorSelector = animators[j].s;
mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
if (animatorProps.sk.propType) {
if (mult.length) {
matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
} else {
matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
}
}
if (animatorProps.r.propType) {
if (mult.length) {
matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
} else {
matrixHelper.rotateZ(-animatorProps.r.v * mult);
}
}
if (animatorProps.ry.propType) {
if (mult.length) {
matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
} else {
matrixHelper.rotateY(animatorProps.ry.v * mult);
}
}
if (animatorProps.rx.propType) {
if (mult.length) {
matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
} else {
matrixHelper.rotateX(animatorProps.rx.v * mult);
}
}
if (animatorProps.o.propType) {
if (mult.length) {
elemOpacity += ((animatorProps.o.v) * mult[0] - elemOpacity) * mult[0];
} else {
elemOpacity += ((animatorProps.o.v) * mult - elemOpacity) * mult;
}
}
if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
if (mult.length) {
sw += animatorProps.sw.v * mult[0];
} else {
sw += animatorProps.sw.v * mult;
}
}
if (documentData.strokeColorAnim && animatorProps.sc.propType) {
for (k = 0; k < 3; k += 1) {
if (mult.length) {
sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0];
} else {
sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult;
}
}
}
if (documentData.fillColorAnim && documentData.fc) {
if (animatorProps.fc.propType) {
for (k = 0; k < 3; k += 1) {
if (mult.length) {
fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0];
} else {
fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult;
}
}
}
if (animatorProps.fh.propType) {
if (mult.length) {
fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
} else {
fc = addHueToRGB(fc, animatorProps.fh.v * mult);
}
}
if (animatorProps.fs.propType) {
if (mult.length) {
fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
} else {
fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
}
}
if (animatorProps.fb.propType) {
if (mult.length) {
fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
} else {
fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult);
}
}
}
}
for (j = 0; j < jLen; j += 1) {
animatorProps = animators[j].a;
if (animatorProps.p.propType) {
animatorSelector = animators[j].s;
mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
if (this._hasMaskedPath) {
if (mult.length) {
matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
} else {
matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
}
} else if (mult.length) {
matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
} else {
matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
}
}
}
if (documentData.strokeWidthAnim) {
letterSw = sw < 0 ? 0 : sw;
}
if (documentData.strokeColorAnim) {
letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
}
if (documentData.fillColorAnim && documentData.fc) {
letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
}
if (this._hasMaskedPath) {
matrixHelper.translate(0, -documentData.ls);
matrixHelper.translate(0, (alignment[1] * yOff) * 0.01 + yPos, 0);
if (this._pathData.p.v) {
tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
var rot = (Math.atan(tanAngle) * 180) / Math.PI;
if (currentPoint.point[0] < prevPoint.point[0]) {
rot += 180;
}
matrixHelper.rotate((-rot * Math.PI) / 180);
}
matrixHelper.translate(xPathPos, yPathPos, 0);
currentLength -= (alignment[0] * letters[i].an) * 0.005;
if (letters[i + 1] && ind !== letters[i + 1].ind) {
currentLength += letters[i].an / 2;
currentLength += (documentData.tr * 0.001) * documentData.finalSize;
}
} else {
matrixHelper.translate(xPos, yPos, 0);
if (documentData.ps) {
// matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
}
switch (documentData.j) {
case 1:
matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
break;
case 2:
matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
break;
default:
break;
}
matrixHelper.translate(0, -documentData.ls);
matrixHelper.translate(offf, 0, 0);
matrixHelper.translate((alignment[0] * letters[i].an) * 0.005, (alignment[1] * yOff) * 0.01, 0);
xPos += letters[i].l + (documentData.tr * 0.001) * documentData.finalSize;
}
if (renderType === 'html') {
letterM = matrixHelper.toCSS();
} else if (renderType === 'svg') {
letterM = matrixHelper.to2dCSS();
} else {
letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
}
letterO = elemOpacity;
}
if (renderedLettersCount <= i) {
letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
this.renderedLetters.push(letterValue);
renderedLettersCount += 1;
this.lettersChangedFlag = true;
} else {
letterValue = this.renderedLetters[i];
this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag;
}
}
};
TextAnimatorProperty.prototype.getValue = function () {
if (this._elem.globalData.frameId === this._frameId) {
return;
}
this._frameId = this._elem.globalData.frameId;
this.iterateDynamicProperties();
};
TextAnimatorProperty.prototype.mHelper = new Matrix();
TextAnimatorProperty.prototype.defaultPropsArray = [];
extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
export default TextAnimatorProperty;

View File

@@ -0,0 +1,461 @@
import {
initialDefaultFrame,
} from '../../main';
import getFontProperties from '../getFontProperties';
import FontManager from '../FontManager';
function TextProperty(elem, data) {
this._frameId = initialDefaultFrame;
this.pv = '';
this.v = '';
this.kf = false;
this._isFirstFrame = true;
this._mdf = false;
if (data.d && data.d.sid) {
data.d = elem.globalData.slotManager.getProp(data.d);
}
this.data = data;
this.elem = elem;
this.comp = this.elem.comp;
this.keysIndex = 0;
this.canResize = false;
this.minimumFontSize = 1;
this.effectsSequence = [];
this.currentData = {
ascent: 0,
boxWidth: this.defaultBoxWidth,
f: '',
fStyle: '',
fWeight: '',
fc: '',
j: '',
justifyOffset: '',
l: [],
lh: 0,
lineWidths: [],
ls: '',
of: '',
s: '',
sc: '',
sw: 0,
t: 0,
tr: 0,
sz: 0,
ps: null,
fillColorAnim: false,
strokeColorAnim: false,
strokeWidthAnim: false,
yOffset: 0,
finalSize: 0,
finalText: [],
finalLineHeight: 0,
__complete: false,
};
this.copyData(this.currentData, this.data.d.k[0].s);
if (!this.searchProperty()) {
this.completeTextData(this.currentData);
}
}
TextProperty.prototype.defaultBoxWidth = [0, 0];
TextProperty.prototype.copyData = function (obj, data) {
for (var s in data) {
if (Object.prototype.hasOwnProperty.call(data, s)) {
obj[s] = data[s];
}
}
return obj;
};
TextProperty.prototype.setCurrentData = function (data) {
if (!data.__complete) {
this.completeTextData(data);
}
this.currentData = data;
this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
this._mdf = true;
};
TextProperty.prototype.searchProperty = function () {
return this.searchKeyframes();
};
TextProperty.prototype.searchKeyframes = function () {
this.kf = this.data.d.k.length > 1;
if (this.kf) {
this.addEffect(this.getKeyframeValue.bind(this));
}
return this.kf;
};
TextProperty.prototype.addEffect = function (effectFunction) {
this.effectsSequence.push(effectFunction);
this.elem.addDynamicProperty(this);
};
TextProperty.prototype.getValue = function (_finalValue) {
if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
return;
}
this.currentData.t = this.data.d.k[this.keysIndex].s.t;
var currentValue = this.currentData;
var currentIndex = this.keysIndex;
if (this.lock) {
this.setCurrentData(this.currentData);
return;
}
this.lock = true;
this._mdf = false;
var i; var
len = this.effectsSequence.length;
var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
for (i = 0; i < len; i += 1) {
// Checking if index changed to prevent creating a new object every time the expression updates.
if (currentIndex !== this.keysIndex) {
finalValue = this.effectsSequence[i](finalValue, finalValue.t);
} else {
finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
}
}
if (currentValue !== finalValue) {
this.setCurrentData(finalValue);
}
this.v = this.currentData;
this.pv = this.v;
this.lock = false;
this.frameId = this.elem.globalData.frameId;
};
TextProperty.prototype.getKeyframeValue = function () {
var textKeys = this.data.d.k;
var frameNum = this.elem.comp.renderedFrame;
var i = 0; var
len = textKeys.length;
while (i <= len - 1) {
if (i === len - 1 || textKeys[i + 1].t > frameNum) {
break;
}
i += 1;
}
if (this.keysIndex !== i) {
this.keysIndex = i;
}
return this.data.d.k[this.keysIndex].s;
};
TextProperty.prototype.buildFinalText = function (text) {
var charactersArray = [];
var i = 0;
var len = text.length;
var charCode;
var secondCharCode;
var shouldCombine = false;
var shouldCombineNext = false;
var currentChars = '';
while (i < len) {
shouldCombine = shouldCombineNext;
shouldCombineNext = false;
charCode = text.charCodeAt(i);
currentChars = text.charAt(i);
if (FontManager.isCombinedCharacter(charCode)) {
shouldCombine = true;
// It's a potential surrogate pair (this is the High surrogate)
} else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
if (FontManager.isRegionalFlag(text, i)) {
currentChars = text.substr(i, 14);
} else {
secondCharCode = text.charCodeAt(i + 1);
// It's a surrogate pair (this is the Low surrogate)
if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
if (FontManager.isModifier(charCode, secondCharCode)) {
currentChars = text.substr(i, 2);
shouldCombine = true;
} else if (FontManager.isFlagEmoji(text.substr(i, 4))) {
currentChars = text.substr(i, 4);
} else {
currentChars = text.substr(i, 2);
}
}
}
} else if (charCode > 0xDBFF) {
secondCharCode = text.charCodeAt(i + 1);
if (FontManager.isVariationSelector(charCode)) {
shouldCombine = true;
}
} else if (FontManager.isZeroWidthJoiner(charCode)) {
shouldCombine = true;
shouldCombineNext = true;
}
if (shouldCombine) {
charactersArray[charactersArray.length - 1] += currentChars;
shouldCombine = false;
} else {
charactersArray.push(currentChars);
}
i += currentChars.length;
}
return charactersArray;
};
TextProperty.prototype.completeTextData = function (documentData) {
documentData.__complete = true;
var fontManager = this.elem.globalData.fontManager;
var data = this.data;
var letters = [];
var i; var
len;
var newLineFlag; var index = 0; var
val;
var anchorGrouping = data.m.g;
var currentSize = 0; var currentPos = 0; var currentLine = 0; var
lineWidths = [];
var lineWidth = 0;
var maxLineWidth = 0;
var j; var
jLen;
var fontData = fontManager.getFontByName(documentData.f);
var charData; var
cLength = 0;
var fontProps = getFontProperties(fontData);
documentData.fWeight = fontProps.weight;
documentData.fStyle = fontProps.style;
documentData.finalSize = documentData.s;
documentData.finalText = this.buildFinalText(documentData.t);
len = documentData.finalText.length;
documentData.finalLineHeight = documentData.lh;
var trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
var charCode;
if (documentData.sz) {
var flag = true;
var boxWidth = documentData.sz[0];
var boxHeight = documentData.sz[1];
var currentHeight; var
finalText;
while (flag) {
finalText = this.buildFinalText(documentData.t);
currentHeight = 0;
lineWidth = 0;
len = finalText.length;
trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
var lastSpaceIndex = -1;
for (i = 0; i < len; i += 1) {
charCode = finalText[i].charCodeAt(0);
newLineFlag = false;
if (finalText[i] === ' ') {
lastSpaceIndex = i;
} else if (charCode === 13 || charCode === 3) {
lineWidth = 0;
newLineFlag = true;
currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
}
if (fontManager.chars) {
charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
} else {
// tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
}
if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
if (lastSpaceIndex === -1) {
len += 1;
} else {
i = lastSpaceIndex;
}
currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
// finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
lastSpaceIndex = -1;
lineWidth = 0;
} else {
lineWidth += cLength;
lineWidth += trackingOffset;
}
}
currentHeight += (fontData.ascent * documentData.finalSize) / 100;
if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
documentData.finalSize -= 1;
documentData.finalLineHeight = (documentData.finalSize * documentData.lh) / documentData.s;
} else {
documentData.finalText = finalText;
len = documentData.finalText.length;
flag = false;
}
}
}
lineWidth = -trackingOffset;
cLength = 0;
var uncollapsedSpaces = 0;
var currentChar;
for (i = 0; i < len; i += 1) {
newLineFlag = false;
currentChar = documentData.finalText[i];
charCode = currentChar.charCodeAt(0);
if (charCode === 13 || charCode === 3) {
uncollapsedSpaces = 0;
lineWidths.push(lineWidth);
maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
lineWidth = -2 * trackingOffset;
val = '';
newLineFlag = true;
currentLine += 1;
} else {
val = currentChar;
}
if (fontManager.chars) {
charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
} else {
// var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
// tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
}
//
if (currentChar === ' ') {
uncollapsedSpaces += cLength + trackingOffset;
} else {
lineWidth += cLength + trackingOffset + uncollapsedSpaces;
uncollapsedSpaces = 0;
}
letters.push({
l: cLength, an: cLength, add: currentSize, n: newLineFlag, anIndexes: [], val: val, line: currentLine, animatorJustifyOffset: 0,
});
if (anchorGrouping == 2) { // eslint-disable-line eqeqeq
currentSize += cLength;
if (val === '' || val === ' ' || i === len - 1) {
if (val === '' || val === ' ') {
currentSize -= cLength;
}
while (currentPos <= i) {
letters[currentPos].an = currentSize;
letters[currentPos].ind = index;
letters[currentPos].extra = cLength;
currentPos += 1;
}
index += 1;
currentSize = 0;
}
} else if (anchorGrouping == 3) { // eslint-disable-line eqeqeq
currentSize += cLength;
if (val === '' || i === len - 1) {
if (val === '') {
currentSize -= cLength;
}
while (currentPos <= i) {
letters[currentPos].an = currentSize;
letters[currentPos].ind = index;
letters[currentPos].extra = cLength;
currentPos += 1;
}
currentSize = 0;
index += 1;
}
} else {
letters[index].ind = index;
letters[index].extra = 0;
index += 1;
}
}
documentData.l = letters;
maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
lineWidths.push(lineWidth);
if (documentData.sz) {
documentData.boxWidth = documentData.sz[0];
documentData.justifyOffset = 0;
} else {
documentData.boxWidth = maxLineWidth;
switch (documentData.j) {
case 1:
documentData.justifyOffset = -documentData.boxWidth;
break;
case 2:
documentData.justifyOffset = -documentData.boxWidth / 2;
break;
default:
documentData.justifyOffset = 0;
}
}
documentData.lineWidths = lineWidths;
var animators = data.a; var animatorData; var
letterData;
jLen = animators.length;
var based; var ind; var
indexes = [];
for (j = 0; j < jLen; j += 1) {
animatorData = animators[j];
if (animatorData.a.sc) {
documentData.strokeColorAnim = true;
}
if (animatorData.a.sw) {
documentData.strokeWidthAnim = true;
}
if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
documentData.fillColorAnim = true;
}
ind = 0;
based = animatorData.s.b;
for (i = 0; i < len; i += 1) {
letterData = letters[i];
letterData.anIndexes[j] = ind;
if ((based == 1 && letterData.val !== '') || (based == 2 && letterData.val !== '' && letterData.val !== ' ') || (based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1)) || (based == 4 && (letterData.n || i == len - 1))) { // eslint-disable-line eqeqeq
if (animatorData.s.rn === 1) {
indexes.push(ind);
}
ind += 1;
}
}
data.a[j].s.totalChars = ind;
var currentInd = -1; var
newInd;
if (animatorData.s.rn === 1) {
for (i = 0; i < len; i += 1) {
letterData = letters[i];
if (currentInd != letterData.anIndexes[j]) { // eslint-disable-line eqeqeq
currentInd = letterData.anIndexes[j];
newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
}
letterData.anIndexes[j] = newInd;
}
}
}
documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
documentData.ls = documentData.ls || 0;
documentData.ascent = (fontData.ascent * documentData.finalSize) / 100;
};
TextProperty.prototype.updateDocumentData = function (newData, index) {
index = index === undefined ? this.keysIndex : index;
var dData = this.copyData({}, this.data.d.k[index].s);
dData = this.copyData(dData, newData);
this.data.d.k[index].s = dData;
this.recalculate(index);
this.setCurrentData(dData);
this.elem.addDynamicProperty(this);
};
TextProperty.prototype.recalculate = function (index) {
var dData = this.data.d.k[index].s;
dData.__complete = false;
this.keysIndex = 0;
this._isFirstFrame = true;
this.getValue(dData);
};
TextProperty.prototype.canResizeFont = function (_canResize) {
this.canResize = _canResize;
this.recalculate(this.keysIndex);
this.elem.addDynamicProperty(this);
};
TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
this.minimumFontSize = Math.floor(_fontValue) || 1;
this.recalculate(this.keysIndex);
this.elem.addDynamicProperty(this);
};
export default TextProperty;

View File

@@ -0,0 +1,179 @@
import {
extendPrototype,
} from '../functionExtensions';
import DynamicPropertyContainer from '../helpers/dynamicProperties';
import PropertyFactory from '../PropertyFactory';
import BezierFactory from '../../3rd_party/BezierEaser';
const TextSelectorProp = (function () {
var max = Math.max;
var min = Math.min;
var floor = Math.floor;
function TextSelectorPropFactory(elem, data) {
this._currentTextLength = -1;
this.k = false;
this.data = data;
this.elem = elem;
this.comp = elem.comp;
this.finalS = 0;
this.finalE = 0;
this.initDynamicPropertyContainer(elem);
this.s = PropertyFactory.getProp(elem, data.s || { k: 0 }, 0, 0, this);
if ('e' in data) {
this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
} else {
this.e = { v: 100 };
}
this.o = PropertyFactory.getProp(elem, data.o || { k: 0 }, 0, 0, this);
this.xe = PropertyFactory.getProp(elem, data.xe || { k: 0 }, 0, 0, this);
this.ne = PropertyFactory.getProp(elem, data.ne || { k: 0 }, 0, 0, this);
this.sm = PropertyFactory.getProp(elem, data.sm || { k: 100 }, 0, 0, this);
this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
if (!this.dynamicProperties.length) {
this.getValue();
}
}
TextSelectorPropFactory.prototype = {
getMult: function (ind) {
if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
this.getValue();
}
var x1 = 0;
var y1 = 0;
var x2 = 1;
var y2 = 1;
if (this.ne.v > 0) {
x1 = this.ne.v / 100.0;
} else {
y1 = -this.ne.v / 100.0;
}
if (this.xe.v > 0) {
x2 = 1.0 - this.xe.v / 100.0;
} else {
y2 = 1.0 + this.xe.v / 100.0;
}
var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
var mult = 0;
var s = this.finalS;
var e = this.finalE;
var type = this.data.sh;
if (type === 2) {
if (e === s) {
mult = ind >= e ? 1 : 0;
} else {
mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
}
mult = easer(mult);
} else if (type === 3) {
if (e === s) {
mult = ind >= e ? 0 : 1;
} else {
mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
}
mult = easer(mult);
} else if (type === 4) {
if (e === s) {
mult = 0;
} else {
mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
if (mult < 0.5) {
mult *= 2;
} else {
mult = 1 - 2 * (mult - 0.5);
}
}
mult = easer(mult);
} else if (type === 5) {
if (e === s) {
mult = 0;
} else {
var tot = e - s;
/* ind += 0.5;
mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
ind = min(max(0, ind + 0.5 - s), e - s);
var x = -tot / 2 + ind;
var a = tot / 2;
mult = Math.sqrt(1 - (x * x) / (a * a));
}
mult = easer(mult);
} else if (type === 6) {
if (e === s) {
mult = 0;
} else {
ind = min(max(0, ind + 0.5 - s), e - s);
mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; // eslint-disable-line
}
mult = easer(mult);
} else {
if (ind >= floor(s)) {
if (ind - s < 0) {
mult = max(0, min(min(e, 1) - (s - ind), 1));
} else {
mult = max(0, min(e - ind, 1));
}
}
mult = easer(mult);
}
// Smoothness implementation.
// The smoothness represents a reduced range of the original [0; 1] range.
// if smoothness is 25%, the new range will be [0.375; 0.625]
// Steps are:
// - find the lower value of the new range (threshold)
// - if multiplier is smaller than that value, floor it to 0
// - if it is larger,
// - subtract the threshold
// - divide it by the smoothness (this will return the range to [0; 1])
// Note: If it doesn't work on some scenarios, consider applying it before the easer.
if (this.sm.v !== 100) {
var smoothness = this.sm.v * 0.01;
if (smoothness === 0) {
smoothness = 0.00000001;
}
var threshold = 0.5 - smoothness * 0.5;
if (mult < threshold) {
mult = 0;
} else {
mult = (mult - threshold) / smoothness;
if (mult > 1) {
mult = 1;
}
}
}
return mult * this.a.v;
},
getValue: function (newCharsFlag) {
this.iterateDynamicProperties();
this._mdf = newCharsFlag || this._mdf;
this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
if (newCharsFlag && this.data.r === 2) {
this.e.v = this._currentTextLength;
}
var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
var o = this.o.v / divisor;
var s = this.s.v / divisor + o;
var e = (this.e.v / divisor) + o;
if (s > e) {
var _s = s;
s = e;
e = _s;
}
this.finalS = s;
this.finalE = e;
},
};
extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
function getTextSelectorProp(elem, data, arr) {
return new TextSelectorPropFactory(elem, data, arr);
}
return {
getTextSelectorProp: getTextSelectorProp,
};
}());
export default TextSelectorProp;