@visactor/vrender-animate
Version:
This module provides a graph-based animation system for VRender.
149 lines (140 loc) • 7.96 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: !0
}), exports.SlideOutRichText = void 0;
const custom_animate_1 = require("../custom-animate"), vrender_core_1 = require("@visactor/vrender-core"), transient_1 = require("../transient");
class SlideOutRichText 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.fadeOutDuration = .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 = [], this.reverseOrder = !1, void 0 !== (null == params ? void 0 : params.fadeOutDuration) && (this.fadeOutDuration = params.fadeOutDuration),
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),
void 0 !== (null == params ? void 0 : params.reverseOrder) && (this.reverseOrder = params.reverseOrder),
this.propKeys = [ "textConfig" ];
}
onFirstRun() {
const fromProps = this.getLastProps(), toProps = this.getEndProps();
this.originalTextConfig = fromProps.textConfig ? [ ...fromProps.textConfig ] : [],
this.valid = !0, this.originalTextConfig && 0 !== this.originalTextConfig.length ? (this.fromTextConfig = vrender_core_1.RichText.TransformTextConfig2SingleCharacter(this.originalTextConfig),
this.toTextConfig = toProps.textConfig && toProps.textConfig.length > 0 ? vrender_core_1.RichText.TransformTextConfig2SingleCharacter(toProps.textConfig) : [],
this.singleCharConfig = this.fromTextConfig.map((item => "text" in item ? Object.assign(Object.assign({}, item), {
opacity: 1,
dx: 0,
dy: 0
}) : Object.assign(Object.assign({}, item), {
opacity: 1
}))), this.wordByWord && this.calculateWordGroups()) : this.valid = !1;
}
calculateWordGroups() {
this.wordGroups = [];
let fullText = "";
const charMap = {};
let match, fullTextIndex = 0;
for ((this.fromTextConfig.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.fromTextConfig.length; i++) "text" in this.fromTextConfig[i] && !allocatedIndices.has(i) && this.wordGroups.push([ i ]);
}
getTargetDx() {
switch (this.slideDirection) {
case "left":
return -this.slideDistance;
case "right":
return this.slideDistance;
default:
return 0;
}
}
getTargetDy() {
switch (this.slideDirection) {
case "up":
return -this.slideDistance;
case "down":
return this.slideDistance;
default:
return 0;
}
}
onEnd(cb) {
super.onEnd(cb), cb || (this.toTextConfig.length > 0 ? this.target.setAttribute("textConfig", this.toTextConfig) : this.target.setAttribute("textConfig", []));
}
onUpdate(end, ratio, out) {
if (!this.valid) return;
const maxTextShowRatio = 1 - this.fadeOutDuration;
let updatedTextConfig;
updatedTextConfig = this.wordByWord && this.wordGroups.length > 0 ? this.updateByWord(ratio, maxTextShowRatio) : this.updateByCharacter(ratio, maxTextShowRatio),
(0, transient_1.applyAnimationTransientAttributes)(this.target, {
textConfig: updatedTextConfig
});
}
updateByWord(ratio, maxTextShowRatio) {
const totalGroups = this.wordGroups.length, updatedTextConfig = [ ...this.singleCharConfig ];
for (let groupIndex = 0; groupIndex < this.wordGroups.length; groupIndex++) {
let disappearTime;
if (disappearTime = this.reverseOrder ? "left" === this.slideDirection ? groupIndex / totalGroups * maxTextShowRatio : (totalGroups - 1 - groupIndex) / totalGroups * maxTextShowRatio : "left" === this.slideDirection ? (totalGroups - 1 - groupIndex) / totalGroups * maxTextShowRatio : groupIndex / totalGroups * maxTextShowRatio,
ratio < disappearTime) {
for (const charIndex of this.wordGroups[groupIndex]) {
const item = updatedTextConfig[charIndex];
"text" in item && (updatedTextConfig[charIndex] = Object.assign(Object.assign({}, item), {
opacity: 1,
dx: 0,
dy: 0
}));
}
continue;
}
const animProgress = (ratio - disappearTime) / this.fadeOutDuration, progress = Math.max(0, Math.min(1, animProgress)), dx = this.getTargetDx() * progress, dy = this.getTargetDy() * progress, opacity = 1 - progress;
for (const charIndex of this.wordGroups[groupIndex]) {
const item = updatedTextConfig[charIndex];
"text" in item && (updatedTextConfig[charIndex] = Object.assign(Object.assign({}, item), {
opacity: opacity,
dx: dx,
dy: dy
}));
}
}
return updatedTextConfig;
}
updateByCharacter(ratio, maxTextShowRatio) {
const totalItems = this.fromTextConfig.length, updatedTextConfig = [ ...this.singleCharConfig ];
for (let index = 0; index < updatedTextConfig.length; index++) {
const item = updatedTextConfig[index];
if ("text" in item) {
let disappearTime;
if (disappearTime = this.reverseOrder ? "left" === this.slideDirection ? index / totalItems * maxTextShowRatio : (totalItems - 1 - index) / totalItems * maxTextShowRatio : "left" === this.slideDirection ? (totalItems - 1 - index) / totalItems * maxTextShowRatio : index / totalItems * maxTextShowRatio,
ratio < disappearTime) {
updatedTextConfig[index] = Object.assign(Object.assign({}, item), {
opacity: 1,
dx: 0,
dy: 0
});
continue;
}
const animProgress = (ratio - disappearTime) / this.fadeOutDuration, progress = Math.max(0, Math.min(1, animProgress)), dx = this.getTargetDx() * progress, dy = this.getTargetDy() * progress, opacity = 1 - progress;
updatedTextConfig[index] = Object.assign(Object.assign({}, item), {
opacity: opacity,
dx: dx,
dy: dy
});
}
}
return updatedTextConfig;
}
}
exports.SlideOutRichText = SlideOutRichText;
//# sourceMappingURL=slide-out-richtext.js.map