@visactor/vrender-animate
Version:
This module provides a graph-based animation system for VRender.
145 lines (136 loc) • 7.32 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: !0
}), exports.SlideRichText = void 0;
const custom_animate_1 = require("../custom-animate"), vrender_core_1 = require("@visactor/vrender-core");
class SlideRichText extends custom_animate_1.ACustomAnimate {
constructor(from, to, duration, easing, params) {
super(from, to, duration, easing, params), this.fromTextConfig = [], this.toTextConfig = [],
this.originalTextConfig = [], this.singleCharConfig = [], this.fadeInDuration = .3,
this.slideDirection = "right", this.slideDistance = 30, this.wordByWord = !1, this.wordRegex = /[a-zA-Z]+(-[a-zA-Z]+)*|[\u4e00-\u9fa5]+|[0-9]+|[^\s\w\u4e00-\u9fa5]/g,
this.wordGroups = [], void 0 !== (null == params ? void 0 : params.fadeInDuration) && (this.fadeInDuration = params.fadeInDuration),
void 0 !== (null == params ? void 0 : params.slideDirection) && (this.slideDirection = params.slideDirection),
void 0 !== (null == params ? void 0 : params.slideDistance) && (this.slideDistance = params.slideDistance),
void 0 !== (null == params ? void 0 : params.wordByWord) && (this.wordByWord = params.wordByWord),
void 0 !== (null == params ? void 0 : params.wordRegex) && (this.wordRegex = params.wordRegex);
}
onFirstRun() {
const fromProps = this.getLastProps(), toProps = this.getEndProps();
this.originalTextConfig = toProps.textConfig ? [ ...toProps.textConfig ] : [], this.valid = !0,
this.originalTextConfig && 0 !== this.originalTextConfig.length ? (this.fromTextConfig = fromProps.textConfig && fromProps.textConfig.length > 0 ? vrender_core_1.RichText.TransformTextConfig2SingleCharacter(fromProps.textConfig) : [],
this.toTextConfig = vrender_core_1.RichText.TransformTextConfig2SingleCharacter(this.originalTextConfig),
this.singleCharConfig = this.toTextConfig.map((item => "text" in item ? Object.assign(Object.assign({}, item), {
opacity: 0,
dx: this.getInitialDx(),
dy: this.getInitialDy()
}) : Object.assign(Object.assign({}, item), {
opacity: 0
}))), this.wordByWord && this.calculateWordGroups()) : this.valid = !1;
}
calculateWordGroups() {
this.wordGroups = [];
let fullText = "";
const charMap = {};
let match, fullTextIndex = 0;
for ((this.toTextConfig.forEach(((item, configIndex) => {
if ("text" in item) {
const text = String(item.text);
fullText += text, charMap[fullTextIndex] = configIndex, fullTextIndex++;
}
})), this.wordRegex.lastIndex = 0); null !== (match = this.wordRegex.exec(fullText)); ) {
const wordStart = match.index, wordEnd = match.index + match[0].length, wordIndices = [];
for (let i = wordStart; i < wordEnd; i++) void 0 !== charMap[i] && wordIndices.push(charMap[i]);
wordIndices.length > 0 && this.wordGroups.push(wordIndices);
}
const allocatedIndices = new Set;
this.wordGroups.forEach((group => {
group.forEach((index => allocatedIndices.add(index)));
}));
for (let i = 0; i < this.toTextConfig.length; i++) "text" in this.toTextConfig[i] && !allocatedIndices.has(i) && this.wordGroups.push([ i ]);
}
getInitialDx() {
switch (this.slideDirection) {
case "left":
return -this.slideDistance;
case "right":
return this.slideDistance;
default:
return 0;
}
}
getInitialDy() {
switch (this.slideDirection) {
case "up":
return -this.slideDistance;
case "down":
return this.slideDistance;
default:
return 0;
}
}
onEnd(cb) {
super.onEnd(cb), cb || this.target.setAttribute("textConfig", this.originalTextConfig);
}
onUpdate(end, ratio, out) {
if (!this.valid) return;
const maxTextShowRatio = 1 - this.fadeInDuration;
let updatedTextConfig;
updatedTextConfig = this.wordByWord && this.wordGroups.length > 0 ? this.updateByWord(ratio, maxTextShowRatio) : this.updateByCharacter(ratio, maxTextShowRatio),
this.target.setAttribute("textConfig", updatedTextConfig);
}
updateByWord(ratio, maxTextShowRatio) {
const totalGroups = this.wordGroups.length, updatedTextConfig = [ ...this.singleCharConfig ];
for (let groupIndex = 0; groupIndex < this.wordGroups.length; groupIndex++) {
let appearTime;
if (appearTime = "left" === this.slideDirection ? (totalGroups - 1 - groupIndex) / totalGroups * maxTextShowRatio : groupIndex / totalGroups * maxTextShowRatio,
ratio < appearTime) {
for (const charIndex of this.wordGroups[groupIndex]) {
const item = updatedTextConfig[charIndex];
"text" in item && (updatedTextConfig[charIndex] = Object.assign(Object.assign({}, item), {
opacity: 0,
dx: this.getInitialDx(),
dy: this.getInitialDy()
}));
}
continue;
}
const animProgress = (ratio - appearTime) / this.fadeInDuration, progress = Math.max(0, Math.min(1, animProgress)), dx = this.getInitialDx() * (1 - progress), dy = this.getInitialDy() * (1 - progress);
for (const charIndex of this.wordGroups[groupIndex]) {
const item = updatedTextConfig[charIndex];
"text" in item && (updatedTextConfig[charIndex] = Object.assign(Object.assign({}, item), {
opacity: progress,
dx: dx,
dy: dy
}));
}
}
return updatedTextConfig;
}
updateByCharacter(ratio, maxTextShowRatio) {
const totalItems = this.toTextConfig.length, updatedTextConfig = [ ...this.singleCharConfig ];
for (let index = 0; index < updatedTextConfig.length; index++) {
const item = updatedTextConfig[index];
if ("text" in item) {
let appearTime;
if (appearTime = "left" === this.slideDirection ? (totalItems - 1 - index) / totalItems * maxTextShowRatio : index / totalItems * maxTextShowRatio,
ratio < appearTime) {
updatedTextConfig[index] = Object.assign(Object.assign({}, item), {
opacity: 0,
dx: this.getInitialDx(),
dy: this.getInitialDy()
});
continue;
}
const animProgress = (ratio - appearTime) / this.fadeInDuration, progress = Math.max(0, Math.min(1, animProgress)), dx = this.getInitialDx() * (1 - progress), dy = this.getInitialDy() * (1 - progress);
updatedTextConfig[index] = Object.assign(Object.assign({}, item), {
opacity: progress,
dx: dx,
dy: dy
});
}
}
return updatedTextConfig;
}
}
exports.SlideRichText = SlideRichText;
//# sourceMappingURL=slide-richtext.js.map