@visactor/vrender-animate 0.23.0-alpha.3 → 1.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/animate-extension.d.ts +1 -3
- package/cjs/animate-extension.js +0 -7
- package/cjs/animate-extension.js.map +1 -1
- package/cjs/animate.d.ts +1 -5
- package/cjs/animate.js +12 -12
- package/cjs/animate.js.map +1 -1
- package/cjs/component/component-animator.d.ts +3 -2
- package/cjs/component/component-animator.js +18 -32
- package/cjs/component/component-animator.js.map +1 -1
- package/cjs/custom/clip-graphic.d.ts +1 -1
- package/cjs/custom/clip-graphic.js.map +1 -1
- package/cjs/custom/clip.d.ts +1 -1
- package/cjs/custom/clip.js.map +1 -1
- package/cjs/custom/common.d.ts +1 -2
- package/cjs/custom/common.js +12 -10
- package/cjs/custom/common.js.map +1 -1
- package/cjs/custom/custom-animate.d.ts +2 -4
- package/cjs/custom/custom-animate.js +2 -2
- package/cjs/custom/custom-animate.js.map +1 -1
- package/cjs/custom/fade.d.ts +1 -1
- package/cjs/custom/fade.js.map +1 -1
- package/cjs/custom/from-to.d.ts +9 -0
- package/cjs/custom/from-to.js +38 -0
- package/cjs/custom/from-to.js.map +1 -0
- package/cjs/custom/group-fade.d.ts +8 -14
- package/cjs/custom/group-fade.js +9 -50
- package/cjs/custom/group-fade.js.map +1 -1
- package/cjs/custom/growAngle.d.ts +2 -2
- package/cjs/custom/growAngle.js +17 -12
- package/cjs/custom/growAngle.js.map +1 -1
- package/cjs/custom/growCenter.d.ts +1 -2
- package/cjs/custom/growCenter.js +8 -7
- package/cjs/custom/growCenter.js.map +1 -1
- package/cjs/custom/growHeight.d.ts +1 -3
- package/cjs/custom/growHeight.js +7 -7
- package/cjs/custom/growHeight.js.map +1 -1
- package/cjs/custom/growPoints.d.ts +1 -2
- package/cjs/custom/growPoints.js +19 -17
- package/cjs/custom/growPoints.js.map +1 -1
- package/cjs/custom/growRadius.d.ts +4 -5
- package/cjs/custom/growRadius.js +12 -12
- package/cjs/custom/growRadius.js.map +1 -1
- package/cjs/custom/growWidth.d.ts +1 -3
- package/cjs/custom/growWidth.js +7 -6
- package/cjs/custom/growWidth.js.map +1 -1
- package/cjs/custom/input-text.d.ts +1 -2
- package/cjs/custom/input-text.js.map +1 -1
- package/cjs/custom/label-item-animate.js +2 -2
- package/cjs/custom/label-item-animate.js.map +1 -1
- package/cjs/custom/move.d.ts +92 -0
- package/cjs/custom/move.js +131 -0
- package/cjs/custom/move.js.map +1 -0
- package/cjs/custom/number.d.ts +1 -2
- package/cjs/custom/number.js.map +1 -1
- package/cjs/custom/poptip-animate.js +2 -1
- package/cjs/custom/poptip-animate.js.map +1 -1
- package/cjs/custom/register.js +21 -2
- package/cjs/custom/register.js.map +1 -1
- package/cjs/custom/richtext/input-richtext.d.ts +33 -0
- package/cjs/custom/richtext/input-richtext.js +70 -0
- package/cjs/custom/richtext/input-richtext.js.map +1 -0
- package/cjs/custom/richtext/output-richtext.d.ts +37 -0
- package/cjs/custom/richtext/output-richtext.js +94 -0
- package/cjs/custom/richtext/output-richtext.js.map +1 -0
- package/cjs/custom/richtext/slide-out-richtext.d.ts +38 -0
- package/cjs/custom/richtext/slide-out-richtext.js +146 -0
- package/cjs/custom/richtext/slide-out-richtext.js.map +1 -0
- package/cjs/custom/richtext/slide-richtext.d.ts +36 -0
- package/cjs/custom/richtext/slide-richtext.js +144 -0
- package/cjs/custom/richtext/slide-richtext.js.map +1 -0
- package/cjs/custom/rotate.d.ts +33 -0
- package/cjs/custom/rotate.js +76 -0
- package/cjs/custom/rotate.js.map +1 -0
- package/cjs/custom/scale.d.ts +2 -2
- package/cjs/custom/scale.js +25 -21
- package/cjs/custom/scale.js.map +1 -1
- package/cjs/custom/sphere.js +1 -2
- package/cjs/custom/state.d.ts +1 -1
- package/cjs/custom/state.js.map +1 -1
- package/cjs/custom/story.d.ts +128 -0
- package/cjs/custom/story.js +347 -0
- package/cjs/custom/story.js.map +1 -0
- package/cjs/custom/tag-points.d.ts +2 -3
- package/cjs/custom/tag-points.js +18 -5
- package/cjs/custom/tag-points.js.map +1 -1
- package/cjs/custom/update.d.ts +2 -1
- package/cjs/custom/update.js +10 -2
- package/cjs/custom/update.js.map +1 -1
- package/cjs/executor/animate-executor.d.ts +6 -5
- package/cjs/executor/animate-executor.js +57 -29
- package/cjs/executor/animate-executor.js.map +1 -1
- package/cjs/executor/executor.d.ts +6 -3
- package/cjs/executor/executor.js.map +1 -1
- package/cjs/index.d.ts +3 -6
- package/cjs/index.js +16 -4
- package/cjs/index.js.map +1 -1
- package/cjs/interpolate/store.d.ts +2 -2
- package/cjs/interpolate/store.js +2 -0
- package/cjs/interpolate/store.js.map +1 -1
- package/cjs/state/animation-state.d.ts +2 -2
- package/cjs/state/animation-state.js +3 -3
- package/cjs/state/animation-state.js.map +1 -1
- package/cjs/state/graphic-extension.d.ts +1 -1
- package/cjs/state/graphic-extension.js.map +1 -1
- package/cjs/step.d.ts +2 -4
- package/cjs/step.js +1 -1
- package/cjs/step.js.map +1 -1
- package/cjs/ticker/default-ticker.d.ts +2 -3
- package/cjs/ticker/default-ticker.js +14 -12
- package/cjs/ticker/default-ticker.js.map +1 -1
- package/cjs/ticker/manual-ticker.d.ts +1 -1
- package/cjs/ticker/manual-ticker.js.map +1 -1
- package/cjs/timeline.d.ts +1 -2
- package/cjs/timeline.js.map +1 -1
- package/cjs/utils/easing-func.js +2 -1
- package/dist/index.es.js +1859 -554
- package/es/animate-extension.d.ts +1 -3
- package/es/animate-extension.js +0 -7
- package/es/animate-extension.js.map +1 -1
- package/es/animate.d.ts +1 -5
- package/es/animate.js +1 -3
- package/es/animate.js.map +1 -1
- package/es/component/component-animator.d.ts +3 -2
- package/es/component/component-animator.js +18 -32
- package/es/component/component-animator.js.map +1 -1
- package/es/custom/clip-graphic.d.ts +1 -1
- package/es/custom/clip-graphic.js.map +1 -1
- package/es/custom/clip.d.ts +1 -1
- package/es/custom/clip.js.map +1 -1
- package/es/custom/common.d.ts +1 -2
- package/es/custom/common.js +12 -10
- package/es/custom/common.js.map +1 -1
- package/es/custom/custom-animate.d.ts +2 -4
- package/es/custom/custom-animate.js +2 -2
- package/es/custom/custom-animate.js.map +1 -1
- package/es/custom/fade.d.ts +1 -1
- package/es/custom/fade.js.map +1 -1
- package/es/custom/from-to.d.ts +9 -0
- package/es/custom/from-to.js +30 -0
- package/es/custom/from-to.js.map +1 -0
- package/es/custom/group-fade.d.ts +8 -14
- package/es/custom/group-fade.js +9 -50
- package/es/custom/group-fade.js.map +1 -1
- package/es/custom/growAngle.d.ts +2 -2
- package/es/custom/growAngle.js +20 -12
- package/es/custom/growAngle.js.map +1 -1
- package/es/custom/growCenter.d.ts +1 -2
- package/es/custom/growCenter.js +8 -7
- package/es/custom/growCenter.js.map +1 -1
- package/es/custom/growHeight.d.ts +1 -3
- package/es/custom/growHeight.js +8 -8
- package/es/custom/growHeight.js.map +1 -1
- package/es/custom/growPoints.d.ts +1 -2
- package/es/custom/growPoints.js +19 -17
- package/es/custom/growPoints.js.map +1 -1
- package/es/custom/growRadius.d.ts +4 -5
- package/es/custom/growRadius.js +12 -10
- package/es/custom/growRadius.js.map +1 -1
- package/es/custom/growWidth.d.ts +1 -3
- package/es/custom/growWidth.js +8 -7
- package/es/custom/growWidth.js.map +1 -1
- package/es/custom/input-text.d.ts +1 -2
- package/es/custom/input-text.js.map +1 -1
- package/es/custom/label-item-animate.js +2 -2
- package/es/custom/label-item-animate.js.map +1 -1
- package/es/custom/move.d.ts +92 -0
- package/es/custom/move.js +116 -0
- package/es/custom/move.js.map +1 -0
- package/es/custom/number.d.ts +1 -2
- package/es/custom/number.js.map +1 -1
- package/es/custom/poptip-animate.js +2 -1
- package/es/custom/poptip-animate.js.map +1 -1
- package/es/custom/register.js +41 -16
- package/es/custom/register.js.map +1 -1
- package/es/custom/richtext/input-richtext.d.ts +33 -0
- package/es/custom/richtext/input-richtext.js +64 -0
- package/es/custom/richtext/input-richtext.js.map +1 -0
- package/es/custom/richtext/output-richtext.d.ts +37 -0
- package/es/custom/richtext/output-richtext.js +88 -0
- package/es/custom/richtext/output-richtext.js.map +1 -0
- package/es/custom/richtext/slide-out-richtext.d.ts +38 -0
- package/es/custom/richtext/slide-out-richtext.js +140 -0
- package/es/custom/richtext/slide-out-richtext.js.map +1 -0
- package/es/custom/richtext/slide-richtext.d.ts +36 -0
- package/es/custom/richtext/slide-richtext.js +138 -0
- package/es/custom/richtext/slide-richtext.js.map +1 -0
- package/es/custom/rotate.d.ts +33 -0
- package/es/custom/rotate.js +62 -0
- package/es/custom/rotate.js.map +1 -0
- package/es/custom/scale.d.ts +2 -2
- package/es/custom/scale.js +25 -21
- package/es/custom/scale.js.map +1 -1
- package/es/custom/sphere.js +1 -2
- package/es/custom/state.d.ts +1 -1
- package/es/custom/state.js.map +1 -1
- package/es/custom/story.d.ts +128 -0
- package/es/custom/story.js +323 -0
- package/es/custom/story.js.map +1 -0
- package/es/custom/tag-points.d.ts +2 -3
- package/es/custom/tag-points.js +19 -6
- package/es/custom/tag-points.js.map +1 -1
- package/es/custom/update.d.ts +2 -1
- package/es/custom/update.js +10 -2
- package/es/custom/update.js.map +1 -1
- package/es/executor/animate-executor.d.ts +6 -5
- package/es/executor/animate-executor.js +55 -29
- package/es/executor/animate-executor.js.map +1 -1
- package/es/executor/executor.d.ts +6 -3
- package/es/executor/executor.js.map +1 -1
- package/es/index.d.ts +3 -6
- package/es/index.js +4 -10
- package/es/index.js.map +1 -1
- package/es/interpolate/store.d.ts +2 -2
- package/es/interpolate/store.js +2 -0
- package/es/interpolate/store.js.map +1 -1
- package/es/state/animation-state.d.ts +2 -2
- package/es/state/animation-state.js +4 -2
- package/es/state/animation-state.js.map +1 -1
- package/es/state/graphic-extension.d.ts +1 -1
- package/es/state/graphic-extension.js.map +1 -1
- package/es/step.d.ts +2 -4
- package/es/step.js +2 -2
- package/es/step.js.map +1 -1
- package/es/ticker/default-ticker.d.ts +2 -3
- package/es/ticker/default-ticker.js +5 -5
- package/es/ticker/default-ticker.js.map +1 -1
- package/es/ticker/manual-ticker.d.ts +1 -1
- package/es/ticker/manual-ticker.js.map +1 -1
- package/es/timeline.d.ts +1 -2
- package/es/timeline.js +1 -1
- package/es/timeline.js.map +1 -1
- package/es/utils/easing-func.js +2 -1
- package/package.json +5 -5
- package/cjs/custom/label-animate.d.ts +0 -4
- package/cjs/custom/label-animate.js +0 -48
- package/cjs/custom/label-animate.js.map +0 -1
- package/cjs/intreface/animate.d.ts +0 -92
- package/cjs/intreface/animate.js +0 -10
- package/cjs/intreface/animate.js.map +0 -1
- package/cjs/intreface/easing.d.ts +0 -3
- package/cjs/intreface/easing.js +0 -6
- package/cjs/intreface/easing.js.map +0 -1
- package/cjs/intreface/ticker.d.ts +0 -37
- package/cjs/intreface/ticker.js +0 -11
- package/cjs/intreface/ticker.js.map +0 -1
- package/cjs/intreface/timeline.d.ts +0 -17
- package/cjs/intreface/timeline.js +0 -6
- package/cjs/intreface/timeline.js.map +0 -1
- package/cjs/intreface/type.d.ts +0 -13
- package/cjs/intreface/type.js +0 -15
- package/cjs/intreface/type.js.map +0 -1
- package/es/custom/label-animate.d.ts +0 -4
- package/es/custom/label-animate.js +0 -42
- package/es/custom/label-animate.js.map +0 -1
- package/es/intreface/animate.d.ts +0 -92
- package/es/intreface/animate.js +0 -6
- package/es/intreface/animate.js.map +0 -1
- package/es/intreface/easing.d.ts +0 -3
- package/es/intreface/easing.js +0 -2
- package/es/intreface/easing.js.map +0 -1
- package/es/intreface/ticker.d.ts +0 -37
- package/es/intreface/ticker.js +0 -7
- package/es/intreface/ticker.js.map +0 -1
- package/es/intreface/timeline.d.ts +0 -17
- package/es/intreface/timeline.js +0 -2
- package/es/intreface/timeline.js.map +0 -1
- package/es/intreface/type.d.ts +0 -13
- package/es/intreface/type.js +0 -14
- package/es/intreface/type.js.map +0 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: !0
|
|
5
|
+
}), exports.InputRichText = void 0;
|
|
6
|
+
|
|
7
|
+
const custom_animate_1 = require("../custom-animate"), vrender_core_1 = require("@visactor/vrender-core");
|
|
8
|
+
|
|
9
|
+
class InputRichText extends custom_animate_1.ACustomAnimate {
|
|
10
|
+
constructor(from, to, duration, easing, params) {
|
|
11
|
+
super(from, to, duration, easing, params), this.fromTextConfig = [], this.toTextConfig = [],
|
|
12
|
+
this.originalTextConfig = [], this.showCursor = !1, this.cursorChar = "|", this.blinkCursor = !0,
|
|
13
|
+
this.beforeText = "", this.afterText = "", this.fadeInChars = !1, this.fadeInDuration = .3,
|
|
14
|
+
void 0 !== (null == params ? void 0 : params.showCursor) && (this.showCursor = params.showCursor),
|
|
15
|
+
void 0 !== (null == params ? void 0 : params.cursorChar) && (this.cursorChar = params.cursorChar),
|
|
16
|
+
void 0 !== (null == params ? void 0 : params.blinkCursor) && (this.blinkCursor = params.blinkCursor),
|
|
17
|
+
void 0 !== (null == params ? void 0 : params.beforeText) && (this.beforeText = params.beforeText),
|
|
18
|
+
void 0 !== (null == params ? void 0 : params.afterText) && (this.afterText = params.afterText),
|
|
19
|
+
void 0 !== (null == params ? void 0 : params.fadeInChars) && (this.fadeInChars = params.fadeInChars),
|
|
20
|
+
void 0 !== (null == params ? void 0 : params.fadeInDuration) && (this.fadeInDuration = params.fadeInDuration);
|
|
21
|
+
}
|
|
22
|
+
onFirstRun() {
|
|
23
|
+
const fromProps = this.getLastProps(), toProps = this.getEndProps();
|
|
24
|
+
this.originalTextConfig = toProps.textConfig ? [ ...toProps.textConfig ] : [], this.valid = !0,
|
|
25
|
+
this.originalTextConfig && 0 !== this.originalTextConfig.length ? (this.fromTextConfig = fromProps.textConfig && fromProps.textConfig.length > 0 ? vrender_core_1.RichText.TransformTextConfig2SingleCharacter(fromProps.textConfig) : [],
|
|
26
|
+
this.toTextConfig = vrender_core_1.RichText.TransformTextConfig2SingleCharacter(this.originalTextConfig)) : this.valid = !1;
|
|
27
|
+
}
|
|
28
|
+
onEnd(cb) {
|
|
29
|
+
super.onEnd(cb), cb || this.target.setAttribute("textConfig", this.originalTextConfig);
|
|
30
|
+
}
|
|
31
|
+
onUpdate(end, ratio, out) {
|
|
32
|
+
if (!this.valid) return;
|
|
33
|
+
const totalItems = this.toTextConfig.length, fromItems = this.fromTextConfig.length, maxTextShowRatio = this.fadeInChars ? 1 - this.fadeInDuration : 1;
|
|
34
|
+
let currentLength, currentTextConfig;
|
|
35
|
+
if (fromItems > totalItems) currentLength = Math.round(fromItems - (fromItems - totalItems) * ratio); else if (this.fadeInChars) {
|
|
36
|
+
const adjustedRatio = Math.min(1, ratio / maxTextShowRatio);
|
|
37
|
+
currentLength = Math.round(fromItems + (totalItems - fromItems) * adjustedRatio);
|
|
38
|
+
} else currentLength = Math.round(fromItems + (totalItems - fromItems) * ratio);
|
|
39
|
+
if (currentTextConfig = fromItems > totalItems ? this.fromTextConfig.slice(0, currentLength) : this.toTextConfig.slice(0, currentLength).map(((item, index) => {
|
|
40
|
+
if (this.fadeInChars && "text" in item) {
|
|
41
|
+
const fadeProgress = (ratio - index / totalItems * maxTextShowRatio) / this.fadeInDuration, opacity = Math.max(0, Math.min(1, fadeProgress));
|
|
42
|
+
return Object.assign(Object.assign({}, item), {
|
|
43
|
+
opacity: opacity
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return item;
|
|
47
|
+
})), this.showCursor && currentLength < totalItems) {
|
|
48
|
+
let shouldShowCursor = !0;
|
|
49
|
+
if (this.blinkCursor) {
|
|
50
|
+
const blinkRate = .1;
|
|
51
|
+
shouldShowCursor = Math.floor(ratio / blinkRate) % 2 == 0;
|
|
52
|
+
}
|
|
53
|
+
if (shouldShowCursor && currentTextConfig.length > 0) {
|
|
54
|
+
const lastIndex = currentTextConfig.length - 1, lastItem = currentTextConfig[lastIndex];
|
|
55
|
+
if ("text" in lastItem) currentTextConfig[lastIndex] = Object.assign(Object.assign({}, lastItem), {
|
|
56
|
+
text: String(lastItem.text) + this.cursorChar
|
|
57
|
+
}); else {
|
|
58
|
+
const cursorItem = {
|
|
59
|
+
text: this.cursorChar,
|
|
60
|
+
fontSize: 16
|
|
61
|
+
};
|
|
62
|
+
currentTextConfig.push(cursorItem);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
this.target.setAttribute("textConfig", currentTextConfig);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
exports.InputRichText = InputRichText;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/custom/richtext/input-richtext.ts"],"names":[],"mappings":"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","file":"input-richtext.js","sourcesContent":["import { ACustomAnimate } from '../custom-animate';\nimport type {\n IRichTextCharacter,\n IRichTextParagraphCharacter,\n IAnimate,\n IStep,\n EasingType\n} from '@visactor/vrender-core';\nimport { RichText } from '@visactor/vrender-core';\n\n/**\n * 富文本输入动画,实现类似打字机的字符逐个显示效果\n * 支持通过beforeText和afterText参数添加前缀和后缀\n * 支持通过showCursor参数显示光标,cursorChar自定义光标字符\n * 支持通过fadeInChars参数开启字符透明度渐变效果\n */\nexport class InputRichText extends ACustomAnimate<{ textConfig: IRichTextCharacter[] }> {\n declare valid: boolean;\n\n private fromTextConfig: IRichTextCharacter[] = [];\n private toTextConfig: IRichTextCharacter[] = [];\n private originalTextConfig: IRichTextCharacter[] = [];\n private showCursor: boolean = false;\n private cursorChar: string = '|';\n private blinkCursor: boolean = true;\n private beforeText: string = '';\n private afterText: string = '';\n private fadeInChars: boolean = false;\n private fadeInDuration: number = 0.3; // 透明度渐变持续时间,以动画总时长的比例表示\n\n constructor(\n from: { textConfig: IRichTextCharacter[] },\n to: { textConfig: IRichTextCharacter[] },\n duration: number,\n easing: EasingType,\n params?: {\n showCursor?: boolean;\n cursorChar?: string;\n blinkCursor?: boolean;\n beforeText?: string;\n afterText?: string;\n fadeInChars?: boolean;\n fadeInDuration?: number;\n }\n ) {\n super(from, to, duration, easing, params);\n\n // 配置光标相关选项\n if (params?.showCursor !== undefined) {\n this.showCursor = params.showCursor;\n }\n if (params?.cursorChar !== undefined) {\n this.cursorChar = params.cursorChar;\n }\n if (params?.blinkCursor !== undefined) {\n this.blinkCursor = params.blinkCursor;\n }\n\n // 配置前缀和后缀文本\n if (params?.beforeText !== undefined) {\n this.beforeText = params.beforeText;\n }\n if (params?.afterText !== undefined) {\n this.afterText = params.afterText;\n }\n\n // 配置字符透明度渐变效果\n if (params?.fadeInChars !== undefined) {\n this.fadeInChars = params.fadeInChars;\n }\n if (params?.fadeInDuration !== undefined) {\n this.fadeInDuration = params.fadeInDuration;\n }\n }\n\n onFirstRun(): void {\n const fromProps = this.getLastProps();\n const toProps = this.getEndProps();\n\n // 存储原始配置\n this.originalTextConfig = toProps.textConfig ? [...toProps.textConfig] : [];\n\n // 初始化解析结果\n this.valid = true;\n\n // 确保to不为空\n if (!this.originalTextConfig || this.originalTextConfig.length === 0) {\n this.valid = false;\n return;\n }\n\n // 将文本拆分为单个字符,使用RichText的静态方法\n this.fromTextConfig =\n fromProps.textConfig && fromProps.textConfig.length > 0\n ? RichText.TransformTextConfig2SingleCharacter(fromProps.textConfig)\n : [];\n\n this.toTextConfig = RichText.TransformTextConfig2SingleCharacter(this.originalTextConfig);\n }\n\n onEnd(cb?: (animate: IAnimate, step: IStep) => void): void {\n super.onEnd(cb);\n if (!cb) {\n // 动画结束时,恢复原始textConfig\n this.target.setAttribute('textConfig', this.originalTextConfig);\n }\n }\n\n onUpdate(end: boolean, ratio: number, out: Record<string, any>): void {\n if (!this.valid) {\n return;\n }\n\n // 计算当前应该显示的字符数量\n const totalItems = this.toTextConfig.length;\n const fromItems = this.fromTextConfig.length;\n\n // 计算文本显示比例上限 - 如果有渐变效果,需要为尾部字符的渐变留出时间\n // 例如,如果fadeInDuration为0.3,则文本显示部分最多占用动画时间的70%\n const maxTextShowRatio = this.fadeInChars ? 1 - this.fadeInDuration : 1;\n\n // 确定当前应该显示多少个项目\n let currentLength: number;\n\n // 如果fromItems比totalItems长,则是删除动画,否则是添加动画\n if (fromItems > totalItems) {\n // 删除文本动画(从多到少)\n currentLength = Math.round(fromItems - (fromItems - totalItems) * ratio);\n } else {\n // 添加文本动画(从少到多)- 需要更快显示字符以便留出时间让最后的字符完成渐变\n if (this.fadeInChars) {\n // 当ratio达到maxTextShowRatio时,应该已经显示全部文本\n const adjustedRatio = Math.min(1, ratio / maxTextShowRatio);\n currentLength = Math.round(fromItems + (totalItems - fromItems) * adjustedRatio);\n } else {\n // 无渐变效果时,正常显示\n currentLength = Math.round(fromItems + (totalItems - fromItems) * ratio);\n }\n }\n\n // 构建当前要显示的textConfig\n let currentTextConfig: IRichTextCharacter[];\n if (fromItems > totalItems) {\n // 删除动画:显示from的前currentLength项\n currentTextConfig = this.fromTextConfig.slice(0, currentLength);\n } else {\n // 添加文本动画:显示to的前currentLength项,可能需要应用透明度\n currentTextConfig = this.toTextConfig.slice(0, currentLength).map((item, index) => {\n // 如果启用了透明度渐变效果\n if (this.fadeInChars && 'text' in item) {\n // 计算每个字符从出现到结束的渐变进度\n // 字符在特定时间点出现:出现时刻 = (index / totalItems) * maxTextShowRatio\n // 当前时刻 = ratio\n // 渐变持续时间 = fadeInDuration\n // 渐变进度 = (当前时刻 - 出现时刻) / 渐变持续时间\n\n const appearTime = (index / totalItems) * maxTextShowRatio;\n const fadeProgress = (ratio - appearTime) / this.fadeInDuration;\n\n // 限制透明度在0-1范围内\n const opacity = Math.max(0, Math.min(1, fadeProgress));\n\n // 如果是文本项,添加透明度\n return {\n ...item,\n opacity: opacity\n };\n }\n return item;\n });\n }\n\n // 如果启用了光标\n if (this.showCursor && currentLength < totalItems) {\n // 判断是否应该显示光标\n let shouldShowCursor = true;\n\n if (this.blinkCursor) {\n // 闪烁效果:在动画期间,光标每半个周期闪烁一次\n const blinkRate = 0.1; // 光标闪烁频率(每10%动画进度闪烁一次)\n shouldShowCursor = Math.floor(ratio / blinkRate) % 2 === 0;\n }\n\n if (shouldShowCursor && currentTextConfig.length > 0) {\n // 找到最后一个文本项,在其后添加光标\n const lastIndex = currentTextConfig.length - 1;\n const lastItem = currentTextConfig[lastIndex];\n\n if ('text' in lastItem) {\n // 如果最后一项是文本,将光标添加到文本后面\n currentTextConfig[lastIndex] = {\n ...lastItem,\n text: String(lastItem.text) + this.cursorChar\n };\n } else {\n // 如果最后一项是非文本(如图片),添加一个只包含光标的新文本项\n const cursorItem: IRichTextParagraphCharacter = {\n text: this.cursorChar,\n fontSize: 16 // 使用默认字体大小,或者从context获取\n };\n currentTextConfig.push(cursorItem);\n }\n }\n }\n\n // 更新富文本的textConfig属性\n this.target.setAttribute('textConfig', currentTextConfig);\n }\n}\n"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ACustomAnimate } from '../custom-animate';
|
|
2
|
+
import type { IRichTextCharacter, IAnimate, IStep, EasingType } from '@visactor/vrender-core';
|
|
3
|
+
export declare class OutputRichText extends ACustomAnimate<{
|
|
4
|
+
textConfig: IRichTextCharacter[];
|
|
5
|
+
}> {
|
|
6
|
+
valid: boolean;
|
|
7
|
+
private fromTextConfig;
|
|
8
|
+
private toTextConfig;
|
|
9
|
+
private originalTextConfig;
|
|
10
|
+
private showCursor;
|
|
11
|
+
private cursorChar;
|
|
12
|
+
private blinkCursor;
|
|
13
|
+
private beforeText;
|
|
14
|
+
private afterText;
|
|
15
|
+
private fadeOutChars;
|
|
16
|
+
private fadeOutDuration;
|
|
17
|
+
private direction;
|
|
18
|
+
constructor(from: {
|
|
19
|
+
textConfig: IRichTextCharacter[];
|
|
20
|
+
}, to: {
|
|
21
|
+
textConfig: IRichTextCharacter[];
|
|
22
|
+
}, duration: number, easing: EasingType, params?: {
|
|
23
|
+
showCursor?: boolean;
|
|
24
|
+
cursorChar?: string;
|
|
25
|
+
blinkCursor?: boolean;
|
|
26
|
+
beforeText?: string;
|
|
27
|
+
afterText?: string;
|
|
28
|
+
fadeOutChars?: boolean;
|
|
29
|
+
fadeOutDuration?: number;
|
|
30
|
+
direction?: 'forward' | 'backward';
|
|
31
|
+
});
|
|
32
|
+
onFirstRun(): void;
|
|
33
|
+
onEnd(cb?: (animate: IAnimate, step: IStep) => void): void;
|
|
34
|
+
onUpdate(end: boolean, ratio: number, out: Record<string, any>): void;
|
|
35
|
+
private applyFadeEffect;
|
|
36
|
+
private addCursor;
|
|
37
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: !0
|
|
5
|
+
}), exports.OutputRichText = void 0;
|
|
6
|
+
|
|
7
|
+
const custom_animate_1 = require("../custom-animate"), vrender_core_1 = require("@visactor/vrender-core");
|
|
8
|
+
|
|
9
|
+
class OutputRichText extends custom_animate_1.ACustomAnimate {
|
|
10
|
+
constructor(from, to, duration, easing, params) {
|
|
11
|
+
super(from, to, duration, easing, params), this.fromTextConfig = [], this.toTextConfig = [],
|
|
12
|
+
this.originalTextConfig = [], this.showCursor = !1, this.cursorChar = "|", this.blinkCursor = !0,
|
|
13
|
+
this.beforeText = "", this.afterText = "", this.fadeOutChars = !1, this.fadeOutDuration = .3,
|
|
14
|
+
this.direction = "backward", void 0 !== (null == params ? void 0 : params.showCursor) && (this.showCursor = params.showCursor),
|
|
15
|
+
void 0 !== (null == params ? void 0 : params.cursorChar) && (this.cursorChar = params.cursorChar),
|
|
16
|
+
void 0 !== (null == params ? void 0 : params.blinkCursor) && (this.blinkCursor = params.blinkCursor),
|
|
17
|
+
void 0 !== (null == params ? void 0 : params.beforeText) && (this.beforeText = params.beforeText),
|
|
18
|
+
void 0 !== (null == params ? void 0 : params.afterText) && (this.afterText = params.afterText),
|
|
19
|
+
void 0 !== (null == params ? void 0 : params.fadeOutChars) && (this.fadeOutChars = params.fadeOutChars),
|
|
20
|
+
void 0 !== (null == params ? void 0 : params.fadeOutDuration) && (this.fadeOutDuration = params.fadeOutDuration),
|
|
21
|
+
void 0 !== (null == params ? void 0 : params.direction) && (this.direction = params.direction),
|
|
22
|
+
this.propKeys = [ "textConfig" ];
|
|
23
|
+
}
|
|
24
|
+
onFirstRun() {
|
|
25
|
+
const fromProps = this.getLastProps(), toProps = this.getEndProps();
|
|
26
|
+
this.originalTextConfig = fromProps.textConfig ? [ ...fromProps.textConfig ] : [],
|
|
27
|
+
this.valid = !0, this.originalTextConfig && 0 !== this.originalTextConfig.length ? (this.fromTextConfig = vrender_core_1.RichText.TransformTextConfig2SingleCharacter(this.originalTextConfig),
|
|
28
|
+
this.toTextConfig = toProps.textConfig && toProps.textConfig.length > 0 ? vrender_core_1.RichText.TransformTextConfig2SingleCharacter(toProps.textConfig) : []) : this.valid = !1;
|
|
29
|
+
}
|
|
30
|
+
onEnd(cb) {
|
|
31
|
+
super.onEnd(cb), cb || (this.toTextConfig.length > 0 ? this.target.setAttribute("textConfig", this.toTextConfig) : this.target.setAttribute("textConfig", []));
|
|
32
|
+
}
|
|
33
|
+
onUpdate(end, ratio, out) {
|
|
34
|
+
if (!this.valid) return;
|
|
35
|
+
const fromItems = this.fromTextConfig.length, maxTextHideRatio = this.fadeOutChars ? 1 - this.fadeOutDuration : 1;
|
|
36
|
+
let displayedLength;
|
|
37
|
+
if ("forward" === this.direction) {
|
|
38
|
+
if (this.fadeOutChars) {
|
|
39
|
+
const adjustedRatio = Math.min(1, ratio / maxTextHideRatio);
|
|
40
|
+
displayedLength = Math.round(fromItems * (1 - adjustedRatio));
|
|
41
|
+
} else displayedLength = Math.round(fromItems * (1 - ratio));
|
|
42
|
+
let currentTextConfig = "forward" === this.direction ? this.fromTextConfig.slice(fromItems - displayedLength) : this.fromTextConfig.slice(0, displayedLength);
|
|
43
|
+
this.fadeOutChars && (currentTextConfig = this.applyFadeEffect(currentTextConfig, ratio, fromItems, displayedLength)),
|
|
44
|
+
this.showCursor && displayedLength > 0 && (currentTextConfig = this.addCursor(currentTextConfig, ratio)),
|
|
45
|
+
this.target.setAttribute("textConfig", currentTextConfig);
|
|
46
|
+
} else {
|
|
47
|
+
if (this.fadeOutChars) {
|
|
48
|
+
const adjustedRatio = Math.min(1, ratio / maxTextHideRatio);
|
|
49
|
+
displayedLength = Math.round(fromItems * (1 - adjustedRatio));
|
|
50
|
+
} else displayedLength = Math.round(fromItems * (1 - ratio));
|
|
51
|
+
let currentTextConfig = this.fromTextConfig.slice(0, displayedLength);
|
|
52
|
+
this.fadeOutChars && (currentTextConfig = this.applyFadeEffect(currentTextConfig, ratio, fromItems, displayedLength)),
|
|
53
|
+
this.showCursor && displayedLength > 0 && (currentTextConfig = this.addCursor(currentTextConfig, ratio)),
|
|
54
|
+
this.target.setAttribute("textConfig", currentTextConfig);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
applyFadeEffect(textConfig, ratio, totalItems, displayedLength) {
|
|
58
|
+
let fadeIndex;
|
|
59
|
+
fadeIndex = "forward" === this.direction ? totalItems - displayedLength : displayedLength;
|
|
60
|
+
const fadeProgress = (ratio - (1 - this.fadeOutDuration)) / this.fadeOutDuration, fadeOpacity = Math.max(0, 1 - Math.min(1, fadeProgress));
|
|
61
|
+
return textConfig.map(((item, index) => {
|
|
62
|
+
if ("forward" === this.direction) {
|
|
63
|
+
if (0 === index && "text" in item) return Object.assign(Object.assign({}, item), {
|
|
64
|
+
opacity: fadeOpacity
|
|
65
|
+
});
|
|
66
|
+
} else if (index === textConfig.length - 1 && "text" in item) return Object.assign(Object.assign({}, item), {
|
|
67
|
+
opacity: fadeOpacity
|
|
68
|
+
});
|
|
69
|
+
return item;
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
addCursor(textConfig, ratio) {
|
|
73
|
+
let shouldShowCursor = !0;
|
|
74
|
+
if (this.blinkCursor) {
|
|
75
|
+
const blinkRate = .1;
|
|
76
|
+
shouldShowCursor = Math.floor(ratio / blinkRate) % 2 == 0;
|
|
77
|
+
}
|
|
78
|
+
if (shouldShowCursor && textConfig.length > 0) {
|
|
79
|
+
const cursorIndex = "forward" === this.direction ? 0 : textConfig.length - 1, cursorItem = textConfig[cursorIndex];
|
|
80
|
+
if ("text" in cursorItem) {
|
|
81
|
+
const result = [ ...textConfig ];
|
|
82
|
+
return "forward" === this.direction ? result[cursorIndex] = Object.assign(Object.assign({}, cursorItem), {
|
|
83
|
+
text: this.cursorChar + String(cursorItem.text)
|
|
84
|
+
}) : result[cursorIndex] = Object.assign(Object.assign({}, cursorItem), {
|
|
85
|
+
text: String(cursorItem.text) + this.cursorChar
|
|
86
|
+
}), result;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return textConfig;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
exports.OutputRichText = OutputRichText;
|
|
94
|
+
//# sourceMappingURL=output-richtext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/custom/richtext/output-richtext.ts"],"names":[],"mappings":"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","file":"output-richtext.js","sourcesContent":["import { ACustomAnimate } from '../custom-animate';\nimport type { IRichTextCharacter, IAnimate, IStep, EasingType } from '@visactor/vrender-core';\nimport { RichText } from '@visactor/vrender-core';\n\n/**\n * 富文本退出动画,实现类似打字机的字符逐个消失效果\n * 支持通过beforeText和afterText参数添加前缀和后缀\n * 支持通过showCursor参数显示光标,cursorChar自定义光标字符\n * 支持通过fadeOutChars参数开启字符透明度渐变效果\n * 支持通过direction参数控制消失方向(从头到尾或从尾到头)\n */\nexport class OutputRichText extends ACustomAnimate<{ textConfig: IRichTextCharacter[] }> {\n declare valid: boolean;\n\n private fromTextConfig: IRichTextCharacter[] = [];\n private toTextConfig: IRichTextCharacter[] = [];\n private originalTextConfig: IRichTextCharacter[] = [];\n private showCursor: boolean = false;\n private cursorChar: string = '|';\n private blinkCursor: boolean = true;\n private beforeText: string = '';\n private afterText: string = '';\n private fadeOutChars: boolean = false;\n private fadeOutDuration: number = 0.3; // 透明度渐变持续时间,以动画总时长的比例表示\n private direction: 'forward' | 'backward' = 'backward'; // 字符消失方向,默认从尾到头(backward)\n\n constructor(\n from: { textConfig: IRichTextCharacter[] },\n to: { textConfig: IRichTextCharacter[] },\n duration: number,\n easing: EasingType,\n params?: {\n showCursor?: boolean;\n cursorChar?: string;\n blinkCursor?: boolean;\n beforeText?: string;\n afterText?: string;\n fadeOutChars?: boolean;\n fadeOutDuration?: number;\n direction?: 'forward' | 'backward';\n }\n ) {\n super(from, to, duration, easing, params);\n\n // 配置光标相关选项\n if (params?.showCursor !== undefined) {\n this.showCursor = params.showCursor;\n }\n if (params?.cursorChar !== undefined) {\n this.cursorChar = params.cursorChar;\n }\n if (params?.blinkCursor !== undefined) {\n this.blinkCursor = params.blinkCursor;\n }\n\n // 配置前缀和后缀文本\n if (params?.beforeText !== undefined) {\n this.beforeText = params.beforeText;\n }\n if (params?.afterText !== undefined) {\n this.afterText = params.afterText;\n }\n\n // 配置字符透明度渐变效果\n if (params?.fadeOutChars !== undefined) {\n this.fadeOutChars = params.fadeOutChars;\n }\n if (params?.fadeOutDuration !== undefined) {\n this.fadeOutDuration = params.fadeOutDuration;\n }\n\n // 配置方向\n if (params?.direction !== undefined) {\n this.direction = params.direction;\n }\n\n this.propKeys = ['textConfig'];\n }\n\n onFirstRun(): void {\n const fromProps = this.getLastProps();\n const toProps = this.getEndProps();\n\n // 存储原始配置(这里是起始状态,显示所有文本)\n this.originalTextConfig = fromProps.textConfig ? [...fromProps.textConfig] : [];\n\n // 初始化解析结果\n this.valid = true;\n\n // 确保from不为空\n if (!this.originalTextConfig || this.originalTextConfig.length === 0) {\n this.valid = false;\n return;\n }\n\n // 将文本拆分为单个字符,使用RichText的静态方法\n this.fromTextConfig = RichText.TransformTextConfig2SingleCharacter(this.originalTextConfig);\n\n // 目标状态是空文本(或指定的目标)\n this.toTextConfig =\n toProps.textConfig && toProps.textConfig.length > 0\n ? RichText.TransformTextConfig2SingleCharacter(toProps.textConfig)\n : [];\n }\n\n onEnd(cb?: (animate: IAnimate, step: IStep) => void): void {\n super.onEnd(cb);\n if (!cb) {\n // 动画结束时,应用最终textConfig(通常是空的或特定的toTextConfig)\n if (this.toTextConfig.length > 0) {\n this.target.setAttribute('textConfig', this.toTextConfig);\n } else {\n this.target.setAttribute('textConfig', []);\n }\n }\n }\n\n onUpdate(end: boolean, ratio: number, out: Record<string, any>): void {\n if (!this.valid) {\n return;\n }\n\n // 获取当前应该显示的字符\n const fromItems = this.fromTextConfig.length;\n\n // 计算文本显示比例上限 - 如果有渐变效果,需要为尾部字符的渐变留出时间\n const maxTextHideRatio = this.fadeOutChars ? 1 - this.fadeOutDuration : 1;\n\n // 根据方向确定字符消失的顺序\n let displayedLength: number;\n\n if (this.direction === 'forward') {\n // 从前往后消失(类似于正向打字效果)\n if (this.fadeOutChars) {\n // 当ratio达到maxTextHideRatio时,应该已经隐藏全部文本\n const adjustedRatio = Math.min(1, ratio / maxTextHideRatio);\n displayedLength = Math.round(fromItems * (1 - adjustedRatio));\n } else {\n // 无渐变效果时,正常隐藏\n displayedLength = Math.round(fromItems * (1 - ratio));\n }\n\n // 构建从头开始删除的文本配置\n let currentTextConfig =\n this.direction === 'forward'\n ? this.fromTextConfig.slice(fromItems - displayedLength) // 从头开始隐藏,保留尾部\n : this.fromTextConfig.slice(0, displayedLength); // 从尾开始隐藏,保留头部\n\n // 应用透明度渐变效果\n if (this.fadeOutChars) {\n currentTextConfig = this.applyFadeEffect(currentTextConfig, ratio, fromItems, displayedLength);\n }\n\n // 如果启用了光标\n if (this.showCursor && displayedLength > 0) {\n currentTextConfig = this.addCursor(currentTextConfig, ratio);\n }\n\n // 更新富文本的textConfig属性\n this.target.setAttribute('textConfig', currentTextConfig);\n } else {\n // 从后往前消失(类似于退格删除效果)\n if (this.fadeOutChars) {\n // 当ratio达到maxTextHideRatio时,应该已经隐藏全部文本\n const adjustedRatio = Math.min(1, ratio / maxTextHideRatio);\n displayedLength = Math.round(fromItems * (1 - adjustedRatio));\n } else {\n // 无渐变效果时,正常隐藏\n displayedLength = Math.round(fromItems * (1 - ratio));\n }\n\n // 构建从尾开始删除的文本配置\n let currentTextConfig = this.fromTextConfig.slice(0, displayedLength);\n\n // 应用透明度渐变效果\n if (this.fadeOutChars) {\n currentTextConfig = this.applyFadeEffect(currentTextConfig, ratio, fromItems, displayedLength);\n }\n\n // 如果启用了光标\n if (this.showCursor && displayedLength > 0) {\n currentTextConfig = this.addCursor(currentTextConfig, ratio);\n }\n\n // 更新富文本的textConfig属性\n this.target.setAttribute('textConfig', currentTextConfig);\n }\n }\n\n // 应用透明度渐变效果\n private applyFadeEffect(\n textConfig: IRichTextCharacter[],\n ratio: number,\n totalItems: number,\n displayedLength: number\n ): IRichTextCharacter[] {\n // 计算边界字符的索引,这是正在淡出的字符\n let fadeIndex: number;\n\n if (this.direction === 'forward') {\n // 从前往后消失,当前正在淡出的是第displayedLength个字符\n fadeIndex = totalItems - displayedLength;\n } else {\n // 从后往前消失,当前正在淡出的是第displayedLength个字符\n fadeIndex = displayedLength;\n }\n\n // 计算边界字符的透明度\n const fadeProgress = (ratio - (1 - this.fadeOutDuration)) / this.fadeOutDuration;\n const fadeOpacity = Math.max(0, 1 - Math.min(1, fadeProgress));\n\n return textConfig.map((item, index) => {\n if (this.direction === 'forward') {\n // 从前往后消失,第一个字符最先淡出\n if (index === 0 && 'text' in item) {\n return {\n ...item,\n opacity: fadeOpacity\n };\n }\n } else {\n // 从后往前消失,最后一个字符最先淡出\n if (index === textConfig.length - 1 && 'text' in item) {\n return {\n ...item,\n opacity: fadeOpacity\n };\n }\n }\n return item;\n });\n }\n\n // 添加光标\n private addCursor(textConfig: IRichTextCharacter[], ratio: number): IRichTextCharacter[] {\n // 判断是否应该显示光标\n let shouldShowCursor = true;\n\n if (this.blinkCursor) {\n // 闪烁效果:在动画期间,光标每半个周期闪烁一次\n const blinkRate = 0.1; // 光标闪烁频率(每10%动画进度闪烁一次)\n shouldShowCursor = Math.floor(ratio / blinkRate) % 2 === 0;\n }\n\n if (shouldShowCursor && textConfig.length > 0) {\n // 确定光标位置(根据direction)\n const cursorIndex = this.direction === 'forward' ? 0 : textConfig.length - 1;\n const cursorItem = textConfig[cursorIndex];\n\n if ('text' in cursorItem) {\n // 复制数组\n const result = [...textConfig];\n\n if (this.direction === 'forward') {\n // 光标在前面\n result[cursorIndex] = {\n ...cursorItem,\n text: this.cursorChar + String(cursorItem.text)\n };\n } else {\n // 光标在后面\n result[cursorIndex] = {\n ...cursorItem,\n text: String(cursorItem.text) + this.cursorChar\n };\n }\n\n return result;\n }\n }\n\n return textConfig;\n }\n}\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ACustomAnimate } from '../custom-animate';
|
|
2
|
+
import type { IRichTextCharacter, IAnimate, IStep, EasingType } from '@visactor/vrender-core';
|
|
3
|
+
export declare class SlideOutRichText extends ACustomAnimate<{
|
|
4
|
+
textConfig: IRichTextCharacter[];
|
|
5
|
+
}> {
|
|
6
|
+
valid: boolean;
|
|
7
|
+
private fromTextConfig;
|
|
8
|
+
private toTextConfig;
|
|
9
|
+
private originalTextConfig;
|
|
10
|
+
private singleCharConfig;
|
|
11
|
+
private fadeOutDuration;
|
|
12
|
+
private slideDirection;
|
|
13
|
+
private slideDistance;
|
|
14
|
+
private wordByWord;
|
|
15
|
+
private wordRegex;
|
|
16
|
+
private wordGroups;
|
|
17
|
+
private reverseOrder;
|
|
18
|
+
constructor(from: {
|
|
19
|
+
textConfig: IRichTextCharacter[];
|
|
20
|
+
}, to: {
|
|
21
|
+
textConfig: IRichTextCharacter[];
|
|
22
|
+
}, duration: number, easing: EasingType, params?: {
|
|
23
|
+
fadeOutDuration?: number;
|
|
24
|
+
slideDirection?: 'up' | 'down' | 'left' | 'right';
|
|
25
|
+
slideDistance?: number;
|
|
26
|
+
wordByWord?: boolean;
|
|
27
|
+
wordRegex?: RegExp;
|
|
28
|
+
reverseOrder?: boolean;
|
|
29
|
+
});
|
|
30
|
+
onFirstRun(): void;
|
|
31
|
+
private calculateWordGroups;
|
|
32
|
+
private getTargetDx;
|
|
33
|
+
private getTargetDy;
|
|
34
|
+
onEnd(cb?: (animate: IAnimate, step: IStep) => void): void;
|
|
35
|
+
onUpdate(end: boolean, ratio: number, out: Record<string, any>): void;
|
|
36
|
+
private updateByWord;
|
|
37
|
+
private updateByCharacter;
|
|
38
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: !0
|
|
5
|
+
}), exports.SlideOutRichText = void 0;
|
|
6
|
+
|
|
7
|
+
const custom_animate_1 = require("../custom-animate"), vrender_core_1 = require("@visactor/vrender-core");
|
|
8
|
+
|
|
9
|
+
class SlideOutRichText extends custom_animate_1.ACustomAnimate {
|
|
10
|
+
constructor(from, to, duration, easing, params) {
|
|
11
|
+
super(from, to, duration, easing, params), this.fromTextConfig = [], this.toTextConfig = [],
|
|
12
|
+
this.originalTextConfig = [], this.singleCharConfig = [], this.fadeOutDuration = .3,
|
|
13
|
+
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,
|
|
14
|
+
this.wordGroups = [], this.reverseOrder = !1, void 0 !== (null == params ? void 0 : params.fadeOutDuration) && (this.fadeOutDuration = params.fadeOutDuration),
|
|
15
|
+
void 0 !== (null == params ? void 0 : params.slideDirection) && (this.slideDirection = params.slideDirection),
|
|
16
|
+
void 0 !== (null == params ? void 0 : params.slideDistance) && (this.slideDistance = params.slideDistance),
|
|
17
|
+
void 0 !== (null == params ? void 0 : params.wordByWord) && (this.wordByWord = params.wordByWord),
|
|
18
|
+
void 0 !== (null == params ? void 0 : params.wordRegex) && (this.wordRegex = params.wordRegex),
|
|
19
|
+
void 0 !== (null == params ? void 0 : params.reverseOrder) && (this.reverseOrder = params.reverseOrder),
|
|
20
|
+
this.propKeys = [ "textConfig" ];
|
|
21
|
+
}
|
|
22
|
+
onFirstRun() {
|
|
23
|
+
const fromProps = this.getLastProps(), toProps = this.getEndProps();
|
|
24
|
+
this.originalTextConfig = fromProps.textConfig ? [ ...fromProps.textConfig ] : [],
|
|
25
|
+
this.valid = !0, this.originalTextConfig && 0 !== this.originalTextConfig.length ? (this.fromTextConfig = vrender_core_1.RichText.TransformTextConfig2SingleCharacter(this.originalTextConfig),
|
|
26
|
+
this.toTextConfig = toProps.textConfig && toProps.textConfig.length > 0 ? vrender_core_1.RichText.TransformTextConfig2SingleCharacter(toProps.textConfig) : [],
|
|
27
|
+
this.singleCharConfig = this.fromTextConfig.map((item => "text" in item ? Object.assign(Object.assign({}, item), {
|
|
28
|
+
opacity: 1,
|
|
29
|
+
dx: 0,
|
|
30
|
+
dy: 0
|
|
31
|
+
}) : Object.assign(Object.assign({}, item), {
|
|
32
|
+
opacity: 1
|
|
33
|
+
}))), this.wordByWord && this.calculateWordGroups()) : this.valid = !1;
|
|
34
|
+
}
|
|
35
|
+
calculateWordGroups() {
|
|
36
|
+
this.wordGroups = [];
|
|
37
|
+
let fullText = "";
|
|
38
|
+
const charMap = {};
|
|
39
|
+
let match, fullTextIndex = 0;
|
|
40
|
+
for ((this.fromTextConfig.forEach(((item, configIndex) => {
|
|
41
|
+
if ("text" in item) {
|
|
42
|
+
const text = String(item.text);
|
|
43
|
+
fullText += text, charMap[fullTextIndex] = configIndex, fullTextIndex++;
|
|
44
|
+
}
|
|
45
|
+
})), this.wordRegex.lastIndex = 0); null !== (match = this.wordRegex.exec(fullText)); ) {
|
|
46
|
+
const wordStart = match.index, wordEnd = match.index + match[0].length, wordIndices = [];
|
|
47
|
+
for (let i = wordStart; i < wordEnd; i++) void 0 !== charMap[i] && wordIndices.push(charMap[i]);
|
|
48
|
+
wordIndices.length > 0 && this.wordGroups.push(wordIndices);
|
|
49
|
+
}
|
|
50
|
+
const allocatedIndices = new Set;
|
|
51
|
+
this.wordGroups.forEach((group => {
|
|
52
|
+
group.forEach((index => allocatedIndices.add(index)));
|
|
53
|
+
}));
|
|
54
|
+
for (let i = 0; i < this.fromTextConfig.length; i++) "text" in this.fromTextConfig[i] && !allocatedIndices.has(i) && this.wordGroups.push([ i ]);
|
|
55
|
+
}
|
|
56
|
+
getTargetDx() {
|
|
57
|
+
switch (this.slideDirection) {
|
|
58
|
+
case "left":
|
|
59
|
+
return -this.slideDistance;
|
|
60
|
+
|
|
61
|
+
case "right":
|
|
62
|
+
return this.slideDistance;
|
|
63
|
+
|
|
64
|
+
default:
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
getTargetDy() {
|
|
69
|
+
switch (this.slideDirection) {
|
|
70
|
+
case "up":
|
|
71
|
+
return -this.slideDistance;
|
|
72
|
+
|
|
73
|
+
case "down":
|
|
74
|
+
return this.slideDistance;
|
|
75
|
+
|
|
76
|
+
default:
|
|
77
|
+
return 0;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
onEnd(cb) {
|
|
81
|
+
super.onEnd(cb), cb || (this.toTextConfig.length > 0 ? this.target.setAttribute("textConfig", this.toTextConfig) : this.target.setAttribute("textConfig", []));
|
|
82
|
+
}
|
|
83
|
+
onUpdate(end, ratio, out) {
|
|
84
|
+
if (!this.valid) return;
|
|
85
|
+
const maxTextShowRatio = 1 - this.fadeOutDuration;
|
|
86
|
+
let updatedTextConfig;
|
|
87
|
+
updatedTextConfig = this.wordByWord && this.wordGroups.length > 0 ? this.updateByWord(ratio, maxTextShowRatio) : this.updateByCharacter(ratio, maxTextShowRatio),
|
|
88
|
+
this.target.setAttribute("textConfig", updatedTextConfig);
|
|
89
|
+
}
|
|
90
|
+
updateByWord(ratio, maxTextShowRatio) {
|
|
91
|
+
const totalGroups = this.wordGroups.length, updatedTextConfig = [ ...this.singleCharConfig ];
|
|
92
|
+
for (let groupIndex = 0; groupIndex < this.wordGroups.length; groupIndex++) {
|
|
93
|
+
let disappearTime;
|
|
94
|
+
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,
|
|
95
|
+
ratio < disappearTime) {
|
|
96
|
+
for (const charIndex of this.wordGroups[groupIndex]) {
|
|
97
|
+
const item = updatedTextConfig[charIndex];
|
|
98
|
+
"text" in item && (updatedTextConfig[charIndex] = Object.assign(Object.assign({}, item), {
|
|
99
|
+
opacity: 1,
|
|
100
|
+
dx: 0,
|
|
101
|
+
dy: 0
|
|
102
|
+
}));
|
|
103
|
+
}
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
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;
|
|
107
|
+
for (const charIndex of this.wordGroups[groupIndex]) {
|
|
108
|
+
const item = updatedTextConfig[charIndex];
|
|
109
|
+
"text" in item && (updatedTextConfig[charIndex] = Object.assign(Object.assign({}, item), {
|
|
110
|
+
opacity: opacity,
|
|
111
|
+
dx: dx,
|
|
112
|
+
dy: dy
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return updatedTextConfig;
|
|
117
|
+
}
|
|
118
|
+
updateByCharacter(ratio, maxTextShowRatio) {
|
|
119
|
+
const totalItems = this.fromTextConfig.length, updatedTextConfig = [ ...this.singleCharConfig ];
|
|
120
|
+
for (let index = 0; index < updatedTextConfig.length; index++) {
|
|
121
|
+
const item = updatedTextConfig[index];
|
|
122
|
+
if ("text" in item) {
|
|
123
|
+
let disappearTime;
|
|
124
|
+
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,
|
|
125
|
+
ratio < disappearTime) {
|
|
126
|
+
updatedTextConfig[index] = Object.assign(Object.assign({}, item), {
|
|
127
|
+
opacity: 1,
|
|
128
|
+
dx: 0,
|
|
129
|
+
dy: 0
|
|
130
|
+
});
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
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;
|
|
134
|
+
updatedTextConfig[index] = Object.assign(Object.assign({}, item), {
|
|
135
|
+
opacity: opacity,
|
|
136
|
+
dx: dx,
|
|
137
|
+
dy: dy
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return updatedTextConfig;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
exports.SlideOutRichText = SlideOutRichText;
|
|
146
|
+
//# sourceMappingURL=slide-out-richtext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/custom/richtext/slide-out-richtext.ts"],"names":[],"mappings":"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","file":"slide-out-richtext.js","sourcesContent":["import { ACustomAnimate } from '../custom-animate';\nimport type { IRichTextCharacter, IAnimate, IStep, EasingType } from '@visactor/vrender-core';\nimport { RichText } from '@visactor/vrender-core';\n\n/**\n * 滑动富文本退出动画,文字会向指定方向滑出,同时逐字消失\n * 支持上、下、左、右四个方向\n * 支持按单词或字符退场\n */\nexport class SlideOutRichText extends ACustomAnimate<{ textConfig: IRichTextCharacter[] }> {\n declare valid: boolean;\n\n private fromTextConfig: IRichTextCharacter[] = [];\n private toTextConfig: IRichTextCharacter[] = [];\n private originalTextConfig: IRichTextCharacter[] = [];\n private singleCharConfig: IRichTextCharacter[] = [];\n private fadeOutDuration: number = 0.3; // 透明度渐变持续时间,以动画总时长的比例表示\n private slideDirection: 'up' | 'down' | 'left' | 'right' = 'right'; // 滑动方向\n private slideDistance: number = 30; // 滑动距离(像素)\n private wordByWord: boolean = false; // 是否按单词为单位进行动画\n // 默认正则表达式: 匹配英文单词(含中间连字符),连续中文字符,数字,以及独立的符号和空格\n private wordRegex: RegExp = /[a-zA-Z]+(-[a-zA-Z]+)*|[\\u4e00-\\u9fa5]+|[0-9]+|[^\\s\\w\\u4e00-\\u9fa5]/g;\n private wordGroups: number[][] = []; // 存储单词分组信息,每个数组包含属于同一单词的字符索引\n private reverseOrder: boolean = false; // 是否反转字符/单词的消失顺序\n\n constructor(\n from: { textConfig: IRichTextCharacter[] },\n to: { textConfig: IRichTextCharacter[] },\n duration: number,\n easing: EasingType,\n params?: {\n fadeOutDuration?: number;\n slideDirection?: 'up' | 'down' | 'left' | 'right';\n slideDistance?: number;\n wordByWord?: boolean;\n wordRegex?: RegExp;\n reverseOrder?: boolean;\n }\n ) {\n super(from, to, duration, easing, params);\n\n // 配置透明度渐变效果\n if (params?.fadeOutDuration !== undefined) {\n this.fadeOutDuration = params.fadeOutDuration;\n }\n\n // 配置滑动方向和距离\n if (params?.slideDirection !== undefined) {\n this.slideDirection = params.slideDirection;\n }\n if (params?.slideDistance !== undefined) {\n this.slideDistance = params.slideDistance;\n }\n\n // 配置按单词动画\n if (params?.wordByWord !== undefined) {\n this.wordByWord = params.wordByWord;\n }\n if (params?.wordRegex !== undefined) {\n this.wordRegex = params.wordRegex;\n }\n\n // 配置顺序\n if (params?.reverseOrder !== undefined) {\n this.reverseOrder = params.reverseOrder;\n }\n\n this.propKeys = ['textConfig'];\n }\n\n onFirstRun(): void {\n const fromProps = this.getLastProps();\n const toProps = this.getEndProps();\n\n // 存储原始配置\n this.originalTextConfig = fromProps.textConfig ? [...fromProps.textConfig] : [];\n\n // 初始化解析结果\n this.valid = true;\n\n // 确保from不为空\n if (!this.originalTextConfig || this.originalTextConfig.length === 0) {\n this.valid = false;\n return;\n }\n\n // 将文本拆分为单个字符,使用RichText的静态方法\n this.fromTextConfig = RichText.TransformTextConfig2SingleCharacter(this.originalTextConfig);\n\n // 目标状态是空文本(或指定的目标)\n this.toTextConfig =\n toProps.textConfig && toProps.textConfig.length > 0\n ? RichText.TransformTextConfig2SingleCharacter(toProps.textConfig)\n : [];\n\n // 创建单字符数组,用于动画初始状态\n this.singleCharConfig = this.fromTextConfig.map(item => {\n if ('text' in item) {\n // 文本字符初始设置为完全可见且无偏移\n return {\n ...item,\n opacity: 1,\n dx: 0,\n dy: 0\n };\n }\n return { ...item, opacity: 1 };\n });\n\n // 如果启用按单词动画,则计算单词分组\n if (this.wordByWord) {\n this.calculateWordGroups();\n }\n }\n\n // 计算单词分组\n private calculateWordGroups(): void {\n // 重置单词分组\n this.wordGroups = [];\n\n // 构建完整文本用于正则匹配\n let fullText = '';\n const charMap: Record<number, number> = {}; // 映射全文索引到字符配置索引\n let fullTextIndex = 0;\n\n // 构建全文和映射\n this.fromTextConfig.forEach((item, configIndex) => {\n if ('text' in item) {\n const text = String(item.text);\n fullText += text;\n // 为每个字符创建映射\n charMap[fullTextIndex] = configIndex;\n fullTextIndex++;\n }\n });\n\n // 使用正则表达式查找单词\n let match;\n\n // 重置正则表达式状态\n this.wordRegex.lastIndex = 0;\n\n while ((match = this.wordRegex.exec(fullText)) !== null) {\n const wordStart = match.index;\n const wordEnd = match.index + match[0].length;\n\n // 找出属于这个单词的所有字符索引\n const wordIndices = [];\n\n for (let i = wordStart; i < wordEnd; i++) {\n if (charMap[i] !== undefined) {\n wordIndices.push(charMap[i]);\n }\n }\n\n // 添加到单词分组\n if (wordIndices.length > 0) {\n this.wordGroups.push(wordIndices);\n }\n }\n\n // 处理没有分配到任何单词的字符\n const allocatedIndices = new Set<number>();\n this.wordGroups.forEach(group => {\n group.forEach(index => allocatedIndices.add(index));\n });\n\n for (let i = 0; i < this.fromTextConfig.length; i++) {\n if ('text' in this.fromTextConfig[i] && !allocatedIndices.has(i)) {\n // 单独为每个未分配的字符创建一个\"单词\"\n this.wordGroups.push([i]);\n }\n }\n }\n\n // 根据滑动方向计算目标x偏移(最终位置)\n private getTargetDx(): number {\n switch (this.slideDirection) {\n case 'left':\n return -this.slideDistance;\n case 'right':\n return this.slideDistance;\n default:\n return 0;\n }\n }\n\n // 根据滑动方向计算目标y偏移(最终位置)\n private getTargetDy(): number {\n switch (this.slideDirection) {\n case 'up':\n return -this.slideDistance;\n case 'down':\n return this.slideDistance;\n default:\n return 0;\n }\n }\n\n onEnd(cb?: (animate: IAnimate, step: IStep) => void): void {\n super.onEnd(cb);\n if (!cb) {\n // 动画结束时,应用最终textConfig(通常是空的或特定的toTextConfig)\n if (this.toTextConfig.length > 0) {\n this.target.setAttribute('textConfig', this.toTextConfig);\n } else {\n this.target.setAttribute('textConfig', []);\n }\n }\n }\n\n onUpdate(end: boolean, ratio: number, out: Record<string, any>): void {\n if (!this.valid) {\n return;\n }\n\n // 计算文本显示时间比例上限 - 为尾部字符的渐变和滑动效果留出时间\n const maxTextShowRatio = 1 - this.fadeOutDuration;\n\n let updatedTextConfig: IRichTextCharacter[];\n\n if (this.wordByWord && this.wordGroups.length > 0) {\n // 按单词动画\n updatedTextConfig = this.updateByWord(ratio, maxTextShowRatio);\n } else {\n // 按字符动画\n updatedTextConfig = this.updateByCharacter(ratio, maxTextShowRatio);\n }\n\n // 更新富文本的textConfig属性\n this.target.setAttribute('textConfig', updatedTextConfig);\n }\n\n // 按单词更新文本配置\n private updateByWord(ratio: number, maxTextShowRatio: number): IRichTextCharacter[] {\n const totalGroups = this.wordGroups.length;\n const updatedTextConfig = [...this.singleCharConfig];\n\n // 处理单词分组\n for (let groupIndex = 0; groupIndex < this.wordGroups.length; groupIndex++) {\n // 计算这个单词组的消失时间点\n let disappearTime;\n\n if (this.reverseOrder) {\n // 反转顺序 (与入场顺序相反)\n if (this.slideDirection === 'left') {\n // 从左到右的顺序 (第一个单词先消失)\n disappearTime = (groupIndex / totalGroups) * maxTextShowRatio;\n } else {\n // 从右到左的顺序 (最后的单词先消失)\n disappearTime = ((totalGroups - 1 - groupIndex) / totalGroups) * maxTextShowRatio;\n }\n } else {\n // 标准顺序 (与入场顺序相同)\n if (this.slideDirection === 'left') {\n // 从右到左的顺序 (最后的单词先消失)\n disappearTime = ((totalGroups - 1 - groupIndex) / totalGroups) * maxTextShowRatio;\n } else {\n // 从左到右的顺序 (第一个单词先消失)\n disappearTime = (groupIndex / totalGroups) * maxTextShowRatio;\n }\n }\n\n // 如果当前时间还没到显示这个单词的消失时间点,保持可见状态\n if (ratio < disappearTime) {\n for (const charIndex of this.wordGroups[groupIndex]) {\n const item = updatedTextConfig[charIndex];\n if ('text' in item) {\n updatedTextConfig[charIndex] = {\n ...item,\n opacity: 1,\n dx: 0,\n dy: 0\n };\n }\n }\n continue;\n }\n\n // 计算动画进度(0-1之间)\n const animProgress = (ratio - disappearTime) / this.fadeOutDuration;\n const progress = Math.max(0, Math.min(1, animProgress));\n\n // 计算当前偏移和透明度\n const dx = this.getTargetDx() * progress;\n const dy = this.getTargetDy() * progress;\n const opacity = 1 - progress;\n\n // 更新这个单词的所有字符\n for (const charIndex of this.wordGroups[groupIndex]) {\n const item = updatedTextConfig[charIndex];\n if ('text' in item) {\n updatedTextConfig[charIndex] = {\n ...item,\n opacity,\n dx,\n dy\n };\n }\n }\n }\n\n return updatedTextConfig;\n }\n\n // 按字符更新文本配置\n private updateByCharacter(ratio: number, maxTextShowRatio: number): IRichTextCharacter[] {\n const totalItems = this.fromTextConfig.length;\n const updatedTextConfig = [...this.singleCharConfig];\n\n // 更新每个字符的状态\n for (let index = 0; index < updatedTextConfig.length; index++) {\n const item = updatedTextConfig[index];\n if ('text' in item) {\n // 计算每个字符的消失时间点\n let disappearTime;\n\n if (this.reverseOrder) {\n // 反转入场顺序\n if (this.slideDirection === 'left') {\n // 从左到右的顺序 (第一个字符先消失)\n disappearTime = (index / totalItems) * maxTextShowRatio;\n } else {\n // 从右到左的顺序 (最后的字符先消失)\n disappearTime = ((totalItems - 1 - index) / totalItems) * maxTextShowRatio;\n }\n } else {\n // 与入场顺序相同\n if (this.slideDirection === 'left') {\n // 从右到左的顺序 (最后的字符先消失)\n disappearTime = ((totalItems - 1 - index) / totalItems) * maxTextShowRatio;\n } else {\n // 标准顺序 (第一个字符先消失)\n disappearTime = (index / totalItems) * maxTextShowRatio;\n }\n }\n\n // 如果当前时间还没到这个字符的消失时间点,保持可见状态\n if (ratio < disappearTime) {\n updatedTextConfig[index] = {\n ...item,\n opacity: 1,\n dx: 0,\n dy: 0\n };\n continue;\n }\n\n // 计算动画进度(0-1之间)\n const animProgress = (ratio - disappearTime) / this.fadeOutDuration;\n const progress = Math.max(0, Math.min(1, animProgress));\n\n // 计算当前偏移和透明度\n const dx = this.getTargetDx() * progress;\n const dy = this.getTargetDy() * progress;\n const opacity = 1 - progress;\n\n updatedTextConfig[index] = {\n ...item,\n opacity,\n dx,\n dy\n };\n }\n }\n\n return updatedTextConfig;\n }\n}\n"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ACustomAnimate } from '../custom-animate';
|
|
2
|
+
import type { IRichTextCharacter, IAnimate, IStep, EasingType } from '@visactor/vrender-core';
|
|
3
|
+
export declare class SlideRichText extends ACustomAnimate<{
|
|
4
|
+
textConfig: IRichTextCharacter[];
|
|
5
|
+
}> {
|
|
6
|
+
valid: boolean;
|
|
7
|
+
private fromTextConfig;
|
|
8
|
+
private toTextConfig;
|
|
9
|
+
private originalTextConfig;
|
|
10
|
+
private singleCharConfig;
|
|
11
|
+
private fadeInDuration;
|
|
12
|
+
private slideDirection;
|
|
13
|
+
private slideDistance;
|
|
14
|
+
private wordByWord;
|
|
15
|
+
private wordRegex;
|
|
16
|
+
private wordGroups;
|
|
17
|
+
constructor(from: {
|
|
18
|
+
textConfig: IRichTextCharacter[];
|
|
19
|
+
}, to: {
|
|
20
|
+
textConfig: IRichTextCharacter[];
|
|
21
|
+
}, duration: number, easing: EasingType, params?: {
|
|
22
|
+
fadeInDuration?: number;
|
|
23
|
+
slideDirection?: 'up' | 'down' | 'left' | 'right';
|
|
24
|
+
slideDistance?: number;
|
|
25
|
+
wordByWord?: boolean;
|
|
26
|
+
wordRegex?: RegExp;
|
|
27
|
+
});
|
|
28
|
+
onFirstRun(): void;
|
|
29
|
+
private calculateWordGroups;
|
|
30
|
+
private getInitialDx;
|
|
31
|
+
private getInitialDy;
|
|
32
|
+
onEnd(cb?: (animate: IAnimate, step: IStep) => void): void;
|
|
33
|
+
onUpdate(end: boolean, ratio: number, out: Record<string, any>): void;
|
|
34
|
+
private updateByWord;
|
|
35
|
+
private updateByCharacter;
|
|
36
|
+
}
|