@applemusic-like-lyrics/react 0.5.2 → 0.6.0

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/README.md CHANGED
@@ -34,7 +34,7 @@ yarn add @applemusic-like-lyrics/react # using yarn
34
34
 
35
35
  ## Usage Summary
36
36
 
37
- For detailed API documentation, please refer to [./docs/modules.md](./docs/modules.md)
37
+ For detailed API documentation, please refer to [AMLL Docs](https://amll.dev/en/reference/react.html).
38
38
 
39
39
  A test program can be found in [../playground/react/src/test.tsx](../playground/react/src/test.tsx).
40
40
 
@@ -7,66 +7,98 @@ let react_dom = require("react-dom");
7
7
  /**
8
8
  * 流体背景渲染组件,通过提供图片链接可以显示出酷似 Apple Music 的流体背景效果
9
9
  */
10
- const BackgroundRender = (0, react.forwardRef)(({ album, albumIsVideo, fps, playing, flowSpeed, renderScale, staticMode, lowFreqVolume, hasLyric, renderer, style, ...props }, ref) => {
10
+ const BackgroundRender = (0, react.forwardRef)(({ album, albumIsVideo, fps, playing, flowSpeed, renderScale, staticMode, lowFreqVolume, hasLyric, renderer, configureRenderer, style, ...props }, ref) => {
11
11
  const coreBGRenderRef = (0, react.useRef)(null);
12
12
  const wrapperRef = (0, react.useRef)(null);
13
- const lastRendererRef = (0, react.useRef)(null);
13
+ const configureRendererRef = (0, react.useRef)(configureRenderer);
14
+ configureRendererRef.current = configureRenderer;
15
+ const rendererPropsRef = (0, react.useRef)({
16
+ album,
17
+ albumIsVideo,
18
+ fps,
19
+ playing,
20
+ flowSpeed,
21
+ renderScale,
22
+ staticMode,
23
+ lowFreqVolume,
24
+ hasLyric
25
+ });
26
+ rendererPropsRef.current = {
27
+ album,
28
+ albumIsVideo,
29
+ fps,
30
+ playing,
31
+ flowSpeed,
32
+ renderScale,
33
+ staticMode,
34
+ lowFreqVolume,
35
+ hasLyric
36
+ };
14
37
  const curRenderer = renderer ?? _applemusic_like_lyrics_core.MeshGradientRenderer;
15
38
  (0, react.useEffect)(() => {
16
- if (lastRendererRef.current !== curRenderer || coreBGRenderRef.current === void 0) {
17
- lastRendererRef.current = curRenderer;
18
- coreBGRenderRef.current?.dispose();
19
- coreBGRenderRef.current = _applemusic_like_lyrics_core.BackgroundRender.new(curRenderer);
20
- }
21
- }, [curRenderer]);
39
+ const rendererInstance = coreBGRenderRef.current?.getRenderer();
40
+ if (rendererInstance) configureRenderer?.(rendererInstance);
41
+ }, [configureRenderer]);
22
42
  (0, react.useEffect)(() => {
23
- if (curRenderer && album) coreBGRenderRef.current?.setAlbum(album, albumIsVideo);
24
- }, [
25
- curRenderer,
26
- album,
27
- albumIsVideo
28
- ]);
43
+ if (album) coreBGRenderRef.current?.setAlbum(album, albumIsVideo);
44
+ }, [album, albumIsVideo]);
29
45
  (0, react.useEffect)(() => {
30
- if (curRenderer && fps) coreBGRenderRef.current?.setFPS(fps);
31
- }, [curRenderer, fps]);
46
+ if (fps !== void 0) coreBGRenderRef.current?.setFPS(fps);
47
+ }, [fps]);
32
48
  (0, react.useEffect)(() => {
33
- if (!curRenderer) return;
34
49
  if (playing === void 0) coreBGRenderRef.current?.resume();
35
50
  else if (playing) coreBGRenderRef.current?.resume();
36
51
  else coreBGRenderRef.current?.pause();
37
- }, [curRenderer, playing]);
52
+ }, [playing]);
38
53
  (0, react.useEffect)(() => {
39
- if (!curRenderer) return;
40
- if (flowSpeed) coreBGRenderRef.current?.setFlowSpeed(flowSpeed);
41
- }, [curRenderer, flowSpeed]);
54
+ if (flowSpeed !== void 0) coreBGRenderRef.current?.setFlowSpeed(flowSpeed);
55
+ }, [flowSpeed]);
42
56
  (0, react.useEffect)(() => {
43
- if (!curRenderer) return;
44
57
  coreBGRenderRef.current?.setStaticMode(staticMode ?? false);
45
- }, [curRenderer, staticMode]);
58
+ }, [staticMode]);
46
59
  (0, react.useEffect)(() => {
47
- if (curRenderer && renderScale) coreBGRenderRef.current?.setRenderScale(renderScale ?? .5);
48
- }, [curRenderer, renderScale]);
60
+ if (renderScale !== void 0) coreBGRenderRef.current?.setRenderScale(renderScale);
61
+ }, [renderScale]);
49
62
  (0, react.useEffect)(() => {
50
- if (curRenderer && lowFreqVolume) coreBGRenderRef.current?.setLowFreqVolume(lowFreqVolume ?? 1);
51
- }, [curRenderer, lowFreqVolume]);
63
+ if (lowFreqVolume !== void 0) coreBGRenderRef.current?.setLowFreqVolume(lowFreqVolume);
64
+ }, [lowFreqVolume]);
52
65
  (0, react.useEffect)(() => {
53
- if (curRenderer && hasLyric !== void 0) coreBGRenderRef.current?.setHasLyric(hasLyric ?? true);
54
- }, [curRenderer, hasLyric]);
66
+ if (hasLyric !== void 0) coreBGRenderRef.current?.setHasLyric(hasLyric);
67
+ }, [hasLyric]);
55
68
  (0, react.useEffect)(() => {
56
- if (coreBGRenderRef.current) {
57
- const el = coreBGRenderRef.current.getElement();
58
- el.style.width = "100%";
59
- el.style.height = "100%";
60
- el.style.minHeight = "0";
61
- el.style.minWidth = "0";
62
- el.style.overflow = "hidden";
63
- wrapperRef.current?.appendChild(el);
64
- }
65
- }, [coreBGRenderRef.current]);
69
+ const backgroundRender = _applemusic_like_lyrics_core.BackgroundRender.new(curRenderer);
70
+ coreBGRenderRef.current = backgroundRender;
71
+ configureRendererRef.current?.(backgroundRender.getRenderer());
72
+ const current = rendererPropsRef.current;
73
+ if (current.album) backgroundRender.setAlbum(current.album, current.albumIsVideo);
74
+ if (current.fps !== void 0) backgroundRender.setFPS(current.fps);
75
+ if (current.flowSpeed !== void 0) backgroundRender.setFlowSpeed(current.flowSpeed);
76
+ backgroundRender.setStaticMode(current.staticMode ?? false);
77
+ if (current.renderScale !== void 0) backgroundRender.setRenderScale(current.renderScale);
78
+ if (current.lowFreqVolume !== void 0) backgroundRender.setLowFreqVolume(current.lowFreqVolume);
79
+ if (current.hasLyric !== void 0) backgroundRender.setHasLyric(current.hasLyric);
80
+ if (current.playing === false) backgroundRender.pause();
81
+ else backgroundRender.resume();
82
+ const element = backgroundRender.getElement();
83
+ element.style.width = "100%";
84
+ element.style.height = "100%";
85
+ element.style.minHeight = "0";
86
+ element.style.minWidth = "0";
87
+ element.style.overflow = "hidden";
88
+ wrapperRef.current?.appendChild(element);
89
+ return () => {
90
+ backgroundRender.dispose();
91
+ if (coreBGRenderRef.current === backgroundRender) coreBGRenderRef.current = null;
92
+ };
93
+ }, [curRenderer]);
66
94
  (0, react.useImperativeHandle)(ref, () => ({
67
- wrapperEl: wrapperRef.current,
68
- bgRender: coreBGRenderRef.current
69
- }), [wrapperRef.current, coreBGRenderRef.current]);
95
+ get wrapperEl() {
96
+ return wrapperRef.current;
97
+ },
98
+ get bgRender() {
99
+ return coreBGRenderRef.current ?? void 0;
100
+ }
101
+ }), []);
70
102
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
71
103
  style: {
72
104
  display: "contents",
@@ -87,6 +119,7 @@ const LyricPlayer = (0, react.forwardRef)(({ disabled, playing, alignAnchor, ali
87
119
  const [corePlayer, setCorePlayer] = (0, react.useState)();
88
120
  const wrapperRef = (0, react.useRef)(null);
89
121
  const currentTimeRef = (0, react.useRef)(currentTime);
122
+ const prevLyricLinesRef = (0, react.useRef)(lyricLines);
90
123
  (0, react.useLayoutEffect)(() => {
91
124
  const newPlayer = new (lyricPlayer ?? _applemusic_like_lyrics_core.LyricPlayer)();
92
125
  setCorePlayer(newPlayer);
@@ -97,19 +130,29 @@ const LyricPlayer = (0, react.forwardRef)(({ disabled, playing, alignAnchor, ali
97
130
  };
98
131
  }, [lyricPlayer]);
99
132
  (0, react.useLayoutEffect)(() => {
100
- if (optimizeOptions !== void 0) corePlayer?.setOptimizeOptions(optimizeOptions);
101
- if (lyricLines !== void 0) {
102
- corePlayer?.setLyricLines(lyricLines, currentTimeRef.current);
103
- if (currentTimeRef.current !== void 0) corePlayer?.setCurrentTime(currentTimeRef.current, true);
104
- corePlayer?.update();
105
- } else {
106
- corePlayer?.setLyricLines([]);
107
- corePlayer?.update();
108
- }
133
+ if (!corePlayer) return;
134
+ corePlayer.setLyricProcessConfig({
135
+ optimizeOptions,
136
+ maskMode: maskObsceneWordsMode ?? _applemusic_like_lyrics_core.MaskObsceneWordsMode.Disabled,
137
+ maskChar: maskObsceneWordChar ?? "*"
138
+ });
139
+ const lyricLinesChanged = prevLyricLinesRef.current !== lyricLines;
140
+ prevLyricLinesRef.current = lyricLines;
141
+ if (lyricLinesChanged || corePlayer.getLyricLines().length === 0) {
142
+ if (lyricLines !== void 0) {
143
+ corePlayer.setLyricLines(lyricLines, currentTimeRef.current);
144
+ corePlayer.update();
145
+ } else {
146
+ corePlayer.setLyricLines([]);
147
+ corePlayer.update();
148
+ }
149
+ } else corePlayer.rebuildLyricView(currentTimeRef.current);
109
150
  }, [
110
151
  corePlayer,
111
152
  lyricLines,
112
- optimizeOptions
153
+ optimizeOptions,
154
+ maskObsceneWordsMode,
155
+ maskObsceneWordChar
113
156
  ]);
114
157
  (0, react.useEffect)(() => {
115
158
  if (!disabled) {
@@ -122,7 +165,7 @@ const LyricPlayer = (0, react.forwardRef)(({ disabled, playing, alignAnchor, ali
122
165
  lastTime = time;
123
166
  requestAnimationFrame(onFrame);
124
167
  };
125
- corePlayer?.calcLayout();
168
+ corePlayer?.calcLayout(_applemusic_like_lyrics_core.LayoutReason.ConfigChange);
126
169
  requestAnimationFrame(onFrame);
127
170
  return () => {
128
171
  canceled = true;
@@ -130,9 +173,10 @@ const LyricPlayer = (0, react.forwardRef)(({ disabled, playing, alignAnchor, ali
130
173
  }
131
174
  }, [corePlayer, disabled]);
132
175
  (0, react.useEffect)(() => {
133
- if (playing !== void 0) if (playing) corePlayer?.resume();
134
- else corePlayer?.pause();
135
- else corePlayer?.resume();
176
+ if (playing !== void 0) {
177
+ if (playing) corePlayer?.resume();
178
+ else corePlayer?.pause();
179
+ } else corePlayer?.resume();
136
180
  }, [corePlayer, playing]);
137
181
  (0, react.useEffect)(() => {
138
182
  if (alignAnchor !== void 0) corePlayer?.setAlignAnchor(alignAnchor);
@@ -162,14 +206,7 @@ const LyricPlayer = (0, react.forwardRef)(({ disabled, playing, alignAnchor, ali
162
206
  corePlayer?.setCurrentTime(0);
163
207
  currentTimeRef.current = 0;
164
208
  }
165
- }, [
166
- corePlayer,
167
- currentTime,
168
- isSeeking
169
- ]);
170
- (0, react.useEffect)(() => {
171
- corePlayer?.setIsSeeking(!!isSeeking);
172
- }, [corePlayer, isSeeking]);
209
+ }, [corePlayer, currentTime]);
173
210
  (0, react.useEffect)(() => {
174
211
  corePlayer?.setWordFadeWidth(wordFadeWidth);
175
212
  }, [corePlayer, wordFadeWidth]);
@@ -182,13 +219,6 @@ const LyricPlayer = (0, react.forwardRef)(({ disabled, playing, alignAnchor, ali
182
219
  (0, react.useEffect)(() => {
183
220
  if (lineScaleSpringParams !== void 0) corePlayer?.setLineScaleSpringParams(lineScaleSpringParams);
184
221
  }, [corePlayer, lineScaleSpringParams]);
185
- (0, react.useEffect)(() => {
186
- if (maskObsceneWordsMode !== void 0) corePlayer?.setMaskObsceneWords(maskObsceneWordsMode);
187
- else corePlayer?.setMaskObsceneWords(_applemusic_like_lyrics_core.MaskObsceneWordsMode.Disabled);
188
- }, [corePlayer, maskObsceneWordsMode]);
189
- (0, react.useEffect)(() => {
190
- if (maskObsceneWordChar !== void 0) corePlayer?.setMaskObsceneWordChar(maskObsceneWordChar);
191
- }, [corePlayer, maskObsceneWordChar]);
192
222
  (0, react.useEffect)(() => {
193
223
  if (onLyricLineClick) {
194
224
  const handler = (e) => onLyricLineClick(e);
@@ -1 +1 @@
1
- {"version":3,"file":"amll-react.cjs","names":["MeshGradientRenderer","CoreBackgroundRender","DefaultLyricPlayer","MaskObsceneWordsMode"],"sources":["../src/bg-render.tsx","../src/lyric-player.tsx"],"sourcesContent":["import {\n\ttype AbstractBaseRenderer,\n\ttype BaseRenderer,\n\tBackgroundRender as CoreBackgroundRender,\n\tMeshGradientRenderer,\n} from \"@applemusic-like-lyrics/core\";\nimport {\n\ttype ForwardRefExoticComponent,\n\tforwardRef,\n\ttype HTMLProps,\n\ttype RefAttributes,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n} from \"react\";\n\nexport {\n\tBaseRenderer,\n\tMeshGradientRenderer,\n\tPixiRenderer,\n} from \"@applemusic-like-lyrics/core\";\n\n/**\n * 背景渲染组件的属性\n */\nexport interface BackgroundRenderProps {\n\t/**\n\t * 设置背景专辑资源\n\t */\n\talbum?: string | HTMLImageElement | HTMLVideoElement;\n\t/**\n\t * 设置专辑资源是否为视频\n\t */\n\talbumIsVideo?: boolean;\n\t/**\n\t * 设置当前背景动画帧率,如果为 `undefined` 则默认为 `30`\n\t */\n\tfps?: number;\n\t/**\n\t * 设置当前播放状态,如果为 `undefined` 则默认为 `true`\n\t */\n\tplaying?: boolean;\n\t/**\n\t * 设置当前动画流动速度,如果为 `undefined` 则默认为 `2`\n\t */\n\tflowSpeed?: number;\n\t/**\n\t * 设置背景是否根据“是否有歌词”这个特征调整自身效果,例如有歌词时会变得更加活跃\n\t *\n\t * 部分渲染器会根据这个特征调整自身效果\n\t *\n\t * 如果不确定是否需要赋值或无法知晓是否包含歌词,请传入 true 或不做任何处理(默认值为 true)\n\t */\n\thasLyric?: boolean;\n\t/**\n\t * 设置低频的音量大小,范围在 80hz-120hz 之间为宜,取值范围在 [0.0-1.0] 之间\n\t *\n\t * 部分渲染器会根据音量大小调整背景效果(例如根据鼓点跳动)\n\t *\n\t * 如果无法获取到类似的数据,请传入 undefined 或 1.0 作为默认值,或不做任何处理(默认值即 1.0)\n\t */\n\tlowFreqVolume?: number;\n\t/**\n\t * 设置当前渲染缩放比例,如果为 `undefined` 则默认为 `0.5`\n\t */\n\trenderScale?: number;\n\t/**\n\t * 是否启用静态模式,即图片在更换后就会保持静止状态并禁用更新,以节省性能\n\t * 默认为 `false`\n\t */\n\tstaticMode?: boolean;\n\t/**\n\t * 设置渲染器,如果为 `undefined` 则默认为 `PixiRenderer`\n\t * 默认渲染器有可能会随着版本更新而更换\n\t */\n\trenderer?: {\n\t\tnew (...args: ConstructorParameters<typeof BaseRenderer>): BaseRenderer;\n\t};\n}\n\n/**\n * 背景渲染组件的引用\n */\nexport interface BackgroundRenderRef {\n\t/**\n\t * 背景渲染实例引用\n\t */\n\tbgRender?: AbstractBaseRenderer;\n\t/**\n\t * 将背景渲染实例的元素包裹起来的 DIV 元素实例\n\t */\n\twrapperEl: HTMLDivElement | null;\n}\n\n/**\n * 流体背景渲染组件,通过提供图片链接可以显示出酷似 Apple Music 的流体背景效果\n */\nexport const BackgroundRender: ForwardRefExoticComponent<\n\tOmit<HTMLProps<HTMLDivElement> & BackgroundRenderProps, \"ref\"> &\n\t\tRefAttributes<BackgroundRenderRef>\n> = forwardRef<\n\tBackgroundRenderRef,\n\tHTMLProps<HTMLDivElement> & BackgroundRenderProps\n>(\n\t(\n\t\t{\n\t\t\talbum,\n\t\t\talbumIsVideo,\n\t\t\tfps,\n\t\t\tplaying,\n\t\t\tflowSpeed,\n\t\t\trenderScale,\n\t\t\tstaticMode,\n\t\t\tlowFreqVolume,\n\t\t\thasLyric,\n\t\t\trenderer,\n\t\t\tstyle,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst coreBGRenderRef = useRef<AbstractBaseRenderer>(null);\n\t\tconst wrapperRef = useRef<HTMLDivElement>(null);\n\t\tconst lastRendererRef = useRef<{\n\t\t\tnew (canvas: HTMLCanvasElement): BaseRenderer;\n\t\t}>(null);\n\t\tconst curRenderer = renderer ?? MeshGradientRenderer;\n\n\t\tuseEffect(() => {\n\t\t\tif (\n\t\t\t\tlastRendererRef.current !== curRenderer ||\n\t\t\t\tcoreBGRenderRef.current === undefined\n\t\t\t) {\n\t\t\t\tlastRendererRef.current = curRenderer;\n\t\t\t\tcoreBGRenderRef.current?.dispose();\n\t\t\t\tcoreBGRenderRef.current = CoreBackgroundRender.new(curRenderer);\n\t\t\t}\n\t\t}, [curRenderer]);\n\n\t\tuseEffect(() => {\n\t\t\tif (curRenderer && album)\n\t\t\t\tcoreBGRenderRef.current?.setAlbum(album, albumIsVideo);\n\t\t}, [curRenderer, album, albumIsVideo]);\n\n\t\tuseEffect(() => {\n\t\t\tif (curRenderer && fps) coreBGRenderRef.current?.setFPS(fps);\n\t\t}, [curRenderer, fps]);\n\n\t\tuseEffect(() => {\n\t\t\tif (!curRenderer) return;\n\t\t\tif (playing === undefined) {\n\t\t\t\tcoreBGRenderRef.current?.resume();\n\t\t\t} else if (playing) {\n\t\t\t\tcoreBGRenderRef.current?.resume();\n\t\t\t} else {\n\t\t\t\tcoreBGRenderRef.current?.pause();\n\t\t\t}\n\t\t}, [curRenderer, playing]);\n\n\t\tuseEffect(() => {\n\t\t\tif (!curRenderer) return;\n\t\t\tif (flowSpeed) coreBGRenderRef.current?.setFlowSpeed(flowSpeed);\n\t\t}, [curRenderer, flowSpeed]);\n\n\t\tuseEffect(() => {\n\t\t\tif (!curRenderer) return;\n\t\t\tcoreBGRenderRef.current?.setStaticMode(staticMode ?? false);\n\t\t}, [curRenderer, staticMode]);\n\n\t\tuseEffect(() => {\n\t\t\tif (curRenderer && renderScale)\n\t\t\t\tcoreBGRenderRef.current?.setRenderScale(renderScale ?? 0.5);\n\t\t}, [curRenderer, renderScale]);\n\n\t\tuseEffect(() => {\n\t\t\tif (curRenderer && lowFreqVolume)\n\t\t\t\tcoreBGRenderRef.current?.setLowFreqVolume(lowFreqVolume ?? 1.0);\n\t\t}, [curRenderer, lowFreqVolume]);\n\n\t\tuseEffect(() => {\n\t\t\tif (curRenderer && hasLyric !== undefined)\n\t\t\t\tcoreBGRenderRef.current?.setHasLyric(hasLyric ?? true);\n\t\t}, [curRenderer, hasLyric]);\n\n\t\t// biome-ignore lint/correctness/useExhaustiveDependencies: coreBGRenderRef.current\n\t\tuseEffect(() => {\n\t\t\tif (coreBGRenderRef.current) {\n\t\t\t\tconst el = coreBGRenderRef.current.getElement();\n\t\t\t\tel.style.width = \"100%\";\n\t\t\t\tel.style.height = \"100%\";\n\t\t\t\tel.style.minHeight = \"0\";\n\t\t\t\tel.style.minWidth = \"0\";\n\t\t\t\tel.style.overflow = \"hidden\";\n\t\t\t\twrapperRef.current?.appendChild(el);\n\t\t\t}\n\t\t}, [coreBGRenderRef.current]);\n\n\t\t// biome-ignore lint/correctness/useExhaustiveDependencies: wrapperRef.current, coreBGRenderRef.current\n\t\tuseImperativeHandle(\n\t\t\tref,\n\t\t\t() => ({\n\t\t\t\twrapperEl: wrapperRef.current,\n\t\t\t\tbgRender: coreBGRenderRef.current as AbstractBaseRenderer,\n\t\t\t}),\n\t\t\t[wrapperRef.current, coreBGRenderRef.current],\n\t\t);\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: \"contents\",\n\t\t\t\t\t...style,\n\t\t\t\t}}\n\t\t\t\t{...props}\n\t\t\t\tref={wrapperRef}\n\t\t\t/>\n\t\t);\n\t},\n);\n","import type {\n\tLyricLine,\n\tLyricLineMouseEvent,\n\tLyricPlayerBase,\n\tOptimizeLyricOptions,\n\tspring,\n} from \"@applemusic-like-lyrics/core\";\nimport {\n\tLyricPlayer as DefaultLyricPlayer,\n\tMaskObsceneWordsMode,\n} from \"@applemusic-like-lyrics/core\";\nimport {\n\ttype ForwardRefExoticComponent,\n\tforwardRef,\n\ttype HTMLProps,\n\ttype RefAttributes,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\n/**\n * 歌词播放组件的属性\n */\nexport interface LyricPlayerProps {\n\t/**\n\t * 是否禁用歌词播放组件,默认为 `false`,歌词组件启用后将会开始逐帧更新歌词的动画效果,并对传入的其他参数变更做出反馈。\n\t *\n\t * 如果禁用了歌词组件动画,你也可以通过引用取得原始渲染组件实例,手动逐帧调用其 `update` 函数来更新动画效果。\n\t */\n\tdisabled?: boolean;\n\t/**\n\t * 是否演出部分效果,目前会控制播放间奏点的动画的播放暂停与否,默认为 `true`\n\t */\n\tplaying?: boolean;\n\t/**\n\t * 设置歌词行的对齐方式,如果为 `undefined` 则默认为 `center`\n\t *\n\t * - 设置成 `top` 的话将会向目标歌词行的顶部对齐\n\t * - 设置成 `bottom` 的话将会向目标歌词行的底部对齐\n\t * - 设置成 `center` 的话将会向目标歌词行的垂直中心对齐\n\t */\n\talignAnchor?: \"top\" | \"bottom\" | \"center\";\n\t/**\n\t * 设置默认的歌词行对齐位置,相对于整个歌词播放组件的大小位置,如果为 `undefined`\n\t * 则默认为 `0.5`\n\t *\n\t * 可以设置一个 `[0.0-1.0]` 之间的任意数字,代表组件高度由上到下的比例位置\n\t */\n\talignPosition?: number;\n\t/**\n\t * 设置是否使用物理弹簧算法实现歌词动画效果,默认启用\n\t *\n\t * 如果启用,则会通过弹簧算法实时处理歌词位置,但是需要性能足够强劲的电脑方可流畅运行\n\t *\n\t * 如果不启用,则会回退到基于 `transition` 的过渡效果,对低性能的机器比较友好,但是效果会比较单一\n\t */\n\tenableSpring?: boolean;\n\t/**\n\t * 设置是否启用歌词行的模糊效果,默认为 `true`\n\t */\n\tenableBlur?: boolean;\n\t/**\n\t * 设置是否使用物理弹簧算法实现歌词动画效果,默认启用\n\t *\n\t * 如果启用,则会通过弹簧算法实时处理歌词位置,但是需要性能足够强劲的电脑方可流畅运行\n\t *\n\t * 如果不启用,则会回退到基于 `transition` 的过渡效果,对低性能的机器比较友好,但是效果会比较单一\n\t */\n\tenableScale?: boolean;\n\t/**\n\t * 设置是否隐藏已经播放过的歌词行,默认不隐藏\n\t */\n\thidePassedLines?: boolean;\n\t/**\n\t * 设置歌词中不雅用语的掩码模式,默认为 `MaskObsceneWordsMode.Disabled`,即不掩码\n\t */\n\tmaskObsceneWordsMode?: MaskObsceneWordsMode;\n\t/**\n\t * 设置不雅用语掩码使用的字符,默认为 `*`\n\t */\n\tmaskObsceneWordChar?: string;\n\t/**\n\t * 设置歌词优化选项\n\t */\n\toptimizeOptions?: OptimizeLyricOptions;\n\t/**\n\t * 设置当前播放歌词,要注意传入后这个数组内的信息不得修改,否则会发生错误\n\t */\n\tlyricLines?: LyricLine[];\n\t/**\n\t * 设置当前播放进度,单位为毫秒且**必须是整数**,此时将会更新内部的歌词进度信息\n\t * 内部会根据调用间隔和播放进度自动决定如何滚动和显示歌词,所以这个的调用频率越快越准确越好\n\t */\n\tcurrentTime?: number;\n\tisSeeking?: boolean;\n\t/**\n\t * 设置文字动画的渐变宽度,单位以歌词行的主文字字体大小的倍数为单位,默认为 0.5,即一个全角字符的一半宽度\n\t *\n\t * 如果要模拟 Apple Music for Android 的效果,可以设置为 1\n\t *\n\t * 如果要模拟 Apple Music for iPad 的效果,可以设置为 0.5\n\t *\n\t * 如果想要近乎禁用渐变效果,可以设置成非常接近 0 的小数(例如 `0.0001` ),但是**不可以为 0**\n\t */\n\twordFadeWidth?: number;\n\t/**\n\t * 设置所有歌词行在横坐标上的弹簧属性,包括重量、弹力和阻力。\n\t *\n\t * @param params 需要设置的弹簧属性,提供的属性将会覆盖原来的属性,未提供的属性将会保持原样\n\t */\n\tlinePosXSpringParams?: Partial<spring.SpringParams>;\n\t/**\n\t * 设置所有歌词行在​纵坐标上的弹簧属性,包括重量、弹力和阻力。\n\t *\n\t * @param params 需要设置的弹簧属性,提供的属性将会覆盖原来的属性,未提供的属性将会保持原样\n\t */\n\tlinePosYSpringParams?: Partial<spring.SpringParams>;\n\t/**\n\t * 设置所有歌词行在​缩放大小上的弹簧属性,包括重量、弹力和阻力。\n\t *\n\t * @param params 需要设置的弹簧属性,提供的属性将会覆盖原来的属性,未提供的属性将会保持原样\n\t */\n\tlineScaleSpringParams?: Partial<spring.SpringParams>;\n\t/**\n\t * 在一个特殊的底栏元素内加入指定元素,默认是空白的,可以往内部添加任意元素\n\t *\n\t * 这个元素始终在歌词的底部,可以用于显示歌曲创作者等信息\n\t */\n\tbottomLine?: Parameters<typeof createPortal>[0];\n\t/**\n\t * 需要用于创建歌词播放组件的类实例\n\t */\n\tlyricPlayer?: {\n\t\tnew (\n\t\t\t...args: ConstructorParameters<typeof LyricPlayerBase>\n\t\t): LyricPlayerBase;\n\t};\n\t/**\n\t * 当某个歌词行被左键点击时触发的事件\n\t * @param line 歌词行的事件对象,可以访问到对应的歌词行信息和歌词行索引\n\t */\n\tonLyricLineClick?: (line: LyricLineMouseEvent) => void;\n\t/**\n\t * 当某个歌词行被右键点击时触发的事件\n\t * @param line 歌词行的事件对象,可以访问到对应的歌词行信息和歌词行索引\n\t */\n\tonLyricLineContextMenu?: (line: LyricLineMouseEvent) => void;\n}\n\n/**\n * 歌词播放组件的引用\n */\nexport interface LyricPlayerRef {\n\t/**\n\t * 歌词播放实例\n\t */\n\tlyricPlayer?: LyricPlayerBase;\n\t/**\n\t * 将歌词播放实例的元素包裹起来的 DIV 元素实例\n\t */\n\twrapperEl: HTMLDivElement | null;\n}\n\n/**\n * 歌词播放组件,本框架的核心组件\n *\n * 尽可能贴切 Apple Music for iPad 的歌词效果设计,且做了力所能及的优化措施\n */\nexport const LyricPlayer: ForwardRefExoticComponent<\n\tOmit<HTMLProps<HTMLDivElement> & LyricPlayerProps, \"ref\"> &\n\t\tRefAttributes<LyricPlayerRef>\n> = forwardRef<LyricPlayerRef, HTMLProps<HTMLDivElement> & LyricPlayerProps>(\n\t(\n\t\t{\n\t\t\tdisabled,\n\t\t\tplaying,\n\t\t\talignAnchor,\n\t\t\talignPosition,\n\t\t\tenableSpring,\n\t\t\tenableBlur,\n\t\t\tenableScale,\n\t\t\tmaskObsceneWordsMode,\n\t\t\tmaskObsceneWordChar,\n\t\t\thidePassedLines,\n\t\t\toptimizeOptions,\n\t\t\tlyricLines,\n\t\t\tcurrentTime,\n\t\t\tisSeeking,\n\t\t\twordFadeWidth,\n\t\t\tlinePosXSpringParams,\n\t\t\tlinePosYSpringParams,\n\t\t\tlineScaleSpringParams,\n\t\t\tbottomLine,\n\t\t\tlyricPlayer,\n\t\t\tonLyricLineClick,\n\t\t\tonLyricLineContextMenu,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\t// const corePlayerRef = useRef<LyricPlayerBase>();\n\t\tconst [corePlayer, setCorePlayer] = useState<LyricPlayerBase>();\n\t\tconst wrapperRef = useRef<HTMLDivElement>(null);\n\t\tconst currentTimeRef = useRef(currentTime);\n\n\t\tuseLayoutEffect(() => {\n\t\t\tconst newPlayer = new (lyricPlayer ?? DefaultLyricPlayer)();\n\t\t\tsetCorePlayer(newPlayer);\n\t\t\twrapperRef.current?.appendChild(newPlayer.getElement());\n\t\t\treturn () => {\n\t\t\t\tnewPlayer?.dispose();\n\t\t\t\tsetCorePlayer(undefined);\n\t\t\t};\n\t\t}, [lyricPlayer]);\n\n\t\tuseLayoutEffect(() => {\n\t\t\tif (optimizeOptions !== undefined) {\n\t\t\t\tcorePlayer?.setOptimizeOptions(optimizeOptions);\n\t\t\t}\n\n\t\t\tif (lyricLines !== undefined) {\n\t\t\t\tcorePlayer?.setLyricLines(lyricLines, currentTimeRef.current);\n\n\t\t\t\tif (currentTimeRef.current !== undefined) {\n\t\t\t\t\tcorePlayer?.setCurrentTime(currentTimeRef.current, true);\n\t\t\t\t}\n\n\t\t\t\tcorePlayer?.update();\n\t\t\t} else {\n\t\t\t\tcorePlayer?.setLyricLines([]);\n\t\t\t\tcorePlayer?.update();\n\t\t\t}\n\t\t}, [corePlayer, lyricLines, optimizeOptions]);\n\n\t\tuseEffect(() => {\n\t\t\tif (!disabled) {\n\t\t\t\tlet canceled = false;\n\t\t\t\tlet lastTime = -1;\n\t\t\t\tconst onFrame = (time: number) => {\n\t\t\t\t\tif (canceled) return;\n\t\t\t\t\tif (lastTime === -1) {\n\t\t\t\t\t\tlastTime = time;\n\t\t\t\t\t}\n\t\t\t\t\tcorePlayer?.update(time - lastTime);\n\t\t\t\t\tlastTime = time;\n\t\t\t\t\trequestAnimationFrame(onFrame);\n\t\t\t\t};\n\t\t\t\tcorePlayer?.calcLayout();\n\t\t\t\trequestAnimationFrame(onFrame);\n\t\t\t\treturn () => {\n\t\t\t\t\tcanceled = true;\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn;\n\t\t}, [corePlayer, disabled]);\n\n\t\tuseEffect(() => {\n\t\t\tif (playing !== undefined) {\n\t\t\t\tif (playing) {\n\t\t\t\t\tcorePlayer?.resume();\n\t\t\t\t} else {\n\t\t\t\t\tcorePlayer?.pause();\n\t\t\t\t}\n\t\t\t} else corePlayer?.resume();\n\t\t}, [corePlayer, playing]);\n\n\t\tuseEffect(() => {\n\t\t\tif (alignAnchor !== undefined) corePlayer?.setAlignAnchor(alignAnchor);\n\t\t}, [corePlayer, alignAnchor]);\n\n\t\tuseEffect(() => {\n\t\t\tif (hidePassedLines !== undefined)\n\t\t\t\tcorePlayer?.setHidePassedLines(hidePassedLines);\n\t\t}, [corePlayer, hidePassedLines]);\n\n\t\tuseEffect(() => {\n\t\t\tif (alignPosition !== undefined)\n\t\t\t\tcorePlayer?.setAlignPosition(alignPosition);\n\t\t}, [corePlayer, alignPosition]);\n\n\t\tuseEffect(() => {\n\t\t\tif (enableSpring !== undefined) corePlayer?.setEnableSpring(enableSpring);\n\t\t\telse corePlayer?.setEnableSpring(true);\n\t\t}, [corePlayer, enableSpring]);\n\n\t\tuseEffect(() => {\n\t\t\tif (enableScale !== undefined) corePlayer?.setEnableScale(enableScale);\n\t\t\telse corePlayer?.setEnableScale(true);\n\t\t}, [corePlayer, enableScale]);\n\n\t\tuseEffect(() => {\n\t\t\tcorePlayer?.setEnableBlur(enableBlur ?? true);\n\t\t}, [corePlayer, enableBlur]);\n\n\t\tuseLayoutEffect(() => {\n\t\t\tif (currentTime !== undefined) {\n\t\t\t\tcorePlayer?.setCurrentTime(currentTime, isSeeking);\n\t\t\t\tcurrentTimeRef.current = currentTime;\n\t\t\t} else {\n\t\t\t\tcorePlayer?.setCurrentTime(0);\n\t\t\t\tcurrentTimeRef.current = 0;\n\t\t\t}\n\t\t}, [corePlayer, currentTime, isSeeking]);\n\n\t\tuseEffect(() => {\n\t\t\tcorePlayer?.setIsSeeking(!!isSeeking);\n\t\t}, [corePlayer, isSeeking]);\n\n\t\tuseEffect(() => {\n\t\t\tcorePlayer?.setWordFadeWidth(wordFadeWidth);\n\t\t}, [corePlayer, wordFadeWidth]);\n\n\t\tuseEffect(() => {\n\t\t\tif (linePosXSpringParams !== undefined)\n\t\t\t\tcorePlayer?.setLinePosXSpringParams(linePosXSpringParams);\n\t\t}, [corePlayer, linePosXSpringParams]);\n\n\t\tuseEffect(() => {\n\t\t\tif (linePosYSpringParams !== undefined)\n\t\t\t\tcorePlayer?.setLinePosYSpringParams(linePosYSpringParams);\n\t\t}, [corePlayer, linePosYSpringParams]);\n\n\t\tuseEffect(() => {\n\t\t\tif (lineScaleSpringParams !== undefined)\n\t\t\t\tcorePlayer?.setLineScaleSpringParams(lineScaleSpringParams);\n\t\t}, [corePlayer, lineScaleSpringParams]);\n\n\t\tuseEffect(() => {\n\t\t\tif (maskObsceneWordsMode !== undefined) {\n\t\t\t\tcorePlayer?.setMaskObsceneWords(maskObsceneWordsMode);\n\t\t\t} else {\n\t\t\t\tcorePlayer?.setMaskObsceneWords(MaskObsceneWordsMode.Disabled);\n\t\t\t}\n\t\t}, [corePlayer, maskObsceneWordsMode]);\n\n\t\tuseEffect(() => {\n\t\t\tif (maskObsceneWordChar !== undefined) {\n\t\t\t\tcorePlayer?.setMaskObsceneWordChar(maskObsceneWordChar);\n\t\t\t}\n\t\t}, [corePlayer, maskObsceneWordChar]);\n\n\t\tuseEffect(() => {\n\t\t\tif (onLyricLineClick) {\n\t\t\t\tconst handler = (e: Event) =>\n\t\t\t\t\tonLyricLineClick(e as LyricLineMouseEvent);\n\t\t\t\tcorePlayer?.addEventListener(\"line-click\", handler);\n\t\t\t\treturn () => corePlayer?.removeEventListener(\"line-click\", handler);\n\t\t\t}\n\t\t\treturn;\n\t\t}, [corePlayer, onLyricLineClick]);\n\n\t\tuseEffect(() => {\n\t\t\tif (onLyricLineContextMenu) {\n\t\t\t\tconst handler = (e: Event) =>\n\t\t\t\t\tonLyricLineContextMenu(e as LyricLineMouseEvent);\n\t\t\t\tcorePlayer?.addEventListener(\"line-contextmenu\", handler);\n\t\t\t\treturn () =>\n\t\t\t\t\tcorePlayer?.removeEventListener(\"line-contextmenu\", handler);\n\t\t\t}\n\t\t\treturn;\n\t\t}, [corePlayer, onLyricLineContextMenu]);\n\n\t\tuseImperativeHandle(\n\t\t\tref,\n\t\t\t() => ({\n\t\t\t\twrapperEl: wrapperRef.current,\n\t\t\t\tlyricPlayer: corePlayer,\n\t\t\t}),\n\t\t\t[corePlayer],\n\t\t);\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<div {...props} ref={wrapperRef} />\n\t\t\t\t{corePlayer?.getBottomLineElement() && bottomLine\n\t\t\t\t\t? createPortal(bottomLine, corePlayer?.getBottomLineElement())\n\t\t\t\t\t: null}\n\t\t\t</>\n\t\t);\n\t},\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"amll-react.cjs","names":["forwardRef","useRef","MeshGradientRenderer","CoreBackgroundRender","forwardRef","useState","useRef","DefaultLyricPlayer","MaskObsceneWordsMode","LayoutReason","createPortal"],"sources":["../src/bg-render.tsx","../src/lyric-player.tsx"],"sourcesContent":["import {\n\ttype AbstractBaseRenderer,\n\ttype BaseRenderer,\n\tBackgroundRender as CoreBackgroundRender,\n\tMeshGradientRenderer,\n} from \"@applemusic-like-lyrics/core\";\nimport {\n\ttype ForwardRefExoticComponent,\n\tforwardRef,\n\ttype HTMLProps,\n\ttype RefAttributes,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n} from \"react\";\n\nexport {\n\tBaseRenderer,\n\tMeshGradientRenderer,\n\tPixiRenderer,\n} from \"@applemusic-like-lyrics/core\";\n\n/**\n * 背景渲染组件的属性\n */\nexport interface BackgroundRenderProps {\n\t/**\n\t * 设置背景专辑资源\n\t */\n\talbum?: string | HTMLImageElement | HTMLVideoElement;\n\t/**\n\t * 设置专辑资源是否为视频\n\t */\n\talbumIsVideo?: boolean;\n\t/**\n\t * 设置当前背景动画帧率,如果为 `undefined` 则默认为 `30`\n\t */\n\tfps?: number;\n\t/**\n\t * 设置当前播放状态,如果为 `undefined` 则默认为 `true`\n\t */\n\tplaying?: boolean;\n\t/**\n\t * 设置当前动画流动速度,如果为 `undefined` 则默认为 `2`\n\t */\n\tflowSpeed?: number;\n\t/**\n\t * 设置背景是否根据“是否有歌词”这个特征调整自身效果,例如有歌词时会变得更加活跃\n\t *\n\t * 部分渲染器会根据这个特征调整自身效果\n\t *\n\t * 如果不确定是否需要赋值或无法知晓是否包含歌词,请传入 true 或不做任何处理(默认值为 true)\n\t */\n\thasLyric?: boolean;\n\t/**\n\t * 设置低频的音量大小,范围在 80hz-120hz 之间为宜,取值范围在 [0.0-1.0] 之间\n\t *\n\t * 部分渲染器会根据音量大小调整背景效果(例如根据鼓点跳动)\n\t *\n\t * 如果无法获取到类似的数据,请传入 undefined 或 1.0 作为默认值,或不做任何处理(默认值即 1.0)\n\t */\n\tlowFreqVolume?: number;\n\t/**\n\t * 设置当前渲染缩放比例,如果为 `undefined` 则默认为 `0.5`\n\t */\n\trenderScale?: number;\n\t/**\n\t * 是否启用静态模式,即图片在更换后就会保持静止状态并禁用更新,以节省性能\n\t * 默认为 `false`\n\t */\n\tstaticMode?: boolean;\n\t/**\n\t * 设置渲染器,如果为 `undefined` 则默认为 `MeshGradientRenderer`\n\t * 默认渲染器有可能会随着版本更新而更换\n\t */\n\trenderer?: {\n\t\tnew (...args: ConstructorParameters<typeof BaseRenderer>): BaseRenderer;\n\t};\n\t/**\n\t * 配置当前渲染器实例。\n\t *\n\t * 渲染器创建或回调变化后调用,可用于下发特定渲染器才支持的选项。\n\t */\n\tconfigureRenderer?: (renderer: BaseRenderer) => void;\n}\n\n/**\n * 背景渲染组件的引用\n */\nexport interface BackgroundRenderRef {\n\t/**\n\t * 背景渲染实例引用\n\t */\n\tbgRender?: AbstractBaseRenderer;\n\t/**\n\t * 将背景渲染实例的元素包裹起来的 DIV 元素实例\n\t */\n\twrapperEl: HTMLDivElement | null;\n}\n\n/**\n * 流体背景渲染组件,通过提供图片链接可以显示出酷似 Apple Music 的流体背景效果\n */\nexport const BackgroundRender: ForwardRefExoticComponent<\n\tOmit<HTMLProps<HTMLDivElement> & BackgroundRenderProps, \"ref\"> &\n\t\tRefAttributes<BackgroundRenderRef>\n> = forwardRef<\n\tBackgroundRenderRef,\n\tHTMLProps<HTMLDivElement> & BackgroundRenderProps\n>(\n\t(\n\t\t{\n\t\t\talbum,\n\t\t\talbumIsVideo,\n\t\t\tfps,\n\t\t\tplaying,\n\t\t\tflowSpeed,\n\t\t\trenderScale,\n\t\t\tstaticMode,\n\t\t\tlowFreqVolume,\n\t\t\thasLyric,\n\t\t\trenderer,\n\t\t\tconfigureRenderer,\n\t\t\tstyle,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst coreBGRenderRef = useRef<CoreBackgroundRender<BaseRenderer>>(null);\n\t\tconst wrapperRef = useRef<HTMLDivElement>(null);\n\t\tconst configureRendererRef = useRef(configureRenderer);\n\t\tconfigureRendererRef.current = configureRenderer;\n\t\tconst rendererPropsRef = useRef({\n\t\t\talbum,\n\t\t\talbumIsVideo,\n\t\t\tfps,\n\t\t\tplaying,\n\t\t\tflowSpeed,\n\t\t\trenderScale,\n\t\t\tstaticMode,\n\t\t\tlowFreqVolume,\n\t\t\thasLyric,\n\t\t});\n\t\trendererPropsRef.current = {\n\t\t\talbum,\n\t\t\talbumIsVideo,\n\t\t\tfps,\n\t\t\tplaying,\n\t\t\tflowSpeed,\n\t\t\trenderScale,\n\t\t\tstaticMode,\n\t\t\tlowFreqVolume,\n\t\t\thasLyric,\n\t\t};\n\t\tconst curRenderer = renderer ?? MeshGradientRenderer;\n\n\t\tuseEffect(() => {\n\t\t\tconst rendererInstance = coreBGRenderRef.current?.getRenderer();\n\t\t\tif (rendererInstance) configureRenderer?.(rendererInstance);\n\t\t}, [configureRenderer]);\n\n\t\tuseEffect(() => {\n\t\t\tif (album) coreBGRenderRef.current?.setAlbum(album, albumIsVideo);\n\t\t}, [album, albumIsVideo]);\n\n\t\tuseEffect(() => {\n\t\t\tif (fps !== undefined) coreBGRenderRef.current?.setFPS(fps);\n\t\t}, [fps]);\n\n\t\tuseEffect(() => {\n\t\t\tif (playing === undefined) {\n\t\t\t\tcoreBGRenderRef.current?.resume();\n\t\t\t} else if (playing) {\n\t\t\t\tcoreBGRenderRef.current?.resume();\n\t\t\t} else {\n\t\t\t\tcoreBGRenderRef.current?.pause();\n\t\t\t}\n\t\t}, [playing]);\n\n\t\tuseEffect(() => {\n\t\t\tif (flowSpeed !== undefined) {\n\t\t\t\tcoreBGRenderRef.current?.setFlowSpeed(flowSpeed);\n\t\t\t}\n\t\t}, [flowSpeed]);\n\n\t\tuseEffect(() => {\n\t\t\tcoreBGRenderRef.current?.setStaticMode(staticMode ?? false);\n\t\t}, [staticMode]);\n\n\t\tuseEffect(() => {\n\t\t\tif (renderScale !== undefined) {\n\t\t\t\tcoreBGRenderRef.current?.setRenderScale(renderScale);\n\t\t\t}\n\t\t}, [renderScale]);\n\n\t\tuseEffect(() => {\n\t\t\tif (lowFreqVolume !== undefined) {\n\t\t\t\tcoreBGRenderRef.current?.setLowFreqVolume(lowFreqVolume);\n\t\t\t}\n\t\t}, [lowFreqVolume]);\n\n\t\tuseEffect(() => {\n\t\t\tif (hasLyric !== undefined) {\n\t\t\t\tcoreBGRenderRef.current?.setHasLyric(hasLyric);\n\t\t\t}\n\t\t}, [hasLyric]);\n\n\t\tuseEffect(() => {\n\t\t\tconst backgroundRender = CoreBackgroundRender.new(curRenderer);\n\t\t\tcoreBGRenderRef.current = backgroundRender;\n\t\t\tconfigureRendererRef.current?.(backgroundRender.getRenderer());\n\n\t\t\tconst current = rendererPropsRef.current;\n\t\t\tif (current.album) {\n\t\t\t\tbackgroundRender.setAlbum(current.album, current.albumIsVideo);\n\t\t\t}\n\t\t\tif (current.fps !== undefined) backgroundRender.setFPS(current.fps);\n\t\t\tif (current.flowSpeed !== undefined) {\n\t\t\t\tbackgroundRender.setFlowSpeed(current.flowSpeed);\n\t\t\t}\n\t\t\tbackgroundRender.setStaticMode(current.staticMode ?? false);\n\t\t\tif (current.renderScale !== undefined) {\n\t\t\t\tbackgroundRender.setRenderScale(current.renderScale);\n\t\t\t}\n\t\t\tif (current.lowFreqVolume !== undefined) {\n\t\t\t\tbackgroundRender.setLowFreqVolume(current.lowFreqVolume);\n\t\t\t}\n\t\t\tif (current.hasLyric !== undefined) {\n\t\t\t\tbackgroundRender.setHasLyric(current.hasLyric);\n\t\t\t}\n\t\t\tif (current.playing === false) backgroundRender.pause();\n\t\t\telse backgroundRender.resume();\n\n\t\t\tconst element = backgroundRender.getElement();\n\t\t\telement.style.width = \"100%\";\n\t\t\telement.style.height = \"100%\";\n\t\t\telement.style.minHeight = \"0\";\n\t\t\telement.style.minWidth = \"0\";\n\t\t\telement.style.overflow = \"hidden\";\n\t\t\twrapperRef.current?.appendChild(element);\n\n\t\t\treturn () => {\n\t\t\t\tbackgroundRender.dispose();\n\t\t\t\tif (coreBGRenderRef.current === backgroundRender) {\n\t\t\t\t\tcoreBGRenderRef.current = null;\n\t\t\t\t}\n\t\t\t};\n\t\t}, [curRenderer]);\n\n\t\tuseImperativeHandle(\n\t\t\tref,\n\t\t\t() => ({\n\t\t\t\tget wrapperEl() {\n\t\t\t\t\treturn wrapperRef.current;\n\t\t\t\t},\n\t\t\t\tget bgRender() {\n\t\t\t\t\treturn coreBGRenderRef.current ?? undefined;\n\t\t\t\t},\n\t\t\t}),\n\t\t\t[],\n\t\t);\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: \"contents\",\n\t\t\t\t\t...style,\n\t\t\t\t}}\n\t\t\t\t{...props}\n\t\t\t\tref={wrapperRef}\n\t\t\t/>\n\t\t);\n\t},\n);\n","import type {\n\tLyricLine,\n\tLyricLineMouseEvent,\n\tLyricPlayerBase,\n\tOptimizeLyricOptions,\n\tspring,\n} from \"@applemusic-like-lyrics/core\";\nimport {\n\tLyricPlayer as DefaultLyricPlayer,\n\tLayoutReason,\n\tMaskObsceneWordsMode,\n} from \"@applemusic-like-lyrics/core\";\nimport {\n\ttype ForwardRefExoticComponent,\n\tforwardRef,\n\ttype HTMLProps,\n\ttype RefAttributes,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\n/**\n * 歌词播放组件的属性\n */\nexport interface LyricPlayerProps {\n\t/**\n\t * 是否禁用歌词播放组件,默认为 `false`,歌词组件启用后将会开始逐帧更新歌词的动画效果,并对传入的其他参数变更做出反馈。\n\t *\n\t * 如果禁用了歌词组件动画,你也可以通过引用取得原始渲染组件实例,手动逐帧调用其 `update` 函数来更新动画效果。\n\t */\n\tdisabled?: boolean;\n\t/**\n\t * 是否演出部分效果,目前会控制播放间奏点的动画的播放暂停与否,默认为 `true`\n\t */\n\tplaying?: boolean;\n\t/**\n\t * 设置歌词行的对齐方式,如果为 `undefined` 则默认为 `center`\n\t *\n\t * - 设置成 `top` 的话将会向目标歌词行的顶部对齐\n\t * - 设置成 `bottom` 的话将会向目标歌词行的底部对齐\n\t * - 设置成 `center` 的话将会向目标歌词行的垂直中心对齐\n\t */\n\talignAnchor?: \"top\" | \"bottom\" | \"center\";\n\t/**\n\t * 设置默认的歌词行对齐位置,相对于整个歌词播放组件的大小位置,如果为 `undefined`\n\t * 则默认为 `0.5`\n\t *\n\t * 可以设置一个 `[0.0-1.0]` 之间的任意数字,代表组件高度由上到下的比例位置\n\t */\n\talignPosition?: number;\n\t/**\n\t * 设置是否使用物理弹簧算法实现歌词动画效果,默认启用\n\t *\n\t * 如果启用,则会通过弹簧算法实时处理歌词位置,但是需要性能足够强劲的电脑方可流畅运行\n\t *\n\t * 如果不启用,则会回退到基于 `transition` 的过渡效果,对低性能的机器比较友好,但是效果会比较单一\n\t */\n\tenableSpring?: boolean;\n\t/**\n\t * 设置是否启用歌词行的模糊效果,默认为 `true`\n\t */\n\tenableBlur?: boolean;\n\t/**\n\t * 设置是否使用物理弹簧算法实现歌词动画效果,默认启用\n\t *\n\t * 如果启用,则会通过弹簧算法实时处理歌词位置,但是需要性能足够强劲的电脑方可流畅运行\n\t *\n\t * 如果不启用,则会回退到基于 `transition` 的过渡效果,对低性能的机器比较友好,但是效果会比较单一\n\t */\n\tenableScale?: boolean;\n\t/**\n\t * 设置是否隐藏已经播放过的歌词行,默认不隐藏\n\t */\n\thidePassedLines?: boolean;\n\t/**\n\t * 设置歌词中不雅用语的掩码模式,默认为 `MaskObsceneWordsMode.Disabled`,即不掩码\n\t */\n\tmaskObsceneWordsMode?: MaskObsceneWordsMode;\n\t/**\n\t * 设置不雅用语掩码使用的字符,默认为 `*`\n\t */\n\tmaskObsceneWordChar?: string;\n\t/**\n\t * 设置歌词优化选项\n\t */\n\toptimizeOptions?: OptimizeLyricOptions;\n\t/**\n\t * 设置当前播放歌词,要注意传入后这个数组内的信息不得修改,否则会发生错误\n\t */\n\tlyricLines?: LyricLine[];\n\t/**\n\t * 设置当前播放进度,单位为毫秒且**必须是整数**,此时将会更新内部的歌词进度信息\n\t * 内部会根据调用间隔和播放进度自动决定如何滚动和显示歌词,所以这个的调用频率越快越准确越好\n\t */\n\tcurrentTime?: number;\n\t/**\n\t * 标识本次 {@link currentTime} 变化是否由跳转触发,将强制触发一次重新排版\n\t *\n\t * 此属性只标注 {@link currentTime} 的变化,本身不会触发推送,\n\t * 因此 {@link currentTime} 未变化时改动它不产生任何效果\n\t *\n\t * @see https://amll.dev/guides/component/seeking\n\t */\n\tisSeeking?: boolean;\n\t/**\n\t * 设置文字动画的渐变宽度,单位以歌词行的主文字字体大小的倍数为单位,默认为 0.5,即一个全角字符的一半宽度\n\t *\n\t * 如果要模拟 Apple Music for Android 的效果,可以设置为 1\n\t *\n\t * 如果要模拟 Apple Music for iPad 的效果,可以设置为 0.5\n\t *\n\t * 如果想要近乎禁用渐变效果,可以设置成非常接近 0 的小数(例如 `0.0001` ),但是**不可以为 0**\n\t */\n\twordFadeWidth?: number;\n\t/**\n\t * 设置所有歌词行在横坐标上的弹簧属性,包括重量、弹力和阻力。\n\t *\n\t * @param params 需要设置的弹簧属性,提供的属性将会覆盖原来的属性,未提供的属性将会保持原样\n\t */\n\tlinePosXSpringParams?: Partial<spring.SpringParams>;\n\t/**\n\t * 设置所有歌词行在​纵坐标上的弹簧属性,包括重量、弹力和阻力。\n\t *\n\t * @param params 需要设置的弹簧属性,提供的属性将会覆盖原来的属性,未提供的属性将会保持原样\n\t */\n\tlinePosYSpringParams?: Partial<spring.SpringParams>;\n\t/**\n\t * 设置所有歌词行在​缩放大小上的弹簧属性,包括重量、弹力和阻力。\n\t *\n\t * @param params 需要设置的弹簧属性,提供的属性将会覆盖原来的属性,未提供的属性将会保持原样\n\t */\n\tlineScaleSpringParams?: Partial<spring.SpringParams>;\n\t/**\n\t * 在一个特殊的底栏元素内加入指定元素,默认是空白的,可以往内部添加任意元素\n\t *\n\t * 这个元素始终在歌词的底部,可以用于显示歌曲创作者等信息\n\t */\n\tbottomLine?: Parameters<typeof createPortal>[0];\n\t/**\n\t * 需要用于创建歌词播放组件的类实例\n\t */\n\tlyricPlayer?: {\n\t\tnew (\n\t\t\t...args: ConstructorParameters<typeof LyricPlayerBase>\n\t\t): LyricPlayerBase;\n\t};\n\t/**\n\t * 当某个歌词行被左键点击时触发的事件\n\t * @param line 歌词行的事件对象,可以访问到对应的歌词行信息和歌词行索引\n\t */\n\tonLyricLineClick?: (line: LyricLineMouseEvent) => void;\n\t/**\n\t * 当某个歌词行被右键点击时触发的事件\n\t * @param line 歌词行的事件对象,可以访问到对应的歌词行信息和歌词行索引\n\t */\n\tonLyricLineContextMenu?: (line: LyricLineMouseEvent) => void;\n}\n\n/**\n * 歌词播放组件的引用\n */\nexport interface LyricPlayerRef {\n\t/**\n\t * 歌词播放实例\n\t */\n\tlyricPlayer?: LyricPlayerBase;\n\t/**\n\t * 将歌词播放实例的元素包裹起来的 DIV 元素实例\n\t */\n\twrapperEl: HTMLDivElement | null;\n}\n\n/**\n * 歌词播放组件,本框架的核心组件\n *\n * 尽可能贴切 Apple Music for iPad 的歌词效果设计,且做了力所能及的优化措施\n */\nexport const LyricPlayer: ForwardRefExoticComponent<\n\tOmit<HTMLProps<HTMLDivElement> & LyricPlayerProps, \"ref\"> &\n\t\tRefAttributes<LyricPlayerRef>\n> = forwardRef<LyricPlayerRef, HTMLProps<HTMLDivElement> & LyricPlayerProps>(\n\t(\n\t\t{\n\t\t\tdisabled,\n\t\t\tplaying,\n\t\t\talignAnchor,\n\t\t\talignPosition,\n\t\t\tenableSpring,\n\t\t\tenableBlur,\n\t\t\tenableScale,\n\t\t\tmaskObsceneWordsMode,\n\t\t\tmaskObsceneWordChar,\n\t\t\thidePassedLines,\n\t\t\toptimizeOptions,\n\t\t\tlyricLines,\n\t\t\tcurrentTime,\n\t\t\tisSeeking,\n\t\t\twordFadeWidth,\n\t\t\tlinePosXSpringParams,\n\t\t\tlinePosYSpringParams,\n\t\t\tlineScaleSpringParams,\n\t\t\tbottomLine,\n\t\t\tlyricPlayer,\n\t\t\tonLyricLineClick,\n\t\t\tonLyricLineContextMenu,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\t// const corePlayerRef = useRef<LyricPlayerBase>();\n\t\tconst [corePlayer, setCorePlayer] = useState<LyricPlayerBase>();\n\t\tconst wrapperRef = useRef<HTMLDivElement>(null);\n\t\tconst currentTimeRef = useRef(currentTime);\n\t\tconst prevLyricLinesRef = useRef(lyricLines);\n\n\t\tuseLayoutEffect(() => {\n\t\t\tconst newPlayer = new (lyricPlayer ?? DefaultLyricPlayer)();\n\t\t\tsetCorePlayer(newPlayer);\n\t\t\twrapperRef.current?.appendChild(newPlayer.getElement());\n\t\t\treturn () => {\n\t\t\t\tnewPlayer?.dispose();\n\t\t\t\tsetCorePlayer(undefined);\n\t\t\t};\n\t\t}, [lyricPlayer]);\n\n\t\tuseLayoutEffect(() => {\n\t\t\tif (!corePlayer) return;\n\n\t\t\tcorePlayer.setLyricProcessConfig({\n\t\t\t\toptimizeOptions,\n\t\t\t\tmaskMode: maskObsceneWordsMode ?? MaskObsceneWordsMode.Disabled,\n\t\t\t\tmaskChar: maskObsceneWordChar ?? \"*\",\n\t\t\t});\n\n\t\t\tconst lyricLinesChanged = prevLyricLinesRef.current !== lyricLines;\n\t\t\tprevLyricLinesRef.current = lyricLines;\n\n\t\t\tif (lyricLinesChanged || corePlayer.getLyricLines().length === 0) {\n\t\t\t\tif (lyricLines !== undefined) {\n\t\t\t\t\tcorePlayer.setLyricLines(lyricLines, currentTimeRef.current);\n\t\t\t\t\tcorePlayer.update();\n\t\t\t\t} else {\n\t\t\t\t\tcorePlayer.setLyricLines([]);\n\t\t\t\t\tcorePlayer.update();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcorePlayer.rebuildLyricView(currentTimeRef.current);\n\t\t\t}\n\t\t}, [\n\t\t\tcorePlayer,\n\t\t\tlyricLines,\n\t\t\toptimizeOptions,\n\t\t\tmaskObsceneWordsMode,\n\t\t\tmaskObsceneWordChar,\n\t\t]);\n\n\t\tuseEffect(() => {\n\t\t\tif (!disabled) {\n\t\t\t\tlet canceled = false;\n\t\t\t\tlet lastTime = -1;\n\t\t\t\tconst onFrame = (time: number) => {\n\t\t\t\t\tif (canceled) return;\n\t\t\t\t\tif (lastTime === -1) {\n\t\t\t\t\t\tlastTime = time;\n\t\t\t\t\t}\n\t\t\t\t\tcorePlayer?.update(time - lastTime);\n\t\t\t\t\tlastTime = time;\n\t\t\t\t\trequestAnimationFrame(onFrame);\n\t\t\t\t};\n\t\t\t\tcorePlayer?.calcLayout(LayoutReason.ConfigChange);\n\t\t\t\trequestAnimationFrame(onFrame);\n\t\t\t\treturn () => {\n\t\t\t\t\tcanceled = true;\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn;\n\t\t}, [corePlayer, disabled]);\n\n\t\tuseEffect(() => {\n\t\t\tif (playing !== undefined) {\n\t\t\t\tif (playing) {\n\t\t\t\t\tcorePlayer?.resume();\n\t\t\t\t} else {\n\t\t\t\t\tcorePlayer?.pause();\n\t\t\t\t}\n\t\t\t} else corePlayer?.resume();\n\t\t}, [corePlayer, playing]);\n\n\t\tuseEffect(() => {\n\t\t\tif (alignAnchor !== undefined) corePlayer?.setAlignAnchor(alignAnchor);\n\t\t}, [corePlayer, alignAnchor]);\n\n\t\tuseEffect(() => {\n\t\t\tif (hidePassedLines !== undefined)\n\t\t\t\tcorePlayer?.setHidePassedLines(hidePassedLines);\n\t\t}, [corePlayer, hidePassedLines]);\n\n\t\tuseEffect(() => {\n\t\t\tif (alignPosition !== undefined)\n\t\t\t\tcorePlayer?.setAlignPosition(alignPosition);\n\t\t}, [corePlayer, alignPosition]);\n\n\t\tuseEffect(() => {\n\t\t\tif (enableSpring !== undefined) corePlayer?.setEnableSpring(enableSpring);\n\t\t\telse corePlayer?.setEnableSpring(true);\n\t\t}, [corePlayer, enableSpring]);\n\n\t\tuseEffect(() => {\n\t\t\tif (enableScale !== undefined) corePlayer?.setEnableScale(enableScale);\n\t\t\telse corePlayer?.setEnableScale(true);\n\t\t}, [corePlayer, enableScale]);\n\n\t\tuseEffect(() => {\n\t\t\tcorePlayer?.setEnableBlur(enableBlur ?? true);\n\t\t}, [corePlayer, enableBlur]);\n\n\t\t// isSeeking 只标注本次 currentTime 推送是否为跳转,不作为推送的触发源\n\t\t//\n\t\t// currentTime 未变而 isSeeking 变化若重跑此 Effect,只会把同一个时间再推送一次,\n\t\t// 除了多走一次同步流程之外没有任何效果,因此不值得作为依赖参与重跑\n\t\t// biome-ignore lint/correctness/useExhaustiveDependencies: isSeeking 不作为触发源\n\t\tuseLayoutEffect(() => {\n\t\t\tif (currentTime !== undefined) {\n\t\t\t\tcorePlayer?.setCurrentTime(currentTime, isSeeking);\n\t\t\t\tcurrentTimeRef.current = currentTime;\n\t\t\t} else {\n\t\t\t\tcorePlayer?.setCurrentTime(0);\n\t\t\t\tcurrentTimeRef.current = 0;\n\t\t\t}\n\t\t}, [corePlayer, currentTime]);\n\n\t\tuseEffect(() => {\n\t\t\tcorePlayer?.setWordFadeWidth(wordFadeWidth);\n\t\t}, [corePlayer, wordFadeWidth]);\n\n\t\tuseEffect(() => {\n\t\t\tif (linePosXSpringParams !== undefined)\n\t\t\t\tcorePlayer?.setLinePosXSpringParams(linePosXSpringParams);\n\t\t}, [corePlayer, linePosXSpringParams]);\n\n\t\tuseEffect(() => {\n\t\t\tif (linePosYSpringParams !== undefined)\n\t\t\t\tcorePlayer?.setLinePosYSpringParams(linePosYSpringParams);\n\t\t}, [corePlayer, linePosYSpringParams]);\n\n\t\tuseEffect(() => {\n\t\t\tif (lineScaleSpringParams !== undefined)\n\t\t\t\tcorePlayer?.setLineScaleSpringParams(lineScaleSpringParams);\n\t\t}, [corePlayer, lineScaleSpringParams]);\n\n\t\tuseEffect(() => {\n\t\t\tif (onLyricLineClick) {\n\t\t\t\tconst handler = (e: Event) =>\n\t\t\t\t\tonLyricLineClick(e as LyricLineMouseEvent);\n\t\t\t\tcorePlayer?.addEventListener(\"line-click\", handler);\n\t\t\t\treturn () => corePlayer?.removeEventListener(\"line-click\", handler);\n\t\t\t}\n\t\t\treturn;\n\t\t}, [corePlayer, onLyricLineClick]);\n\n\t\tuseEffect(() => {\n\t\t\tif (onLyricLineContextMenu) {\n\t\t\t\tconst handler = (e: Event) =>\n\t\t\t\t\tonLyricLineContextMenu(e as LyricLineMouseEvent);\n\t\t\t\tcorePlayer?.addEventListener(\"line-contextmenu\", handler);\n\t\t\t\treturn () =>\n\t\t\t\t\tcorePlayer?.removeEventListener(\"line-contextmenu\", handler);\n\t\t\t}\n\t\t\treturn;\n\t\t}, [corePlayer, onLyricLineContextMenu]);\n\n\t\tuseImperativeHandle(\n\t\t\tref,\n\t\t\t() => ({\n\t\t\t\twrapperEl: wrapperRef.current,\n\t\t\t\tlyricPlayer: corePlayer,\n\t\t\t}),\n\t\t\t[corePlayer],\n\t\t);\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<div {...props} ref={wrapperRef} />\n\t\t\t\t{corePlayer?.getBottomLineElement() && bottomLine\n\t\t\t\t\t? createPortal(bottomLine, corePlayer?.getBottomLineElement())\n\t\t\t\t\t: null}\n\t\t\t</>\n\t\t);\n\t},\n);\n"],"mappings":"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"}