@applemusic-like-lyrics/core 0.1.1 → 0.1.3

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.
@@ -0,0 +1,2284 @@
1
+ var Ie = Object.defineProperty;
2
+ var de = (o, i, e) => i in o ? Ie(o, i, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[i] = e;
3
+ var a = (o, i, e) => (de(o, typeof i != "symbol" ? i + "" : i, e), e);
4
+ import { Container as me } from "@pixi/display";
5
+ import { Application as fe } from "@pixi/app";
6
+ import { BlurFilter as R } from "@pixi/filter-blur";
7
+ import { ColorMatrixFilter as X } from "@pixi/filter-color-matrix";
8
+ import { Texture as ue } from "@pixi/core";
9
+ import { Sprite as N } from "@pixi/sprite";
10
+ import { BulgePinchFilter as G } from "@pixi/filter-bulge-pinch";
11
+ import { create as pe } from "jss";
12
+ import ge from "jss-preset-default";
13
+ class ye {
14
+ }
15
+ class te extends ye {
16
+ constructor(e) {
17
+ super();
18
+ a(this, "observer");
19
+ a(this, "flowSpeed", 2);
20
+ a(this, "currerntRenderScale", 0.75);
21
+ this.canvas = e, this.observer = new ResizeObserver(() => {
22
+ const t = Math.max(
23
+ 1,
24
+ e.clientWidth * window.devicePixelRatio * this.currerntRenderScale
25
+ ), s = Math.max(
26
+ 1,
27
+ e.clientHeight * window.devicePixelRatio * this.currerntRenderScale
28
+ );
29
+ this.onResize(t, s);
30
+ }), this.observer.observe(e);
31
+ }
32
+ setRenderScale(e) {
33
+ this.currerntRenderScale = e, this.onResize(
34
+ this.canvas.clientWidth * window.devicePixelRatio * this.currerntRenderScale,
35
+ this.canvas.clientHeight * window.devicePixelRatio * this.currerntRenderScale
36
+ );
37
+ }
38
+ /**
39
+ * 当画板元素大小发生变化时此函数会被调用
40
+ * 可以在此处重设和渲染器相关的尺寸设置
41
+ * 考虑到初始化的时候元素不一定在文档中或出于某些特殊样式状态,尺寸长宽有可能会为 0,请注意进行特判处理
42
+ * @param width 画板元素实际的物理像素宽度,有可能为 0
43
+ * @param height 画板元素实际的物理像素高度,有可能为 0
44
+ */
45
+ onResize(e, t) {
46
+ this.canvas.width = e, this.canvas.height = t;
47
+ }
48
+ /**
49
+ * 修改背景的流动速度,数字越大越快,默认为 2
50
+ * @param speed 背景的流动速度,默认为 2
51
+ */
52
+ setFlowSpeed(e) {
53
+ this.flowSpeed = e;
54
+ }
55
+ dispose() {
56
+ this.observer.disconnect(), this.canvas.remove();
57
+ }
58
+ }
59
+ function Te(o) {
60
+ return new Promise((i, e) => {
61
+ const t = document.createElement("img");
62
+ t.onload = () => i(t), t.onerror = e, t.src = o, t.crossOrigin = "anonymous", t.decode().then(() => i(t)).catch(e);
63
+ });
64
+ }
65
+ function Ee(o) {
66
+ return new Promise((i, e) => {
67
+ const t = document.createElement("video");
68
+ let s = !1, l = !1, r = !1;
69
+ t.addEventListener(
70
+ "playing",
71
+ () => {
72
+ s = !0, n();
73
+ },
74
+ !0
75
+ ), t.addEventListener(
76
+ "timeupdate",
77
+ () => {
78
+ l = !0, n();
79
+ },
80
+ !0
81
+ ), t.addEventListener(
82
+ "error",
83
+ (h) => {
84
+ r = !0, e(h);
85
+ },
86
+ !0
87
+ );
88
+ function n() {
89
+ s && l && !r && i(t);
90
+ }
91
+ t.src = o, t.playsInline = !0, t.crossOrigin = "anonymous", t.autoplay = !0, t.loop = !0, t.muted = !0, t.play();
92
+ });
93
+ }
94
+ function ie(o, i = !1) {
95
+ return i ? Ee(o) : Te(o);
96
+ }
97
+ function se(o) {
98
+ return new Promise((i, e) => {
99
+ (o instanceof HTMLImageElement ? o.complete : o.readyState >= 3) ? i(o) : (o.onload = () => i(o), o.onerror = e);
100
+ });
101
+ }
102
+ class we extends me {
103
+ constructor() {
104
+ super(...arguments);
105
+ a(this, "time", 0);
106
+ }
107
+ }
108
+ class pt extends te {
109
+ constructor(e) {
110
+ super(e);
111
+ a(this, "app");
112
+ a(this, "curContainer");
113
+ a(this, "staticMode", !1);
114
+ a(this, "lastContainer", /* @__PURE__ */ new Set());
115
+ a(this, "onTick", (e) => {
116
+ for (const t of this.lastContainer)
117
+ t.alpha = Math.max(0, t.alpha - e / 60), t.alpha <= 0 && (this.app.stage.removeChild(t), this.lastContainer.delete(t), t.destroy(!0));
118
+ if (this.curContainer) {
119
+ this.curContainer.alpha = Math.min(
120
+ 1,
121
+ this.curContainer.alpha + e / 60
122
+ );
123
+ const [t, s, l, r] = this.curContainer.children, n = Math.max(this.app.screen.width, this.app.screen.height);
124
+ t.position.set(this.app.screen.width / 2, this.app.screen.height / 2), s.position.set(
125
+ this.app.screen.width / 2.5,
126
+ this.app.screen.height / 2.5
127
+ ), l.position.set(this.app.screen.width / 2, this.app.screen.height / 2), r.position.set(this.app.screen.width / 2, this.app.screen.height / 2), t.width = n * Math.sqrt(2), t.height = t.width, s.width = n * 0.8, s.height = s.width, l.width = n * 0.5, l.height = l.width, r.width = n * 0.25, r.height = r.width, this.curContainer.time += e * this.flowSpeed, t.rotation += e / 1e3 * this.flowSpeed, s.rotation -= e / 500 * this.flowSpeed, l.rotation += e / 1e3 * this.flowSpeed, r.rotation -= e / 750 * this.flowSpeed, l.x = this.app.screen.width / 2 + this.app.screen.width / 4 * Math.cos(this.curContainer.time / 1e3 * 0.75), l.y = this.app.screen.height / 2 + this.app.screen.width / 4 * Math.cos(this.curContainer.time / 1e3 * 0.75), r.x = this.app.screen.width / 2 + this.app.screen.width / 4 * 0.1 + Math.cos(this.curContainer.time * 6e-3 * 0.75), r.y = this.app.screen.height / 2 + this.app.screen.width / 4 * 0.1 + Math.cos(this.curContainer.time * 6e-3 * 0.75), this.curContainer.alpha >= 1 && this.lastContainer.size === 0 && this.staticMode && this.app.ticker.stop();
128
+ }
129
+ });
130
+ this.canvas = e, this.app = new fe({
131
+ view: e,
132
+ resizeTo: this.canvas,
133
+ powerPreference: "low-power",
134
+ backgroundAlpha: 1
135
+ }), this.rebuildFilters(), this.app.ticker.maxFPS = 30, this.app.ticker.add(this.onTick), this.app.ticker.start();
136
+ }
137
+ onResize(e, t) {
138
+ super.onResize(e, t), this.app.resize(), this.rebuildFilters();
139
+ }
140
+ setRenderScale(e) {
141
+ super.setRenderScale(e), this.rebuildFilters();
142
+ }
143
+ rebuildFilters() {
144
+ var n;
145
+ const e = Math.min(this.canvas.width, this.canvas.height), t = Math.max(this.canvas.width, this.canvas.height), s = new X();
146
+ s.saturate(1.2, !1);
147
+ const l = new X();
148
+ l.brightness(0.6, !1);
149
+ const r = new X();
150
+ r.contrast(0.3, !0), (n = this.app.stage.filters) == null || n.forEach((h) => {
151
+ h.destroy();
152
+ }), this.app.stage.filters = [], this.app.stage.filters.push(new R(5, 1)), this.app.stage.filters.push(new R(10, 1)), this.app.stage.filters.push(new R(20, 2)), this.app.stage.filters.push(new R(40, 2)), this.app.stage.filters.push(new R(80, 2)), e > 768 && this.app.stage.filters.push(new R(160, 4)), e > 768 * 2 && this.app.stage.filters.push(new R(320, 4)), this.app.stage.filters.push(s, l, r), this.app.stage.filters.push(new R(5, 1)), Math.random() > 0.5 ? (this.app.stage.filters.push(
153
+ new G({
154
+ radius: (t + e) / 2,
155
+ strength: 1,
156
+ center: [0.25, 1]
157
+ })
158
+ ), this.app.stage.filters.push(
159
+ new G({
160
+ radius: (t + e) / 2,
161
+ strength: 1,
162
+ center: [0.75, 0]
163
+ })
164
+ )) : (this.app.stage.filters.push(
165
+ new G({
166
+ radius: (t + e) / 2,
167
+ strength: 1,
168
+ center: [0.75, 1]
169
+ })
170
+ ), this.app.stage.filters.push(
171
+ new G({
172
+ radius: (t + e) / 2,
173
+ strength: 1,
174
+ center: [0.25, 0]
175
+ })
176
+ ));
177
+ }
178
+ setStaticMode(e = !1) {
179
+ this.staticMode = e, this.app.ticker.start();
180
+ }
181
+ setFPS(e) {
182
+ this.app.ticker.maxFPS = e;
183
+ }
184
+ pause() {
185
+ this.app.ticker.stop(), this.app.render();
186
+ }
187
+ resume() {
188
+ this.app.ticker.start();
189
+ }
190
+ setLowFreqVolume(e) {
191
+ }
192
+ setHasLyric(e) {
193
+ }
194
+ async setAlbum(e, t) {
195
+ var m, f;
196
+ if (typeof e == "string" && e.trim().length === 0)
197
+ return;
198
+ let s = null, l = 5, r = null;
199
+ for (; !((f = (m = r == null ? void 0 : r.baseTexture) == null ? void 0 : m.resource) != null && f.valid) && l > 0; )
200
+ try {
201
+ typeof e == "string" ? s = await ie(e, t) : s = await se(e), r = ue.from(s, {
202
+ resourceOptions: {
203
+ autoLoad: !1
204
+ }
205
+ }), await r.baseTexture.resource.load();
206
+ } catch (p) {
207
+ console.warn(
208
+ `failed on loading album image, retrying (${l})`,
209
+ e,
210
+ p
211
+ ), r = null, l--;
212
+ }
213
+ if (!r)
214
+ return;
215
+ const n = new we(), h = new N(r), c = new N(r), I = new N(r), d = new N(r);
216
+ h.anchor.set(0.5, 0.5), c.anchor.set(0.5, 0.5), I.anchor.set(0.5, 0.5), d.anchor.set(0.5, 0.5), h.rotation = Math.random() * Math.PI * 2, c.rotation = Math.random() * Math.PI * 2, I.rotation = Math.random() * Math.PI * 2, d.rotation = Math.random() * Math.PI * 2, n.addChild(h, c, I, d), this.curContainer && this.lastContainer.add(this.curContainer), this.curContainer = n, this.app.stage.addChild(n), this.curContainer.alpha = 0, this.app.ticker.start();
217
+ }
218
+ dispose() {
219
+ super.dispose(), this.app.ticker.remove(this.onTick), this.app.destroy(!0);
220
+ }
221
+ getElement() {
222
+ return this.canvas;
223
+ }
224
+ }
225
+ const Y = `#version 300 es
226
+ precision highp float;
227
+
228
+ in vec2 v_coord;
229
+ out vec2 f_v_coord;
230
+
231
+ void main() {
232
+ gl_Position = vec4(v_coord, 0.0f, 1.0f);
233
+ f_v_coord = (vec2(v_coord.x, v_coord.y) + vec2(1.0f, 1.0f)) / 2.0f;
234
+ }
235
+ `, be = `#version 300 es
236
+ precision highp float;
237
+
238
+ uniform sampler2D src;
239
+ in vec2 f_v_coord;
240
+ out vec4 fragColor;
241
+
242
+ void main() {
243
+ vec2 coord = f_v_coord;
244
+ fragColor = texture(src, coord);
245
+ }
246
+ `, Se = `#version 300 es
247
+ precision highp float;
248
+
249
+ uniform sampler2D src;
250
+ uniform float lerp;
251
+ uniform float scale;
252
+ in vec2 f_v_coord;
253
+ out vec4 fragColor;
254
+
255
+ void main() {
256
+ vec2 tex_coord = f_v_coord;
257
+ if(scale < 1.0f) {
258
+ tex_coord /= scale;
259
+ }
260
+ vec4 srcColor = texture(src, tex_coord);
261
+ fragColor = mix(vec4(srcColor.xyz, 0.0f), srcColor, lerp);
262
+ }
263
+ `, Le = `#version 300 es
264
+ precision highp float;uniform float IIIlllllllIIIllIl,lIIIlllllIllIl,IIIlllIlIIllll;uniform sampler2D IlllIIlIlllIll;uniform vec2 IIlIlIIlIlIllI,IllIlllIlIIlllI;out vec4 lIIlIIIIIlIlIlllIIIIlIIl;float lIlIIllllIllIll(float IIIlIIlIIIlllIII){IIIlIIlIIIlllIII-=0.;return sin(IIIlIIlIIIlllIII);}float lIlIlllllIllIll(float IIIlIIlIIIlllIII){IIIlIIlIIIlllIII+=acos(0.);return sin(IIIlIIlIIIlllIII);}mat2 lIIllIIlIIIllIl(float IIIlIIlIIIlllIII){return mat2(lIlIlllllIllIll(IIIlIIlIIIlllIII),-lIlIIllllIllIll(IIIlIIlIIIlllIII),lIlIIllllIllIll(IIIlIIlIIIlllIII),lIlIlllllIllIll(IIIlIIlIIIlllIII));}mat2 lIIllIIlIIIlllI(float IIIlIIlIIIlllIII){return mat2(lIlIIllllIllIll(IIIlIIlIIIlllIII),-lIlIlllllIllIll(IIIlIIlIIIlllIII),lIlIlllllIllIll(IIIlIIlIIIlllIII),lIlIIllllIllIll(IIIlIIlIIIlllIII));}float IllllIIlIllII(float llIIllIllIIIllI){return fract(lIlIIllllIllIll(llIIllIllIIIllI)*43758.5453);}float llIlIIllllIII(vec2 IIIlIIlIIIlllIII){vec2 IIllIlIIlllI=floor(IIIlIIlIIIlllIII),lIlIllIIIIIlIl=fract(IIIlIIlIIIlllIII);lIlIllIIIIIlIl=lIlIllIIIIIlIl*lIlIllIIIIIlIl*(3.-2.*lIlIllIIIIIlIl);float lIlIlIlIlIlIIl=IIllIlIIlllI.x+IIllIlIIlllI.y*57.;return mix(mix(IllllIIlIllII(lIlIlIlIlIlIIl),IllllIIlIllII(lIlIlIlIlIlIIl+1.),lIlIllIIIIIlIl.x),mix(IllllIIlIllII(lIlIlIlIlIlIIl+57.),IllllIIlIllII(lIlIlIlIlIlIIl+58.),lIlIllIIIIIlIl.x),lIlIllIIIIIlIl.y);}vec2 lllIIIIIIllIlIIIlI(vec2 IlllIIlIIIIlIIII,float lIIIIlllIIIIllIlIlI,vec2 IlIlIIIIlIlllIlIII){float lIIlIllIIIlIl=llIlIIllllIII(IlllIIlIIIIlIIII*vec2(1)*3.5+.1)*4.2831*mix(.2,1.,IIIlllllllIIIllIl);IlllIIlIIIIlIIII+=vec2(-1,.5);lIIlIllIIIlIl-=lIIIIlllIIIIllIlIlI;return vec2(lIlIlllllIllIll(lIIlIllIIIlIl),lIlIIllllIllIll(lIIlIllIIIlIl));}const mat3 lIIllIIIlllIl=mat3(1.,.02,.002,.02,1.,.008,.002,.02,1.),lIIIlllIIIIll=mat3(1.022,-.02,-.002,-.02,1.028,-.008,-.002,-.02,1.022);void main(){vec2 lIIIlIIllIlIIlI=lIlIIllllIllIll(lIIIlllllIllIl*.2)*.01+.5+gl_FragCoord.xy/IIlIlIIlIlIllI.xy,lIIllIIlIIIllI=lIIIlIIllIlIIlI*.77f+IllIlllIlIIlllI;lIIllIIlIIIllI.x*=IIlIlIIlIlIllI.x/IIlIlIIlIlIllI.y;float lIIlIIlIIlIIIlII=gl_FragCoord.x/max(IIlIlIIlIlIllI.x,IIlIlIIlIlIllI.y),lIIIlIllIllIlIIl=0.f;vec3 lIIIlIlIIIlIlIIl=vec3(0);vec2 lIlIIlIlIIIllIll=lIIllIIlIIIllI;for(int IllIlIIlIIlllllIIIl=0;IllIlIIlIIlllllIIIl<8;IllIlIIlIIlllllIIIl++){bool lIlIlIIllIllIIll=IllIlIIlIIlllllIIIl%2==0;vec2 lIlllIlllIlllII=lllIIIIIIllIlIIIlI(lIIllIIlIIIllI,lIIlIIlIIlIIIlII,lIIIlIIllIlIIlI),lIllIIlIIlIIIll=lIlllIlllIlllII;float lIIlIlIIlIIlIllI=float(IllIlIIlIIlllllIIIl)/8.f;vec3 llIIlIIIIlIIlIII=texture(IlllIIlIlllIll,-lIIIlllllIllIl*.01+.8*lIIllIIlIIIllI*lIIllIIlIIIllIl(-lIIIlllllIllIl*.2)+vec2(IIIlllIlIIllll*.3*(float(lIlIlIIllIllIIll)*2.-1.)*lIIllIIlIIIlllI(lIIIlllllIllIl*.2+1.5))).xyz;lIIIlIlIIIlIlIIl+=llIIlIIIIlIIlIII;lIIIlIllIllIlIIl+=4.f*lIIlIlIIlIIlIllI*(1.f-lIIlIlIIlIIlIllI);lIIllIIlIIIllI+=.01f*lIllIIlIIlIIIll*(lIlIIllllIllIll(lIIIlllllIllIl)*4.8+.8);lIlIIlIlIIIllIll+=.05f*lIllIIlIIlIIIll;}lIIIlIlIIIlIlIIl/=lIIIlIllIllIlIIl;lIIIlIlIIIlIlIIl*=1.6f;lIIIlIlIIIlIlIIl=1.f-exp(-lIIIlIlIIIlIlIIl);lIIIlIlIIIlIlIIl=pow(lIIIlIlIIIlIlIIl,vec3(2.2));lIIIlIlIIIlIlIIl*=.8f;lIIlIIIIIlIlIlllIIIIlIIl=vec4(lIIIlIlIIIlIlIIl,1);}`, xe = `#version 300 es
265
+ precision highp float;
266
+
267
+ uniform sampler2D src;
268
+ in vec2 f_v_coord;
269
+ out vec4 fragColor;
270
+
271
+ /* Gradient noise from Jorge Jimenez's presentation: */
272
+ /* http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare */
273
+ float gradientNoise(in vec2 uv) {
274
+ return fract(52.9829189f * fract(dot(uv, vec2(0.06711056f, 0.00583715f))));
275
+ }
276
+
277
+ void main() {
278
+ vec2 tex_coord = f_v_coord;
279
+ float dither = (1.0f / 255.0f) * gradientNoise(gl_FragCoord.xy) - (0.5f / 255.0f);
280
+ vec4 color = texture(src, tex_coord);
281
+ color += dither;
282
+ fragColor = color;
283
+ }
284
+ `, Pe = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAYUklEQVR4nH3bV89VVRcF4IX7qNgVe8WKvaIiNsCuYCKCSEg0JCYm/gTjzf4R3njhlRdeWKKi2AvYEBV7b1ixY2+ofPuZcbwxXzie5OQ9Z5+11pxzjDHnKnu/k0477bSN+++/fzvyyCPbdttt17766qu2YcOG9ttvv7U33nijffHFF23atGntgAMOaN98803bc88926RJk9pnn31W10855ZT2888/1/vrr79ur732Wjv00EPbgQce2NavX99eeOGF+nvmmWfWuD4fc8wx1ffDDz9sTz31VPv000/bRx99VL/vsssu7eCDDy57hxxySPv222/L1saNG9vatWsbX19++eXyhb9//PFH23HHHdsHH3zQLrrooorjxRdfrPbG+/jjj9u6devaX3/91aZMmdImT57cdt1114lYu5133rnfeuut28yZM9t+++3XVq9e3T7//PMa9Ljjjqu/m222WTn73HPPtR122KF99913bcsttyyQnnzyybbbbrvVm4MMAe37778vUATIkaOPPrqCe+KJJ9qPP/7Ydt9993bvvfe2lStXtvfee69ttdVW7bzzzmvbbLNN++STT9rUqVPL7jvvvNP+/PPP8o1NNn7//fcakx3XL7300moPyC222KL8ev/99ws8Y2s3xFmAIpD9H374of36669txBEIvf3224UmR1w74YQTyhlgHHTQQeU845Bfs2ZN23fffcsQRn/55Zf6jQJOP/30GvjLL78sMPbee+8y6rM2gvPea6+9yg7Htt1223bSSSe1nXbaqWwC+K677iq2qMU1yqKK0WhUAWGREruuq3GBw8dVq1ZV4Pvss08744wzSgns/fTTT+UzoigIAL53gyM95P7+++9Cj1OQz+ACwb7PHAGA3133phKyY/TVV1+t3zHEAUa8t99++1IDJwAsKFIWkFQQOFaeffbZ9u6775aTgBXskKIVhDEBSxFJCaznOoCpNdJHGlvGNRa5s8N3PiLg5JNPbt1goNfIYKeeemo74ogjKmC5yxlIY/D5559v999/f8nxrLPOqsCBwknIkxcmpISXYFesWFGqIlNKck3bGTNmFNDyltPaUBXnsMWGfKZCeQto/QQqmOnTpxegvvNVH4G7Jg4AG4P8qVM6jCN5JDc5QYZyHHrynFGd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", Z = (() => {
285
+ const o = document.createElement("img");
286
+ return o.src = Pe, o;
287
+ })();
288
+ function Ae(o, i, e) {
289
+ const t = o.data, s = o.width, l = o.height;
290
+ let r, n, h, c, I, d, m, f, p, y, u, g, E;
291
+ const L = s - 1, w = l - 1, T = i + 1, b = i + T, S = i + 1, M = i + S, x = 1 / (b * M), P = [], A = [], v = [], z = [], O = [], _ = [];
292
+ for (; e-- > 0; ) {
293
+ for (E = g = 0, d = 0; d < l; d++) {
294
+ for (r = t[E] * T, n = t[E + 1] * T, h = t[E + 2] * T, c = t[E + 3] * T, m = 1; m <= i; m++)
295
+ f = E + ((m > L ? L : m) << 2), r += t[f++], n += t[f++], h += t[f++], c += t[f];
296
+ for (I = 0; I < s; I++)
297
+ P[g] = r, A[g] = n, v[g] = h, z[g] = c, d === 0 && (O[I] = Math.min(I + T, L) << 2, _[I] = Math.max(I - i, 0) << 2), p = E + O[I], y = E + _[I], r += t[p++] - t[y++], n += t[p++] - t[y++], h += t[p++] - t[y++], c += t[p] - t[y], g++;
298
+ E += s << 2;
299
+ }
300
+ for (I = 0; I < s; I++) {
301
+ for (u = I, r = P[u] * S, n = A[u] * S, h = v[u] * S, c = z[u] * S, m = 1; m <= i; m++)
302
+ u += m > w ? 0 : s, r += P[u], n += A[u], h += v[u], c += z[u];
303
+ for (g = I << 2, d = 0; d < l; d++)
304
+ t[g] = r * x + 0.5 | 0, t[g + 1] = n * x + 0.5 | 0, t[g + 2] = h * x + 0.5 | 0, t[g + 3] = c * x + 0.5 | 0, I === 0 && (O[d] = Math.min(d + S, w) * s, _[d] = Math.max(d - i, 0) * s), p = I + O[d], y = I + _[d], r += P[p] - P[y], n += A[p] - A[y], h += v[p] - v[y], c += z[p] - z[y], g += s << 2;
305
+ }
306
+ }
307
+ }
308
+ function ve(o, i) {
309
+ const e = o.data;
310
+ for (let t = 0; t < e.length; t += 4) {
311
+ const s = e[t], l = e[t + 1], r = e[t + 2], n = e[t + 3], h = s * 0.3 + l * 0.59 + r * 0.11;
312
+ e[t] = h * (1 - i) + s * i, e[t + 1] = h * (1 - i) + l * i, e[t + 2] = h * (1 - i) + r * i, e[t + 3] = n;
313
+ }
314
+ }
315
+ function Me(o, i) {
316
+ const e = o.data;
317
+ for (let t = 0; t < e.length; t += 4) {
318
+ const s = e[t], l = e[t + 1], r = e[t + 2], n = e[t + 3];
319
+ e[t] = (s - 128) * i + 128, e[t + 1] = (l - 128) * i + 128, e[t + 2] = (r - 128) * i + 128, e[t + 3] = n;
320
+ }
321
+ }
322
+ class q {
323
+ constructor(i, e, t, s = "unknown") {
324
+ a(this, "gl");
325
+ a(this, "program");
326
+ a(this, "vertexShader");
327
+ a(this, "fragmentShader");
328
+ a(this, "coordPos");
329
+ a(this, "notFoundUniforms", /* @__PURE__ */ new Set());
330
+ this.label = s, this.gl = i, this.vertexShader = this.createShader(i.VERTEX_SHADER, e), this.fragmentShader = this.createShader(
331
+ i.FRAGMENT_SHADER,
332
+ t
333
+ ), this.program = this.createProgram();
334
+ const l = i.getAttribLocation(this.program, "v_coord");
335
+ if (l === -1)
336
+ throw new Error(
337
+ `Failed to get attribute location v_coord for "${this.label}"`
338
+ );
339
+ this.coordPos = l;
340
+ }
341
+ createShader(i, e) {
342
+ const t = this.gl, s = t.createShader(i);
343
+ if (!s)
344
+ throw new Error("Failed to create shader");
345
+ if (t.shaderSource(s, e), t.compileShader(s), !t.getShaderParameter(s, t.COMPILE_STATUS))
346
+ throw new Error(
347
+ `Failed to compile shader for type ${i} "${this.label}": ${t.getShaderInfoLog(s)}`
348
+ );
349
+ return s;
350
+ }
351
+ createProgram() {
352
+ const i = this.gl, e = i.createProgram();
353
+ if (!e)
354
+ throw new Error("Failed to create program");
355
+ if (i.attachShader(e, this.vertexShader), i.attachShader(e, this.fragmentShader), i.linkProgram(e), i.validateProgram(e), !i.getProgramParameter(e, i.LINK_STATUS)) {
356
+ const t = i.getProgramInfoLog(e);
357
+ throw i.deleteProgram(e), new Error(`Failed to link program "${this.label}": ${t}`);
358
+ }
359
+ return e;
360
+ }
361
+ use() {
362
+ const i = this.gl;
363
+ i.useProgram(this.program), i.vertexAttribPointer(this.coordPos, 2, i.FLOAT, !1, 0, 0), i.enableVertexAttribArray(this.coordPos);
364
+ }
365
+ warnUniformNotFound(i) {
366
+ this.notFoundUniforms.has(i) || (this.notFoundUniforms.add(i), console.warn(
367
+ `Failed to get uniform location for program "${this.label}": ${i}`
368
+ ));
369
+ }
370
+ setUniform1f(i, e) {
371
+ const t = this.gl, s = t.getUniformLocation(this.program, i);
372
+ s ? t.uniform1f(s, e) : this.warnUniformNotFound(i);
373
+ }
374
+ setUniform2f(i, e, t) {
375
+ const s = this.gl, l = s.getUniformLocation(this.program, i);
376
+ l ? s.uniform2f(l, e, t) : this.warnUniformNotFound(i);
377
+ }
378
+ setUniform1i(i, e) {
379
+ const t = this.gl, s = t.getUniformLocation(this.program, i);
380
+ s ? t.uniform1i(s, e) : this.warnUniformNotFound(i);
381
+ }
382
+ dispose() {
383
+ const i = this.gl;
384
+ i.deleteShader(this.vertexShader), i.deleteShader(this.fragmentShader), i.deleteProgram(this.program);
385
+ }
386
+ }
387
+ class Q {
388
+ constructor(i, e, t) {
389
+ a(this, "fb");
390
+ a(this, "tex");
391
+ a(this, "_size");
392
+ this.gl = i, this._size = [e, t];
393
+ const s = i.createFramebuffer();
394
+ if (!s)
395
+ throw new Error("Can't create framebuffer");
396
+ const l = i.createTexture();
397
+ if (!l)
398
+ throw new Error("Failed to create texture");
399
+ this.fb = s, this.tex = l, i.bindFramebuffer(i.FRAMEBUFFER, s), i.bindTexture(i.TEXTURE_2D, l), i.framebufferTexture2D(
400
+ i.FRAMEBUFFER,
401
+ i.COLOR_ATTACHMENT0,
402
+ i.TEXTURE_2D,
403
+ l,
404
+ 0
405
+ ), this.resize(e, t), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.MIRRORED_REPEAT), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.MIRRORED_REPEAT);
406
+ }
407
+ get size() {
408
+ return this._size;
409
+ }
410
+ resize(i, e) {
411
+ const t = this.gl;
412
+ this.bind(), t.bindTexture(t.TEXTURE_2D, this.tex), t.getExtension("EXT_color_buffer_float") ? t.texImage2D(
413
+ t.TEXTURE_2D,
414
+ 0,
415
+ t.RGBA32F,
416
+ i,
417
+ e,
418
+ 0,
419
+ t.RGBA,
420
+ t.FLOAT,
421
+ null
422
+ ) : t.texImage2D(
423
+ t.TEXTURE_2D,
424
+ 0,
425
+ t.RGBA,
426
+ i,
427
+ e,
428
+ 0,
429
+ t.RGBA,
430
+ t.UNSIGNED_BYTE,
431
+ null
432
+ ), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MIN_FILTER, t.LINEAR), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MAG_FILTER, t.LINEAR), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_S, t.MIRRORED_REPEAT), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_T, t.MIRRORED_REPEAT);
433
+ }
434
+ bind() {
435
+ const i = this.gl;
436
+ i.bindFramebuffer(i.FRAMEBUFFER, this.fb);
437
+ }
438
+ active(i = this.gl.TEXTURE0) {
439
+ this.gl.activeTexture(i), this.gl.bindTexture(this.gl.TEXTURE_2D, this.tex);
440
+ }
441
+ dispose() {
442
+ this.gl.deleteFramebuffer(this.fb), this.gl.deleteTexture(this.tex);
443
+ }
444
+ }
445
+ class j {
446
+ constructor(i, e, t, s) {
447
+ a(this, "gl");
448
+ a(this, "buffer");
449
+ a(this, "type");
450
+ a(this, "data");
451
+ a(this, "usage");
452
+ a(this, "length");
453
+ this.gl = i, this.type = e, this.data = t, this.usage = s;
454
+ const l = i.createBuffer();
455
+ if (!l)
456
+ throw new Error("Failed to create buffer");
457
+ this.buffer = l, this.length = t.byteLength, i.bindBuffer(e, this.buffer), i.bufferData(e, t, s);
458
+ }
459
+ bind() {
460
+ this.gl.bindBuffer(this.type, this.buffer);
461
+ }
462
+ // update(data: ArrayBufferView) {
463
+ // const gl = this.gl;
464
+ // gl.bindBuffer(this.type, this.buffer);
465
+ // gl.bufferSubData(this.type, 0, data);
466
+ // this.data = data;
467
+ // }
468
+ dispose() {
469
+ this.gl.deleteBuffer(this.buffer);
470
+ }
471
+ }
472
+ class Re {
473
+ constructor(i, e, t, s, l) {
474
+ a(this, "albumTexture");
475
+ a(this, "alpha", 0);
476
+ this.gl = i, this.mainProgram = e, this.vertexBuffer = t, this.indexBuffer = s;
477
+ const r = i.createTexture();
478
+ if (!r)
479
+ throw new Error("Failed to create texture");
480
+ this.albumTexture = r, i.bindTexture(i.TEXTURE_2D, r), i.texImage2D(
481
+ i.TEXTURE_2D,
482
+ 0,
483
+ i.RGBA,
484
+ i.RGBA,
485
+ i.UNSIGNED_BYTE,
486
+ l
487
+ ), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.MIRRORED_REPEAT), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.MIRRORED_REPEAT);
488
+ }
489
+ draw(i) {
490
+ const e = this.gl;
491
+ this.mainProgram.use(), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, this.albumTexture), this.mainProgram.setUniform1i(i, 0), e.drawArrays(e.TRIANGLE_STRIP, 0, 4);
492
+ }
493
+ dispose() {
494
+ this.gl.deleteTexture(this.albumTexture);
495
+ }
496
+ }
497
+ class De {
498
+ constructor(i) {
499
+ a(this, "tex");
500
+ a(this, "alpha", 0);
501
+ this.gl = i;
502
+ const e = i.createTexture();
503
+ if (!e)
504
+ throw new Error("Failed to create texture");
505
+ this.tex = e, Z.decode().then(() => {
506
+ i.bindTexture(i.TEXTURE_2D, e), i.texImage2D(
507
+ i.TEXTURE_2D,
508
+ 0,
509
+ i.RGBA,
510
+ i.RGBA,
511
+ i.UNSIGNED_BYTE,
512
+ Z
513
+ ), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.NEAREST), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.NEAREST), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.REPEAT), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.REPEAT);
514
+ });
515
+ }
516
+ active(i = this.gl.TEXTURE1) {
517
+ this.gl.activeTexture(i), this.gl.bindTexture(this.gl.TEXTURE_2D, this.tex);
518
+ }
519
+ dispose() {
520
+ this.gl.deleteTexture(this.tex);
521
+ }
522
+ }
523
+ const F = class F extends te {
524
+ constructor(e) {
525
+ super(e);
526
+ a(this, "hasLyric", !0);
527
+ a(this, "hasLyricValue", 1);
528
+ a(this, "maxFPS", 30);
529
+ a(this, "lastTickTime", 0);
530
+ a(this, "lastFrameTime", 0);
531
+ a(this, "_lowFreqVolume", 1);
532
+ a(this, "paused", !1);
533
+ a(this, "staticMode", !1);
534
+ a(this, "gl", this.setupGL());
535
+ a(this, "reduceImageSizeCanvas", new OffscreenCanvas(128, 128));
536
+ a(this, "tickHandle", 0);
537
+ a(this, "sprites", []);
538
+ a(this, "ampTransition", 0);
539
+ a(this, "playTime", 0);
540
+ a(this, "frameTime", 0);
541
+ a(this, "IllIlllIlIIlllI", [-0.1, 0]);
542
+ a(this, "mainProgram", new q(
543
+ this.gl,
544
+ Y,
545
+ Le,
546
+ "main"
547
+ ));
548
+ a(this, "blendProgram", new q(
549
+ this.gl,
550
+ Y,
551
+ Se,
552
+ "blend"
553
+ ));
554
+ a(this, "copyProgram", new q(
555
+ this.gl,
556
+ Y,
557
+ be,
558
+ "copy"
559
+ ));
560
+ a(this, "noiseProgram", new q(
561
+ this.gl,
562
+ Y,
563
+ xe,
564
+ "noise"
565
+ ));
566
+ a(this, "vertexBuffer", new j(
567
+ this.gl,
568
+ this.gl.ARRAY_BUFFER,
569
+ F.rawVertexBuffer,
570
+ this.gl.STATIC_DRAW
571
+ ));
572
+ a(this, "indexBuffer", new j(
573
+ this.gl,
574
+ this.gl.ELEMENT_ARRAY_BUFFER,
575
+ F.rawIndexBuffer,
576
+ this.gl.STATIC_DRAW
577
+ ));
578
+ a(this, "noiseTexture", new De(this.gl));
579
+ a(this, "fb");
580
+ a(this, "historyFrameBuffer", []);
581
+ a(this, "_currentSize", [0, 0]);
582
+ a(this, "_targetSize", [0, 0]);
583
+ a(this, "renderSize", [0, 0]);
584
+ a(this, "pixelSize", [0, 0]);
585
+ this.canvas = e;
586
+ const t = this.gl;
587
+ t.enable(this.gl.BLEND), t.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA), this.requestTick();
588
+ const s = e.getBoundingClientRect(), l = s.width * window.devicePixelRatio * this.currerntRenderScale, r = s.height * window.devicePixelRatio * this.currerntRenderScale;
589
+ this.fb = [
590
+ new Q(this.gl, l, r),
591
+ new Q(this.gl, l, r)
592
+ ];
593
+ for (const n of this.fb)
594
+ n.bind(), t.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
595
+ this.historyFrameBuffer = new Array(2).fill(0).map(() => new Q(this.gl, l, r)), this.onResize(l, r);
596
+ }
597
+ onTick(e) {
598
+ if (this.tickHandle = 0, this.paused)
599
+ return;
600
+ const t = e - this.lastTickTime, s = e - this.lastFrameTime;
601
+ if (this.lastFrameTime = e, t < 1e3 / this.maxFPS) {
602
+ this.requestTick();
603
+ return;
604
+ }
605
+ this.hasLyric && (this.playTime += s * this.flowSpeed * 0.2), this.frameTime += s, this.onRedraw(this.playTime, s) && this.staticMode || this.requestTick(), this.lastTickTime = e, this.ampTransition;
606
+ }
607
+ onResize(e, t) {
608
+ this._targetSize = [
609
+ Math.max(1, Math.round(e)),
610
+ Math.max(1, Math.round(t))
611
+ ], this.staticMode && this.requestTick();
612
+ }
613
+ checkResize() {
614
+ if (this._currentSize[0] === this._targetSize[0] && this._currentSize[1] === this._targetSize[1])
615
+ return;
616
+ this._currentSize = [...this._targetSize];
617
+ const [e, t] = this._targetSize, s = Math.round(
618
+ Math.max(e / this.currerntRenderScale, e)
619
+ ), l = Math.round(
620
+ Math.max(t / this.currerntRenderScale, t)
621
+ );
622
+ this.renderSize = [e, t], this.canvas.width = s, this.canvas.height = l, this.pixelSize = [s, l], this.gl.viewport(0, 0, s, l);
623
+ for (const r of this.fb)
624
+ r.resize(e, t);
625
+ for (const r of this.historyFrameBuffer)
626
+ r.resize(s, l);
627
+ }
628
+ requestTick() {
629
+ this.tickHandle || (this.tickHandle = requestAnimationFrame((e) => this.onTick(e)));
630
+ }
631
+ drawScreen() {
632
+ this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
633
+ }
634
+ bindDefaultFrameBuffer() {
635
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
636
+ }
637
+ onRedraw(e, t) {
638
+ this.checkResize(), this.hasLyricValue = (this.hasLyricValue * 19 + (this.hasLyric ? 1 : 0)) / 20;
639
+ const s = this.gl;
640
+ this.vertexBuffer.bind(), this.indexBuffer.bind(), this.mainProgram.use(), this.noiseTexture.active(), this.mainProgram.setUniform1i("noisetex", 1), this.mainProgram.setUniform2f(
641
+ "IIlIlIIlIlIllI",
642
+ this.renderSize[0],
643
+ this.renderSize[1]
644
+ ), this.mainProgram.setUniform1f(
645
+ "lIIIlllllIllIl",
646
+ this.hasLyric ? e / 1e3 : 0
647
+ ), this.mainProgram.setUniform1f("IIIlllllllIIIllIl", this.hasLyricValue), this.mainProgram.setUniform1f(
648
+ "IIIlllIlIIllll",
649
+ this.hasLyric ? this._lowFreqVolume : 0
650
+ ), this.mainProgram.setUniform2f(
651
+ "IllIlllIlIIlllI",
652
+ this.IllIlllIlIIlllI[0],
653
+ this.IllIlllIlIIlllI[1]
654
+ );
655
+ const [l, r] = this.fb;
656
+ r.bind(), s.clearColor(0, 0, 0, 0), s.clear(this.gl.COLOR_BUFFER_BIT);
657
+ for (const c of this.sprites)
658
+ l.bind(), s.clearColor(0, 0, 0, 0), s.clear(this.gl.COLOR_BUFFER_BIT), this.mainProgram.use(), c.draw("IlllIIlIlllIll"), r.bind(), this.blendProgram.use(), l.active(), this.blendProgram.setUniform1i("src", 0), this.blendProgram.setUniform1f("lerp", c.alpha), this.blendProgram.setUniform1f("scale", this.currerntRenderScale), this.drawScreen(), c.alpha = Math.min(1, c.alpha + t / 200);
659
+ if (this.noiseProgram.use(), this.noiseProgram.setUniform1i("src", 0), l.bind(), r.active(), this.bindDefaultFrameBuffer(), this.drawScreen(), this.sprites.length > 1 && this.sprites[this.sprites.length - 1].alpha >= 1)
660
+ for (const I of this.sprites.splice(0, this.sprites.length - 1))
661
+ I.dispose();
662
+ const n = this.sprites.length === 1 && this.sprites[0].alpha >= 1, h = this.hasLyric ? this.hasLyricValue > 1e-5 : this.hasLyricValue < 0.99999;
663
+ return n || !h;
664
+ }
665
+ copyFrameBuffer(e, t = null) {
666
+ e !== t && (e.active(this.gl.TEXTURE0), this.copyProgram.use(), t ? t.bind() : this.bindDefaultFrameBuffer(), this.copyProgram.setUniform1i("src", 0), this.drawScreen());
667
+ }
668
+ setupGL() {
669
+ const e = this.canvas.getContext("webgl2", {
670
+ alpha: !0,
671
+ depth: !1,
672
+ powerPreference: "low-power"
673
+ });
674
+ if (!e)
675
+ throw new Error("WebGL2 not supported");
676
+ return this.gl = e, e.enable(e.BLEND), e.disable(e.DEPTH_TEST), e.blendFunc(e.SRC_ALPHA, e.ONE_MINUS_SRC_ALPHA), e.getExtension("EXT_color_buffer_float") || console.warn("EXT_color_buffer_float not supported"), e.getExtension("EXT_float_blend") || console.warn("EXT_float_blend not supported"), e.getExtension("OES_texture_float_linear") || console.warn("OES_texture_float_linear not supported"), e;
677
+ }
678
+ setLowFreqVolume(e) {
679
+ this._lowFreqVolume = e;
680
+ }
681
+ setStaticMode(e) {
682
+ this.staticMode = e, this.lastFrameTime = performance.now(), this.requestTick();
683
+ }
684
+ setFPS(e) {
685
+ this.maxFPS = e;
686
+ }
687
+ pause() {
688
+ this.tickHandle && (cancelAnimationFrame(this.tickHandle), this.tickHandle = 0), this.paused = !0;
689
+ }
690
+ resume() {
691
+ this.paused = !1, this.requestTick();
692
+ }
693
+ async setAlbum(e, t = !1) {
694
+ if (typeof e == "string" && e.trim().length === 0)
695
+ throw new Error("Empty album url");
696
+ let s = null, l = 5;
697
+ for (console.log("setAlbum", e); !s && l > 0; )
698
+ try {
699
+ typeof e == "string" ? s = await ie(e, t) : s = await se(e);
700
+ } catch (p) {
701
+ console.warn(
702
+ `failed on loading album resource, retrying (${l})`,
703
+ {
704
+ albumSource: e,
705
+ error: p
706
+ }
707
+ ), l--;
708
+ }
709
+ if (console.log("loaded album resource", s), !s)
710
+ return;
711
+ const r = this.reduceImageSizeCanvas, n = r.getContext("2d");
712
+ if (!n)
713
+ throw new Error("Failed to create canvas context");
714
+ n.clearRect(0, 0, r.width, r.height);
715
+ const h = 10, c = s instanceof HTMLVideoElement ? s.videoWidth : s.naturalWidth, I = s instanceof HTMLVideoElement ? s.videoHeight : s.naturalHeight;
716
+ if (c * I === 0)
717
+ throw new Error("Invalid image size");
718
+ n.drawImage(s, 0, 0, c, I, 0, 0, r.width, r.height);
719
+ const d = n.getImageData(0, 0, r.width, r.height);
720
+ Me(d, 0.8), ve(d, 1.5), Ae(d, h, 4);
721
+ const m = new Re(
722
+ this.gl,
723
+ this.mainProgram,
724
+ this.vertexBuffer,
725
+ this.indexBuffer,
726
+ d
727
+ );
728
+ this.sprites.push(m), this.playTime = Math.random() * 1e5, this.lastFrameTime = performance.now(), console.info(Math.random() * 1e4);
729
+ const f = Number.parseInt((Math.random() * 1e4).toFixed(0)) % 3;
730
+ f === 0 ? this.IllIlllIlIIlllI = [-1.3, -0.9] : f === 1 ? this.IllIlllIlIIlllI = [-1.1, -0.9] : this.IllIlllIlIIlllI = [-1.3, -0.9], this.requestTick();
731
+ }
732
+ setHasLyric(e) {
733
+ this.hasLyric = e, this.requestTick();
734
+ }
735
+ getElement() {
736
+ return this.canvas;
737
+ }
738
+ dispose() {
739
+ super.dispose(), this.vertexBuffer.dispose(), this.indexBuffer.dispose(), this.noiseTexture.dispose();
740
+ for (const e of this.sprites)
741
+ e.dispose();
742
+ this.copyProgram.dispose(), this.blendProgram.dispose(), this.mainProgram.dispose();
743
+ for (const e of this.fb)
744
+ e.dispose();
745
+ for (const e of this.historyFrameBuffer)
746
+ e.dispose();
747
+ this.tickHandle && (cancelAnimationFrame(this.tickHandle), this.tickHandle = 0);
748
+ }
749
+ };
750
+ a(F, "rawVertexBuffer", new Float32Array([
751
+ -1,
752
+ -1,
753
+ 1,
754
+ -1,
755
+ -1,
756
+ 1,
757
+ 1,
758
+ 1
759
+ ])), a(F, "rawIndexBuffer", new Uint16Array([0, 1, 2, 1, 2, 3]));
760
+ let J = F;
761
+ class le {
762
+ constructor(i, e) {
763
+ a(this, "element");
764
+ a(this, "renderer");
765
+ this.renderer = i, this.element = e, e.style.pointerEvents = "none", e.style.zIndex = "-1", e.style.contain = "strict";
766
+ }
767
+ static new(i) {
768
+ const e = document.createElement("canvas");
769
+ return new le(new i(e), e);
770
+ }
771
+ setRenderScale(i) {
772
+ this.renderer.setRenderScale(i);
773
+ }
774
+ setFlowSpeed(i) {
775
+ this.renderer.setFlowSpeed(i);
776
+ }
777
+ setStaticMode(i) {
778
+ this.renderer.setStaticMode(i);
779
+ }
780
+ setFPS(i) {
781
+ this.renderer.setFPS(i);
782
+ }
783
+ pause() {
784
+ this.renderer.pause();
785
+ }
786
+ resume() {
787
+ this.renderer.resume();
788
+ }
789
+ setLowFreqVolume(i) {
790
+ this.renderer.setLowFreqVolume(i);
791
+ }
792
+ setHasLyric(i) {
793
+ this.renderer.setHasLyric(i);
794
+ }
795
+ setAlbum(i, e) {
796
+ return this.renderer.setAlbum(i, e);
797
+ }
798
+ getElement() {
799
+ return this.element;
800
+ }
801
+ dispose() {
802
+ this.renderer.dispose(), this.element.remove();
803
+ }
804
+ }
805
+ const Fe = (o, i) => o.size === i.size && [...o].every((e) => i.has(e));
806
+ function Ce(o) {
807
+ return (e) => (o(e + 1e-3) - o(e - 1e-3)) / (2 * 1e-3);
808
+ }
809
+ function K(o) {
810
+ return Ce(o);
811
+ }
812
+ class U {
813
+ constructor(i = 0) {
814
+ a(this, "currentPosition", 0);
815
+ a(this, "targetPosition", 0);
816
+ a(this, "currentTime", 0);
817
+ a(this, "params", {});
818
+ a(this, "currentSolver");
819
+ a(this, "getV");
820
+ a(this, "getV2");
821
+ a(this, "queueParams");
822
+ a(this, "queuePosition");
823
+ this.targetPosition = i, this.currentPosition = this.targetPosition, this.currentSolver = () => this.targetPosition, this.getV = () => 0, this.getV2 = () => 0;
824
+ }
825
+ resetSolver() {
826
+ const i = this.getV(this.currentTime);
827
+ this.currentTime = 0, this.currentSolver = ze(
828
+ this.currentPosition,
829
+ i,
830
+ this.targetPosition,
831
+ 0,
832
+ this.params
833
+ ), this.getV = K(this.currentSolver), this.getV2 = K(this.getV);
834
+ }
835
+ arrived() {
836
+ return Math.abs(this.targetPosition - this.currentPosition) < 0.01 && this.getV(this.currentTime) < 0.01 && this.getV2(this.currentTime) < 0.01 && this.queueParams === void 0 && this.queuePosition === void 0;
837
+ }
838
+ setPosition(i) {
839
+ this.targetPosition = i, this.currentPosition = i, this.currentSolver = () => this.targetPosition, this.getV = () => 0, this.getV2 = () => 0;
840
+ }
841
+ update(i = 0) {
842
+ this.currentTime += i, this.currentPosition = this.currentSolver(this.currentTime), this.queueParams && (this.queueParams.time -= i, this.queueParams.time <= 0 && this.updateParams({
843
+ ...this.queueParams
844
+ })), this.queuePosition && (this.queuePosition.time -= i, this.queuePosition.time <= 0 && this.setTargetPosition(this.queuePosition.position)), this.arrived() && this.setPosition(this.targetPosition);
845
+ }
846
+ updateParams(i, e = 0) {
847
+ e > 0 ? this.queueParams = {
848
+ ...this.queuePosition ?? {},
849
+ ...i,
850
+ time: e
851
+ } : (this.queuePosition = void 0, this.params = {
852
+ ...this.params,
853
+ ...i
854
+ }, this.resetSolver());
855
+ }
856
+ setTargetPosition(i, e = 0) {
857
+ e > 0 ? this.queuePosition = {
858
+ ...this.queuePosition ?? {},
859
+ position: i,
860
+ time: e
861
+ } : (this.queuePosition = void 0, this.targetPosition = i, this.resetSolver());
862
+ }
863
+ getCurrentPosition() {
864
+ return this.currentPosition;
865
+ }
866
+ }
867
+ function ze(o, i, e, t = 0, s) {
868
+ const l = (s == null ? void 0 : s.soft) ?? !1, r = (s == null ? void 0 : s.stiffness) ?? 100, n = (s == null ? void 0 : s.damping) ?? 10, h = (s == null ? void 0 : s.mass) ?? 1, c = e - o;
869
+ if (l || 1 <= n / (2 * Math.sqrt(r * h))) {
870
+ const p = -Math.sqrt(r / h), y = -p * c - i;
871
+ return (u) => (u -= t, u < 0 ? o : e - (c + u * y) * Math.E ** (u * p));
872
+ }
873
+ const I = Math.sqrt(4 * h * r - n ** 2), d = (n * c - 2 * h * i) / I, m = 0.5 * I / h, f = -(0.5 * n) / h;
874
+ return (p) => (p -= t, p < 0 ? o : e - (Math.cos(p * m) * c + Math.sin(p * m) * d) * Math.E ** (p * f));
875
+ }
876
+ class Be {
877
+ constructor(i) {
878
+ a(this, "element", document.createElement("div"));
879
+ a(this, "left", 0);
880
+ a(this, "top", 0);
881
+ a(this, "delay", 0);
882
+ // 由 LyricPlayer 来设置
883
+ a(this, "lineSize", [0, 0]);
884
+ a(this, "lineTransforms", {
885
+ posX: new U(0),
886
+ posY: new U(0)
887
+ });
888
+ a(this, "lastStyle", "");
889
+ this.lyricPlayer = i, this.element.setAttribute(
890
+ "class",
891
+ this.lyricPlayer.style.classes.lyricLine
892
+ ), this.rebuildStyle();
893
+ }
894
+ measureSize() {
895
+ return [
896
+ this.element.clientWidth,
897
+ this.element.clientHeight
898
+ ];
899
+ }
900
+ show() {
901
+ this.rebuildStyle();
902
+ }
903
+ hide() {
904
+ this.rebuildStyle();
905
+ }
906
+ rebuildStyle() {
907
+ let i = `transform:translate(${this.lineTransforms.posX.getCurrentPosition().toFixed(2)}px,${this.lineTransforms.posY.getCurrentPosition().toFixed(2)}px);`;
908
+ !this.lyricPlayer.getEnableSpring() && this.isInSight && (i += `transition-delay:${this.delay}ms;`), i !== this.lastStyle && (this.lastStyle = i, this.element.setAttribute("style", i));
909
+ }
910
+ getElement() {
911
+ return this.element;
912
+ }
913
+ setTransform(i = this.left, e = this.top, t = !1, s = 0) {
914
+ this.left = i, this.top = e, this.delay = s * 1e3 | 0, t || !this.lyricPlayer.getEnableSpring() ? (t && this.element.classList.add(
915
+ this.lyricPlayer.style.classes.tmpDisableTransition
916
+ ), this.lineTransforms.posX.setPosition(i), this.lineTransforms.posY.setPosition(e), this.lyricPlayer.getEnableSpring() ? this.rebuildStyle() : this.show(), t && requestAnimationFrame(() => {
917
+ this.element.classList.remove(
918
+ this.lyricPlayer.style.classes.tmpDisableTransition
919
+ );
920
+ })) : (this.lineTransforms.posX.setTargetPosition(i, s), this.lineTransforms.posY.setTargetPosition(e, s));
921
+ }
922
+ update(i = 0) {
923
+ this.lyricPlayer.getEnableSpring() && (this.lineTransforms.posX.update(i), this.lineTransforms.posY.update(i), this.isInSight ? this.show() : this.hide());
924
+ }
925
+ get isInSight() {
926
+ const i = this.lineTransforms.posX.getCurrentPosition(), e = this.lineTransforms.posY.getCurrentPosition(), t = i + this.lineSize[0], s = e + this.lineSize[1], l = this.lyricPlayer.size[0], r = this.lyricPlayer.size[1];
927
+ return !(i > l || e > r || t < 0 || s < 0);
928
+ }
929
+ dispose() {
930
+ this.element.remove();
931
+ }
932
+ }
933
+ function ke(o) {
934
+ const e = 2.5949095;
935
+ return o < 0.5 ? Math.pow(2 * o, 2) * ((e + 1) * 2 * o - e) / 2 : (Math.pow(2 * o - 2, 2) * ((e + 1) * (o * 2 - 2) + e) + 2) / 2;
936
+ }
937
+ const D = (o, i, e) => Math.max(o, Math.min(i, e));
938
+ class Ue {
939
+ constructor(i) {
940
+ a(this, "element", document.createElement("div"));
941
+ a(this, "dot0", document.createElement("span"));
942
+ a(this, "dot1", document.createElement("span"));
943
+ a(this, "dot2", document.createElement("span"));
944
+ a(this, "left", 0);
945
+ a(this, "top", 0);
946
+ a(this, "scale", 1);
947
+ a(this, "playing", !0);
948
+ a(this, "lastStyle", "");
949
+ a(this, "currentInterlude");
950
+ a(this, "currentTime", 0);
951
+ a(this, "interludeTime", 0);
952
+ a(this, "targetBreatheDuration", 1500);
953
+ this.lyricPlayer = i, this.element.className = this.lyricPlayer.style.classes.interludeDots, this.element.appendChild(this.dot0), this.element.appendChild(this.dot1), this.element.appendChild(this.dot2);
954
+ }
955
+ getElement() {
956
+ return this.element;
957
+ }
958
+ setTransform(i = this.left, e = this.top) {
959
+ this.left = i, this.top = e, this.update();
960
+ }
961
+ setInterlude(i) {
962
+ this.currentInterlude = i, this.currentTime = (i == null ? void 0 : i[0]) ?? 0;
963
+ }
964
+ pause() {
965
+ this.playing = !1;
966
+ }
967
+ resume() {
968
+ this.playing = !0;
969
+ }
970
+ update(i = 0) {
971
+ if (!this.playing)
972
+ return;
973
+ this.currentTime += i;
974
+ let e = "";
975
+ if (e += `transform:translate(${this.left.toFixed(
976
+ 2
977
+ )}px, ${this.top.toFixed(2)}px)`, this.currentInterlude) {
978
+ const t = this.currentInterlude[1] - this.currentInterlude[0], s = this.currentTime - this.currentInterlude[0];
979
+ if (s <= t) {
980
+ const l = t / Math.ceil(t / this.targetBreatheDuration);
981
+ let r = 1, n = 1;
982
+ r *= Math.sin(1.5 * Math.PI - s / l * 2) / 20 + 1, s < 1e3 && (r *= 1 - ((1e3 - s) / 1e3) ** 2), s < 500 ? n = 0 : s < 1e3 && (n *= (s - 500) / 500), t - s < 750 && (r *= 1 - ke(
983
+ (750 - (t - s)) / 750 / 2
984
+ )), t - s < 375 && (n *= D(
985
+ 0,
986
+ (t - s) / 375,
987
+ 1
988
+ ));
989
+ const h = Math.max(0, t - 750);
990
+ r = Math.max(0, r) * 0.7, e += ` scale(${r})`;
991
+ const c = D(
992
+ 0.25,
993
+ s * 3 / h * 0.75,
994
+ 1
995
+ ), I = D(
996
+ 0.25,
997
+ (s - h / 3) * 3 / h * 0.75,
998
+ 1
999
+ ), d = D(
1000
+ 0.25,
1001
+ (s - h / 3 * 2) * 3 / h * 0.75,
1002
+ 1
1003
+ );
1004
+ this.dot0.style.opacity = `${D(
1005
+ 0,
1006
+ Math.max(0, n * c),
1007
+ 1
1008
+ )}`, this.dot1.style.opacity = `${D(
1009
+ 0,
1010
+ Math.max(0, n * I),
1011
+ 1
1012
+ )}`, this.dot2.style.opacity = `${D(
1013
+ 0,
1014
+ Math.max(0, n * d),
1015
+ 1
1016
+ )}`;
1017
+ } else
1018
+ e += " scale(0)", this.dot0.style.opacity = "0", this.dot1.style.opacity = "0", this.dot2.style.opacity = "0";
1019
+ } else
1020
+ e += " scale(0)", this.dot0.style.opacity = "0", this.dot1.style.opacity = "0", this.dot2.style.opacity = "0";
1021
+ e += ";", this.lastStyle !== e && (this.element.setAttribute("style", e), this.lastStyle = e);
1022
+ }
1023
+ dispose() {
1024
+ this.element.remove();
1025
+ }
1026
+ }
1027
+ function Oe() {
1028
+ return [
1029
+ 1,
1030
+ 0,
1031
+ 0,
1032
+ 0,
1033
+ 0,
1034
+ 1,
1035
+ 0,
1036
+ 0,
1037
+ 0,
1038
+ 0,
1039
+ 1,
1040
+ 0,
1041
+ 0,
1042
+ 0,
1043
+ 0,
1044
+ 1
1045
+ ];
1046
+ }
1047
+ function _e(o, i = 1, e = { x: 0, y: 0 }) {
1048
+ const [t, s] = [e.x, e.y];
1049
+ return [
1050
+ o[0] * i,
1051
+ o[1] * i,
1052
+ o[2] * i,
1053
+ o[3],
1054
+ o[4] * i,
1055
+ o[5] * i,
1056
+ o[6] * i,
1057
+ o[7],
1058
+ o[8] * i,
1059
+ o[9] * i,
1060
+ o[10] * i,
1061
+ o[11],
1062
+ o[12] - t * i + t,
1063
+ o[13] - s * i + s,
1064
+ o[14],
1065
+ o[15]
1066
+ ];
1067
+ }
1068
+ function Ne(o, i = 4) {
1069
+ const e = (t, s) => t.toFixed(i);
1070
+ return `matrix3d(${o.map(e).join(", ")})`;
1071
+ }
1072
+ function Ge(o) {
1073
+ return o && o.__esModule && Object.prototype.hasOwnProperty.call(o, "default") ? o.default : o;
1074
+ }
1075
+ var Ye = 4, qe = 1e-3, Ve = 1e-7, He = 10, B = 11, V = 1 / (B - 1), We = typeof Float32Array == "function";
1076
+ function re(o, i) {
1077
+ return 1 - 3 * i + 3 * o;
1078
+ }
1079
+ function ne(o, i) {
1080
+ return 3 * i - 6 * o;
1081
+ }
1082
+ function ae(o) {
1083
+ return 3 * o;
1084
+ }
1085
+ function W(o, i, e) {
1086
+ return ((re(i, e) * o + ne(i, e)) * o + ae(i)) * o;
1087
+ }
1088
+ function oe(o, i, e) {
1089
+ return 3 * re(i, e) * o * o + 2 * ne(i, e) * o + ae(i);
1090
+ }
1091
+ function Xe(o, i, e, t, s) {
1092
+ var l, r, n = 0;
1093
+ do
1094
+ r = i + (e - i) / 2, l = W(r, t, s) - o, l > 0 ? e = r : i = r;
1095
+ while (Math.abs(l) > Ve && ++n < He);
1096
+ return r;
1097
+ }
1098
+ function Qe(o, i, e, t) {
1099
+ for (var s = 0; s < Ye; ++s) {
1100
+ var l = oe(i, e, t);
1101
+ if (l === 0)
1102
+ return i;
1103
+ var r = W(i, e, t) - o;
1104
+ i -= r / l;
1105
+ }
1106
+ return i;
1107
+ }
1108
+ function Ze(o) {
1109
+ return o;
1110
+ }
1111
+ var je = function(i, e, t, s) {
1112
+ if (!(0 <= i && i <= 1 && 0 <= t && t <= 1))
1113
+ throw new Error("bezier x values must be in [0, 1] range");
1114
+ if (i === e && t === s)
1115
+ return Ze;
1116
+ for (var l = We ? new Float32Array(B) : new Array(B), r = 0; r < B; ++r)
1117
+ l[r] = W(r * V, i, t);
1118
+ function n(h) {
1119
+ for (var c = 0, I = 1, d = B - 1; I !== d && l[I] <= h; ++I)
1120
+ c += V;
1121
+ --I;
1122
+ var m = (h - l[I]) / (l[I + 1] - l[I]), f = c + m * V, p = oe(f, i, t);
1123
+ return p >= qe ? Qe(h, f, i, t) : p === 0 ? f : Xe(h, c, c + V, i, t);
1124
+ }
1125
+ return function(c) {
1126
+ return c === 0 ? 0 : c === 1 ? 1 : W(n(c), e, s);
1127
+ };
1128
+ };
1129
+ const $ = /* @__PURE__ */ Ge(je), Je = /^[\p{Unified_Ideograph}\u0800-\u9FFC]+$/u, H = 32, he = (o, i) => (e) => Math.min(1, Math.max(0, (e - o) / (i - o))), C = 0.4, Ke = he(0, C), $e = he(C, 1), ce = (o) => {
1130
+ const i = $(0.3, 0, 0.25, 1), e = $(0.5, 0, 0.3, 1);
1131
+ return (t) => t < o ? i(Ke(t)) : 1 - e($e(t));
1132
+ }, et = ce(C);
1133
+ function ee(o, i = 0, e = "rgba(0,0,0,0.85)", t = "rgba(0,0,0,0.25)") {
1134
+ const s = 2 + o + i, l = o / s, r = (1 - l) / 2;
1135
+ return [
1136
+ `linear-gradient(to right,${e} ${r * 100}%,${t} ${(r + l) * 100}%)`,
1137
+ s
1138
+ ];
1139
+ }
1140
+ function tt(o) {
1141
+ const i = [];
1142
+ for (const l of o) {
1143
+ const r = l.word.replace(/\s/g, "").length, n = l.word.split(" ").filter((h) => h.trim().length > 0);
1144
+ if (n.length > 1) {
1145
+ l.word.startsWith(" ") && i.push({
1146
+ word: " ",
1147
+ startTime: 0,
1148
+ endTime: 0
1149
+ });
1150
+ let h = 0;
1151
+ for (const c of n) {
1152
+ const I = {
1153
+ word: c,
1154
+ startTime: l.startTime + h / r * (l.endTime - l.startTime),
1155
+ endTime: l.startTime + (h + c.length) / r * (l.endTime - l.startTime)
1156
+ };
1157
+ i.push(I), i.push({
1158
+ word: " ",
1159
+ startTime: 0,
1160
+ endTime: 0
1161
+ }), h += c.length;
1162
+ }
1163
+ l.word.endsWith(" ") || i.pop();
1164
+ } else
1165
+ i.push(l);
1166
+ }
1167
+ let e = [], t = [];
1168
+ const s = [];
1169
+ for (const l of i) {
1170
+ const r = l.word;
1171
+ e.push(r), t.push(l), r.length > 0 && r.trim().length === 0 ? (e.pop(), t.pop(), t.length === 1 ? s.push(t[0]) : t.length > 1 && s.push(t), s.push(l), e = [], t = []) : (!/^\s*[^\s]*\s*$/.test(e.join("")) || Je.test(r)) && (e.pop(), t.pop(), t.length === 1 ? s.push(t[0]) : t.length > 1 && s.push(t), e = [r], t = [l]);
1172
+ }
1173
+ return t.length === 1 ? s.push(t[0]) : s.push(t), s;
1174
+ }
1175
+ function k(o) {
1176
+ return o.endTime - o.startTime >= 1e3 && o.word.trim().length <= 7 && o.word.trim().length >= 1;
1177
+ }
1178
+ class it extends MouseEvent {
1179
+ constructor(i, e) {
1180
+ super(e.type, e), this.line = i;
1181
+ }
1182
+ }
1183
+ class st extends EventTarget {
1184
+ // readonly lineWebAnimationTransforms = {
1185
+ // posX: new WebAnimationSpring(this.element, "transform", (v) => `translateX(${v.toFixed(1)}px)`),
1186
+ // posY: new WebAnimationSpring(this.element, "transform", (v) => `translateY(${v.toFixed(1)}px)`),
1187
+ // scale: new WebAnimationSpring(this.element, "transform", (v) => `scale(${v.toFixed(4)})`, 1),
1188
+ // };
1189
+ constructor(e, t = {
1190
+ words: [],
1191
+ translatedLyric: "",
1192
+ romanLyric: "",
1193
+ startTime: 0,
1194
+ endTime: 0,
1195
+ isBG: !1,
1196
+ isDuet: !1
1197
+ }) {
1198
+ super();
1199
+ a(this, "element", document.createElement("div"));
1200
+ a(this, "left", 0);
1201
+ a(this, "top", 0);
1202
+ a(this, "scale", 1);
1203
+ a(this, "blur", 0);
1204
+ a(this, "delay", 0);
1205
+ a(this, "splittedWords", []);
1206
+ // 由 LyricPlayer 来设置
1207
+ a(this, "lineSize", [0, 0]);
1208
+ a(this, "lineTransforms", {
1209
+ posX: new U(0),
1210
+ posY: new U(0),
1211
+ scale: new U(1)
1212
+ });
1213
+ a(this, "listenersMap", /* @__PURE__ */ new Map());
1214
+ a(this, "onMouseEvent", (e) => {
1215
+ const t = new it(this, e);
1216
+ for (const s of this.listenersMap.get(e.type) ?? [])
1217
+ s.call(this, t);
1218
+ if (!this.dispatchEvent(t) || t.defaultPrevented)
1219
+ return e.preventDefault(), e.stopPropagation(), e.stopImmediatePropagation(), !1;
1220
+ });
1221
+ a(this, "isEnabled", !1);
1222
+ a(this, "_hide", !0);
1223
+ a(this, "_prevParentEl", null);
1224
+ a(this, "lastStyle", "");
1225
+ this.lyricPlayer = e, this.lyricLine = t, this._prevParentEl = e.getElement(), this.element.setAttribute(
1226
+ "class",
1227
+ this.lyricPlayer.style.classes.lyricLine
1228
+ ), this.lyricLine.isBG && this.element.classList.add(this.lyricPlayer.style.classes.lyricBgLine), this.lyricLine.isDuet && this.element.classList.add(this.lyricPlayer.style.classes.lyricDuetLine), this.element.appendChild(document.createElement("div")), this.element.appendChild(document.createElement("div")), this.element.appendChild(document.createElement("div"));
1229
+ const s = this.element.children[0], l = this.element.children[1], r = this.element.children[2];
1230
+ s.setAttribute("class", this.lyricPlayer.style.classes.lyricMainLine), l.setAttribute("class", this.lyricPlayer.style.classes.lyricSubLine), r.setAttribute("class", this.lyricPlayer.style.classes.lyricSubLine), this.rebuildElement(), this.rebuildStyle();
1231
+ }
1232
+ addMouseEventListener(e, t, s) {
1233
+ if (t) {
1234
+ const l = this.listenersMap.get(e) ?? /* @__PURE__ */ new Set();
1235
+ l.size === 0 && this.element.addEventListener(e, this.onMouseEvent, s), l.add(t), this.listenersMap.set(e, l);
1236
+ }
1237
+ }
1238
+ removeMouseEventListener(e, t, s) {
1239
+ if (t) {
1240
+ const l = this.listenersMap.get(e);
1241
+ l && (l.delete(t), l.size === 0 && this.element.removeEventListener(e, this.onMouseEvent, s));
1242
+ }
1243
+ }
1244
+ enable(e = this.lyricLine.startTime) {
1245
+ this.isEnabled = !0, this.element.classList.add("active");
1246
+ const t = this.element.children[0];
1247
+ for (const s of this.splittedWords) {
1248
+ for (const l of s.elementAnimations)
1249
+ l.currentTime = 0, l.playbackRate = 1, l.play();
1250
+ for (const l of s.maskAnimations)
1251
+ l.currentTime = Math.min(
1252
+ this.totalDuration,
1253
+ Math.max(0, e - this.lyricLine.startTime)
1254
+ ), l.playbackRate = 1, l.play();
1255
+ }
1256
+ t.classList.add("active");
1257
+ }
1258
+ disable(e = 0) {
1259
+ this.isEnabled = !1, this.element.classList.remove("active");
1260
+ const t = this.element.children[0];
1261
+ for (const s of this.splittedWords) {
1262
+ for (const l of s.elementAnimations)
1263
+ l.id === "float-word" && (l.playbackRate = -1, l.play());
1264
+ for (const l of s.maskAnimations)
1265
+ l.currentTime = Math.min(
1266
+ this.totalDuration,
1267
+ Math.max(0, e - this.lyricLine.startTime)
1268
+ ), l.pause();
1269
+ }
1270
+ t.classList.remove("active");
1271
+ }
1272
+ resume() {
1273
+ if (this.isEnabled)
1274
+ for (const e of this.splittedWords)
1275
+ for (const t of e.maskAnimations)
1276
+ t.play();
1277
+ }
1278
+ pause() {
1279
+ if (this.isEnabled)
1280
+ for (const e of this.splittedWords)
1281
+ for (const t of e.maskAnimations)
1282
+ t.pause();
1283
+ }
1284
+ setMaskAnimationState(e = 0) {
1285
+ const t = e - this.lyricLine.startTime;
1286
+ for (const s of this.splittedWords)
1287
+ for (const l of s.maskAnimations)
1288
+ l.currentTime = Math.min(this.totalDuration, Math.max(0, t)), l.playbackRate = 1, t >= 0 && t < this.totalDuration ? l.play() : l.pause();
1289
+ }
1290
+ measureSize() {
1291
+ this._hide && (this._prevParentEl && this._prevParentEl.appendChild(this.element), this.element.style.display = "", this.element.style.visibility = "hidden");
1292
+ const e = [
1293
+ this.element.clientWidth,
1294
+ this.element.clientHeight
1295
+ ];
1296
+ return this._hide && (this._prevParentEl && this.element.remove(), this.element.style.display = "none", this.element.style.visibility = ""), e;
1297
+ }
1298
+ setLine(e) {
1299
+ this.lyricLine = e, this.lyricLine.isBG ? this.element.classList.add(this.lyricPlayer.style.classes.lyricBgLine) : this.element.classList.remove(this.lyricPlayer.style.classes.lyricBgLine), this.lyricLine.isDuet ? this.element.classList.add(this.lyricPlayer.style.classes.lyricDuetLine) : this.element.classList.remove(
1300
+ this.lyricPlayer.style.classes.lyricDuetLine
1301
+ ), this.rebuildElement(), this.rebuildStyle();
1302
+ }
1303
+ getLine() {
1304
+ return this.lyricLine;
1305
+ }
1306
+ show() {
1307
+ this._hide = !1, this._prevParentEl && (this._prevParentEl.appendChild(this.element), this._prevParentEl = null), this.rebuildStyle();
1308
+ }
1309
+ hide() {
1310
+ this._hide = !0, this.element.parentElement && (this._prevParentEl = this.element.parentElement, this.element.remove()), this.rebuildStyle();
1311
+ }
1312
+ rebuildStyle() {
1313
+ if (this._hide) {
1314
+ this.lastStyle !== "display:none;transform:translate(0,-10000px);" && (this.lastStyle = "display:none;transform:translate(0,-10000px);", this.element.setAttribute(
1315
+ "style",
1316
+ "display:none;transform:translate(0,-10000px);"
1317
+ ));
1318
+ return;
1319
+ }
1320
+ let e = "";
1321
+ e += `transform:translate(${this.lineTransforms.posX.getCurrentPosition().toFixed(1)}px,${this.lineTransforms.posY.getCurrentPosition().toFixed(1)}px) scale(${this.lineTransforms.scale.getCurrentPosition().toFixed(4)});`, !this.lyricPlayer.getEnableSpring() && this.isInSight && (e += `transition-delay:${this.delay}ms;`), e += `filter:blur(${Math.min(32, this.blur)}px);`, e !== this.lastStyle && (this.lastStyle = e, this.element.setAttribute("style", e));
1322
+ }
1323
+ rebuildElement() {
1324
+ const e = this.element.children[0], t = this.element.children[1], s = this.element.children[2];
1325
+ if (this.lyricPlayer._getIsNonDynamic()) {
1326
+ e.innerText = this.lyricLine.words.map((r) => r.word).join(""), t.innerText = this.lyricLine.translatedLyric, s.innerText = this.lyricLine.romanLyric;
1327
+ return;
1328
+ }
1329
+ const l = tt(this.lyricLine.words);
1330
+ e.innerHTML = "", this.splittedWords = [];
1331
+ for (const r of l)
1332
+ if (Array.isArray(r)) {
1333
+ if (r.length === 0)
1334
+ continue;
1335
+ const n = r.reduce(
1336
+ (d, m) => (d.endTime = Math.max(d.endTime, m.endTime), d.startTime = Math.min(d.startTime, m.startTime), d.word += m.word, d),
1337
+ { word: "", startTime: 1 / 0, endTime: -1 / 0 }
1338
+ ), h = r.map((d) => k(d)).reduce((d, m) => d || m, k(n)), c = document.createElement("span");
1339
+ c.classList.add("emphasize-wrapper");
1340
+ const I = [];
1341
+ for (const d of r) {
1342
+ const m = document.createElement("span");
1343
+ if (h) {
1344
+ m.classList.add("emphasize");
1345
+ const f = [];
1346
+ for (const y of d.word.trim().split("")) {
1347
+ const u = document.createElement("span");
1348
+ u.innerText = y, f.push(u), I.push(u), m.appendChild(u);
1349
+ }
1350
+ const p = {
1351
+ ...d,
1352
+ mainElement: m,
1353
+ subElements: f,
1354
+ elementAnimations: [this.initFloatAnimation(n, m)],
1355
+ maskAnimations: [],
1356
+ width: 0,
1357
+ height: 0,
1358
+ padding: 0,
1359
+ shouldEmphasize: h
1360
+ };
1361
+ this.splittedWords.push(p);
1362
+ } else
1363
+ m.innerText = d.word, this.splittedWords.push({
1364
+ ...d,
1365
+ mainElement: m,
1366
+ subElements: [],
1367
+ elementAnimations: [this.initFloatAnimation(d, m)],
1368
+ maskAnimations: [],
1369
+ width: 0,
1370
+ height: 0,
1371
+ padding: 0,
1372
+ shouldEmphasize: h
1373
+ });
1374
+ c.appendChild(m);
1375
+ }
1376
+ h && this.splittedWords[this.splittedWords.length - 1].elementAnimations.push(
1377
+ ...this.initEmphasizeAnimation(
1378
+ I,
1379
+ n.endTime - n.startTime,
1380
+ n.startTime - this.lyricLine.startTime
1381
+ )
1382
+ ), n.word.trimStart() !== n.word && e.appendChild(document.createTextNode(" ")), e.appendChild(c), n.word.trimEnd() !== n.word && e.appendChild(document.createTextNode(" "));
1383
+ } else if (r.word.trim().length === 0)
1384
+ e.appendChild(document.createTextNode(" "));
1385
+ else {
1386
+ const n = k(r), h = document.createElement("span"), c = {
1387
+ ...r,
1388
+ mainElement: h,
1389
+ subElements: [],
1390
+ elementAnimations: [this.initFloatAnimation(r, h)],
1391
+ maskAnimations: [],
1392
+ width: 0,
1393
+ height: 0,
1394
+ padding: 0,
1395
+ shouldEmphasize: n
1396
+ };
1397
+ if (n) {
1398
+ h.classList.add("emphasize");
1399
+ const I = [];
1400
+ for (const m of r.word.trim().split("")) {
1401
+ const f = document.createElement("span");
1402
+ f.innerText = m, I.push(f), h.appendChild(f);
1403
+ }
1404
+ c.subElements = I;
1405
+ const d = Math.abs(c.endTime - c.startTime);
1406
+ c.elementAnimations.push(
1407
+ ...this.initEmphasizeAnimation(
1408
+ I,
1409
+ d,
1410
+ c.startTime - this.lyricLine.startTime
1411
+ )
1412
+ );
1413
+ } else
1414
+ h.innerText = r.word.trim();
1415
+ r.word.trimStart() !== r.word && e.appendChild(document.createTextNode(" ")), e.appendChild(h), r.word.trimEnd() !== r.word && e.appendChild(document.createTextNode(" ")), this.splittedWords.push(c);
1416
+ }
1417
+ t.innerText = this.lyricLine.translatedLyric, s.innerText = this.lyricLine.romanLyric;
1418
+ }
1419
+ initFloatAnimation(e, t) {
1420
+ const s = e.startTime - this.lyricLine.startTime, l = Math.max(1e3, e.endTime - e.startTime);
1421
+ let r = 0.05;
1422
+ this.lyricLine.isBG && (r *= 2), k(e) && l < 1200 && (r = 0);
1423
+ const n = t.animate(
1424
+ [
1425
+ {
1426
+ transform: "translateY(0px)"
1427
+ },
1428
+ {
1429
+ transform: `translateY(${-r}em)`
1430
+ }
1431
+ ],
1432
+ {
1433
+ duration: isFinite(l) ? l : 0,
1434
+ delay: isFinite(s) ? s : 0,
1435
+ id: "float-word",
1436
+ composite: "add",
1437
+ fill: "both",
1438
+ easing: "ease-out"
1439
+ }
1440
+ );
1441
+ return n.pause(), n;
1442
+ }
1443
+ // 按照原 Apple Music 参考,强调效果只应用缩放、轻微左右位移和辉光效果,原主要的悬浮位移效果不变
1444
+ // 为了避免产生锯齿抖动感,使用 matrix3d 来实现缩放和位移
1445
+ initEmphasizeAnimation(e, t, s) {
1446
+ const l = Math.max(0, s), r = Math.max(1e3, t);
1447
+ let n = "float-and-glow";
1448
+ r < 1200 && (n = "float-only");
1449
+ let h = [];
1450
+ switch (n) {
1451
+ case "float-and-glow": {
1452
+ let c = 0, I = 0;
1453
+ r >= 1200 && r < 2e3 ? (c = 0.7, I = 0.5) : r >= 2e3 && r < 3e3 ? (c = 0.8, I = 0.6) : (r >= 3e3 && r < 4e3 || r >= 4e3) && (c = 1, I = 0.8);
1454
+ const d = Number.isFinite(r) ? Math.max(r * 1.2, 2e3) : 0, m = ce(C);
1455
+ h = e.flatMap((f, p, y) => {
1456
+ const u = l + r / 3 / y.length * p, g = [], E = new Array(H).fill(0).map((w, T) => {
1457
+ const b = (T + 1) / H, S = m(b), M = Math.sin(b * Math.PI * 2), x = Math.max(0, b < C ? S / 2 : S - 0.5) * I, P = _e(Oe(), 1 + S * 0.1 * c);
1458
+ return {
1459
+ offset: b,
1460
+ transform: `${Ne(P, 4)} translate(${M * 5e-3 * c}em,${-S * 0.05}em)`,
1461
+ textShadow: `rgba(255, 255, 255, ${x}) 0 0 10px`
1462
+ };
1463
+ }), L = f.animate(E, {
1464
+ duration: d,
1465
+ delay: Number.isFinite(u) ? u : 0,
1466
+ id: `emphasize-word-float-and-glow-${f.innerText}-${p}`,
1467
+ iterations: 1,
1468
+ composite: "replace",
1469
+ easing: "linear",
1470
+ fill: "both"
1471
+ });
1472
+ return L.onfinish = () => {
1473
+ L.pause();
1474
+ }, L.pause(), g.push(L), g;
1475
+ });
1476
+ break;
1477
+ }
1478
+ case "float-only": {
1479
+ h = e.flatMap((c, I, d) => {
1480
+ const m = l + r / 1.5 / d.length * I, f = [], p = new Array(H).fill(0).map((u, g) => {
1481
+ const E = (g + 1) / H, L = E < C ? et(E) : 1;
1482
+ return {
1483
+ offset: E,
1484
+ transform: `translateY(${-L * 0.05}em)`
1485
+ };
1486
+ }), y = c.animate(p, {
1487
+ duration: Number.isFinite(r) ? r * 2 : 0,
1488
+ delay: Number.isFinite(m) ? m : 0,
1489
+ id: `emphasize-word-float-only-${c.innerText}-${I}`,
1490
+ iterations: 1,
1491
+ composite: "replace",
1492
+ easing: "linear",
1493
+ fill: "both"
1494
+ });
1495
+ return y.onfinish = () => {
1496
+ y.pause();
1497
+ }, y.pause(), f.push(y), f;
1498
+ });
1499
+ break;
1500
+ }
1501
+ }
1502
+ return h;
1503
+ }
1504
+ get totalDuration() {
1505
+ return this.lyricLine.endTime - this.lyricLine.startTime;
1506
+ }
1507
+ updateMaskImage() {
1508
+ this._hide && (this._prevParentEl && this._prevParentEl.appendChild(this.element), this.element.style.display = "", this.element.style.visibility = "hidden");
1509
+ for (const e of this.splittedWords) {
1510
+ const t = e.mainElement;
1511
+ t ? (e.padding = parseFloat(getComputedStyle(t).paddingLeft), e.width = t.clientWidth - e.padding * 2, e.height = t.clientHeight - e.padding * 2) : (e.width = 0, e.height = 0, e.padding = 0);
1512
+ }
1513
+ this.lyricPlayer.supportMaskImage ? this.generateWebAnimationBasedMaskImage() : this.generateCalcBasedMaskImage(), this._hide && (this._prevParentEl && this.element.remove(), this.element.style.display = "none", this.element.style.visibility = "");
1514
+ }
1515
+ generateCalcBasedMaskImage() {
1516
+ for (const e of this.splittedWords) {
1517
+ const t = e.mainElement;
1518
+ if (t) {
1519
+ e.width = t.clientWidth, e.height = t.clientHeight;
1520
+ const s = e.height / 2, [l, r] = ee(
1521
+ s / e.width
1522
+ ), n = `${r * 100}% 100%`;
1523
+ this.lyricPlayer.supportMaskImage ? (t.style.maskImage = l, t.style.maskRepeat = "no-repeat", t.style.maskOrigin = "left", t.style.maskSize = n) : (t.style.webkitMaskImage = l, t.style.webkitMaskRepeat = "no-repeat", t.style.webkitMaskOrigin = "left", t.style.webkitMaskSize = n);
1524
+ const h = e.width + s, c = `clamp(${-h}px,calc(${-h}px + (var(--amll-player-time) - ${e.startTime})*${h / Math.abs(e.endTime - e.startTime)}px),0px) 0px, left top`;
1525
+ t.style.maskPosition = c, t.style.webkitMaskPosition = c;
1526
+ }
1527
+ }
1528
+ }
1529
+ generateWebAnimationBasedMaskImage() {
1530
+ const e = this.totalDuration;
1531
+ this.splittedWords.forEach((t, s) => {
1532
+ const l = t.mainElement;
1533
+ if (l) {
1534
+ const r = t.height / 2, [n, h] = ee(
1535
+ r / (t.width + t.padding * 2)
1536
+ ), c = `${h * 100}% 100%`;
1537
+ this.lyricPlayer.supportMaskImage ? (l.style.maskImage = n, l.style.maskRepeat = "no-repeat", l.style.maskOrigin = "left", l.style.maskSize = c) : (l.style.webkitMaskImage = n, l.style.webkitMaskRepeat = "no-repeat", l.style.webkitMaskOrigin = "left", l.style.webkitMaskSize = c);
1538
+ const I = this.splittedWords.slice(0, s).reduce((w, T) => w + T.width, 0) + (this.splittedWords[0] ? r : 0), d = -(t.width + t.padding * 2 + r), m = (w) => Math.max(d, Math.min(0, w));
1539
+ let f = -I - t.width - t.padding - r, p = 0;
1540
+ const y = [];
1541
+ let u = f, g = 0;
1542
+ const E = () => {
1543
+ const w = f - u, T = Math.max(0, Math.min(1, p)), b = T - g, S = Math.abs(b / w);
1544
+ if (f > d && u < d) {
1545
+ const P = Math.abs(u - d) * S, A = `${m(u)}px 0`, v = {
1546
+ offset: g + P,
1547
+ maskPosition: A
1548
+ };
1549
+ y.push(v);
1550
+ }
1551
+ if (f > 0 && u < 0) {
1552
+ const P = Math.abs(u) * S, A = `${m(f)}px 0`, v = {
1553
+ offset: g + P,
1554
+ maskPosition: A
1555
+ };
1556
+ y.push(v);
1557
+ }
1558
+ const M = `${m(f)}px 0`, x = {
1559
+ offset: T,
1560
+ maskPosition: M
1561
+ };
1562
+ y.push(x), u = f, g = T;
1563
+ };
1564
+ E();
1565
+ let L = 0;
1566
+ this.splittedWords.forEach((w, T) => {
1567
+ {
1568
+ const b = w.startTime - this.lyricLine.startTime, S = b - L;
1569
+ p += S / e, S > 0 && E(), L = b;
1570
+ }
1571
+ {
1572
+ const b = w.endTime - w.startTime;
1573
+ p += b / e, f += w.width, T === 0 && (f += r * 1.5), T === this.splittedWords.length - 1 && (f += r * 0.5), b > 0 && E(), L += b;
1574
+ }
1575
+ });
1576
+ for (const w of t.maskAnimations)
1577
+ w.cancel();
1578
+ try {
1579
+ const w = l.animate(y, {
1580
+ duration: e || 1,
1581
+ id: `fade-word-${t.word}-${s}`,
1582
+ easing: "linear",
1583
+ fill: "both"
1584
+ });
1585
+ w.pause(), t.maskAnimations = [w];
1586
+ } catch (w) {
1587
+ console.warn("应用渐变动画发生错误", y, e, w);
1588
+ }
1589
+ }
1590
+ });
1591
+ }
1592
+ getElement() {
1593
+ return this.element;
1594
+ }
1595
+ setTransform(e = this.left, t = this.top, s = this.scale, l = 1, r = 0, n = !1, h = 0) {
1596
+ const c = Math.round(r), I = this.isInSight, d = this.lyricPlayer.getEnableSpring();
1597
+ this.left = e, this.top = t, this.scale = s, this.delay = h * 1e3 | 0;
1598
+ const m = this.element.children[0], f = this.element.children[1], p = this.element.children[2];
1599
+ if (m.style.opacity = `${l}`, f.style.opacity = `${l / 2}`, p.style.opacity = `${l / 2}`, n || !d) {
1600
+ if (this.blur = Math.min(32, c), n && this.element.classList.add(
1601
+ this.lyricPlayer.style.classes.tmpDisableTransition
1602
+ ), this.lineTransforms.posX.setPosition(e), this.lineTransforms.posY.setPosition(t), this.lineTransforms.scale.setPosition(s), d)
1603
+ this.rebuildStyle();
1604
+ else {
1605
+ const y = this.isInSight;
1606
+ I || y ? this.show() : this.hide();
1607
+ }
1608
+ n && requestAnimationFrame(() => {
1609
+ this.element.classList.remove(
1610
+ this.lyricPlayer.style.classes.tmpDisableTransition
1611
+ );
1612
+ });
1613
+ } else
1614
+ this.lineTransforms.posX.setTargetPosition(e, h), this.lineTransforms.posY.setTargetPosition(t, h), this.lineTransforms.scale.setTargetPosition(s), this.blur !== Math.min(32, c) && (this.blur = Math.min(32, c), this.element.style.filter = `blur(${Math.min(32, c)}px)`);
1615
+ }
1616
+ update(e = 0) {
1617
+ this.lyricPlayer.getEnableSpring() && (this.lineTransforms.posX.update(e), this.lineTransforms.posY.update(e), this.lineTransforms.scale.update(e), this.isInSight ? this.show() : this.hide());
1618
+ }
1619
+ _getDebugTargetPos() {
1620
+ return `[位移: ${this.left}, ${this.top}; 缩放: ${this.scale}; 延时: ${this.delay}]`;
1621
+ }
1622
+ get isInSight() {
1623
+ const e = this.lineTransforms.posX.getCurrentPosition(), t = this.lineTransforms.posY.getCurrentPosition(), s = e + this.lineSize[0], l = t + this.lineSize[1], r = this.lyricPlayer.size[0], n = this.lyricPlayer.size[1];
1624
+ return !(e > r || s < 0 || t > n || l < 0);
1625
+ }
1626
+ dispose() {
1627
+ this.element.remove();
1628
+ }
1629
+ }
1630
+ const lt = pe(ge());
1631
+ class rt extends MouseEvent {
1632
+ constructor(i, e, t) {
1633
+ super(`line-${t.type}`, t), this.lineIndex = i, this.line = e;
1634
+ }
1635
+ }
1636
+ class gt extends EventTarget {
1637
+ constructor() {
1638
+ super();
1639
+ a(this, "element", document.createElement("div"));
1640
+ a(this, "currentTime", 0);
1641
+ a(this, "lyricLines", []);
1642
+ a(this, "processedLines", []);
1643
+ a(this, "lyricLinesEl", []);
1644
+ a(this, "lyricLinesSize", /* @__PURE__ */ new WeakMap());
1645
+ a(this, "lyricLinesIndexes", /* @__PURE__ */ new WeakMap());
1646
+ a(this, "hotLines", /* @__PURE__ */ new Set());
1647
+ a(this, "bufferedLines", /* @__PURE__ */ new Set());
1648
+ a(this, "scrollToIndex", 0);
1649
+ a(this, "allowScroll", !0);
1650
+ a(this, "scrolledHandler", 0);
1651
+ a(this, "isScrolled", !1);
1652
+ a(this, "invokedByScrollEvent", !1);
1653
+ a(this, "scrollOffset", 0);
1654
+ a(this, "hidePassedLines", !1);
1655
+ a(this, "resizeObserver", new ResizeObserver((e) => {
1656
+ const t = e[0].contentRect;
1657
+ this.size[0] = t.width, this.size[1] = t.height;
1658
+ const s = getComputedStyle(e[0].target), l = this.element.clientWidth - parseFloat(s.paddingLeft) - parseFloat(s.paddingRight), r = this.element.clientHeight - parseFloat(s.paddingTop) - parseFloat(s.paddingBottom);
1659
+ this.innerSize[0] = l, this.innerSize[1] = r, this.rebuildStyle(), this.calcLayout(!0, !0), this.lyricLinesEl.forEach((n) => n.updateMaskImage());
1660
+ }));
1661
+ a(this, "posXSpringParams", {
1662
+ mass: 1,
1663
+ damping: 10,
1664
+ stiffness: 100
1665
+ });
1666
+ a(this, "posYSpringParams", {
1667
+ mass: 1,
1668
+ damping: 16.5,
1669
+ stiffness: 100
1670
+ });
1671
+ a(this, "scaleSpringParams", {
1672
+ mass: 1,
1673
+ damping: 20,
1674
+ stiffness: 100
1675
+ });
1676
+ a(this, "emUnit", Math.max(Math.min(innerHeight * 0.05, innerWidth * 0.1), 12));
1677
+ a(this, "padding", this.emUnit);
1678
+ a(this, "enableBlur", !0);
1679
+ a(this, "enableScale", !0);
1680
+ a(this, "interludeDots");
1681
+ a(this, "interludeDotsSize", [0, 0]);
1682
+ a(this, "bottomLine");
1683
+ a(this, "supportPlusLighter", CSS.supports("mix-blend-mode", "plus-lighter"));
1684
+ a(this, "supportMaskImage", CSS.supports("mask-image", "none"));
1685
+ a(this, "disableSpring", !1);
1686
+ a(this, "alignAnchor", "center");
1687
+ a(this, "alignPosition", 0.5);
1688
+ a(this, "isNonDynamic", !1);
1689
+ a(this, "scrollBoundary", [0, 0]);
1690
+ a(this, "size", [0, 0]);
1691
+ a(this, "innerSize", [0, 0]);
1692
+ a(this, "onLineClickedHandler", (e) => {
1693
+ const t = new rt(
1694
+ this.lyricLinesIndexes.get(e.line) ?? -1,
1695
+ e.line,
1696
+ e
1697
+ );
1698
+ this.dispatchEvent(t) || (e.preventDefault(), e.stopPropagation(), e.stopImmediatePropagation());
1699
+ });
1700
+ a(this, "style", lt.createStyleSheet({
1701
+ lyricPlayer: {
1702
+ userSelect: "none",
1703
+ fontSize: "var(--amll-lyric-player-font-size,max(min(6vh, 8vw), 12px))",
1704
+ padding: "1em",
1705
+ margin: "-1em",
1706
+ width: "100%",
1707
+ height: "100%",
1708
+ overflow: "hidden",
1709
+ boxSizing: "content-box",
1710
+ maxWidth: "100%",
1711
+ maxHeight: "100%",
1712
+ zIndex: 1,
1713
+ color: "var(--amll-lyric-view-color,white)",
1714
+ mixBlendMode: "plus-lighter",
1715
+ contain: "strict",
1716
+ "&:hover": {
1717
+ "& $lyricLine": {
1718
+ filter: "unset !important"
1719
+ }
1720
+ }
1721
+ },
1722
+ lyricLine: {
1723
+ position: "absolute",
1724
+ backfaceVisibility: "hidden",
1725
+ transformOrigin: "left",
1726
+ width: "var(--amll-lyric-player-width,100%)",
1727
+ height: "fit-content",
1728
+ padding: "2vh 1.05em",
1729
+ margin: "0 -1em",
1730
+ contain: "content",
1731
+ willChange: "filter,transform,opacity",
1732
+ transition: "filter 0.25s, background-color 0.25s, box-shadow 0.25s",
1733
+ boxSizing: "content-box",
1734
+ borderRadius: "8px",
1735
+ "&:has(>*):hover": {
1736
+ backgroundColor: "var(--amll-lyric-view-hover-bg-color,#fff1)",
1737
+ boxShadow: "0 0 0 8px var(--amll-lyric-view-hover-bg-color,#fff1)"
1738
+ },
1739
+ "&:has(>*):active": {
1740
+ boxShadow: "0 0 0 4px var(--amll-lyric-view-hover-bg-color,#fff1)"
1741
+ }
1742
+ },
1743
+ "@media (max-width: 1024px)": {
1744
+ lyricLine: {
1745
+ padding: "1vh 1em"
1746
+ }
1747
+ },
1748
+ lyricDuetLine: {
1749
+ textAlign: "right",
1750
+ transformOrigin: "right"
1751
+ },
1752
+ lyricBgLine: {
1753
+ opacity: 0,
1754
+ fontSize: "max(50%, 10px)",
1755
+ transition: "opacity 0.25s",
1756
+ "&.active": {
1757
+ transition: "opacity 0.25s 0.25s",
1758
+ opacity: 0.4
1759
+ }
1760
+ },
1761
+ lyricMainLine: {
1762
+ transition: "opacity 0.3s 0.25s",
1763
+ willChange: "opacity",
1764
+ margin: "-1em",
1765
+ padding: "1em",
1766
+ "& span": {
1767
+ display: "inline-block"
1768
+ },
1769
+ "& > span, span.emphasize-wrapper": {
1770
+ whiteSpace: "pre-wrap",
1771
+ willChange: "transform,display,mask-image",
1772
+ display: "inline-block",
1773
+ "&.emphasize, span.emphasize": {
1774
+ padding: "1em",
1775
+ margin: "-1em",
1776
+ "& > span": {
1777
+ padding: "1em",
1778
+ margin: "-1em"
1779
+ }
1780
+ }
1781
+ }
1782
+ },
1783
+ lyricSubLine: {
1784
+ fontSize: "max(0.5em, 10px)",
1785
+ transition: "opacity 0.3s 0.25s",
1786
+ opacity: 0.3
1787
+ },
1788
+ disableSpring: {
1789
+ "& > *": {
1790
+ transition: "filter 0.25s, transform 0.5s, background-color 0.25s, box-shadow 0.25s"
1791
+ }
1792
+ },
1793
+ interludeDots: {
1794
+ height: "clamp(0.5em,1vh,3em)",
1795
+ transformOrigin: "center",
1796
+ width: "fit-content",
1797
+ padding: "2.5% 0",
1798
+ position: "absolute",
1799
+ display: "flex",
1800
+ gap: "0.25em",
1801
+ left: "1em",
1802
+ "& > *": {
1803
+ height: "clamp(0.5em,1vh,3em)",
1804
+ display: "inline-block",
1805
+ borderRadius: "50%",
1806
+ aspectRatio: "1 / 1",
1807
+ backgroundColor: "var(--amll-lyric-view-color,white)",
1808
+ marginRight: "4px"
1809
+ },
1810
+ "&.duet": {
1811
+ right: "1em",
1812
+ transformOrigin: "center"
1813
+ }
1814
+ },
1815
+ "@supports (mix-blend-mode: plus-lighter)": {
1816
+ lyricSubLine: {
1817
+ opacity: 0.3
1818
+ }
1819
+ },
1820
+ tmpDisableTransition: {
1821
+ transition: "none !important"
1822
+ }
1823
+ }));
1824
+ a(this, "_baseFontSize", parseFloat(getComputedStyle(this.element).fontSize));
1825
+ a(this, "isPageVisible", !0);
1826
+ a(this, "onPageShow", () => {
1827
+ this.isPageVisible = !0, this.setCurrentTime(this.currentTime, !0);
1828
+ });
1829
+ a(this, "onPageHide", () => {
1830
+ this.isPageVisible = !1;
1831
+ });
1832
+ this.interludeDots = new Ue(this), this.bottomLine = new Be(this), this.element.setAttribute("class", this.style.classes.lyricPlayer), this.disableSpring && this.element.classList.add(this.style.classes.disableSpring), this.rebuildStyle(), this.resizeObserver.observe(this.element), this.element.appendChild(this.interludeDots.getElement()), this.element.appendChild(this.bottomLine.getElement()), this.style.attach(), this.interludeDots.setTransform(0, 200), window.addEventListener("pageshow", this.onPageShow), window.addEventListener("pagehide", this.onPageHide);
1833
+ let e = 0, t = "none", s = 0, l = 0, r = 0, n = Symbol("amll-scroll"), h = 0, c = 0;
1834
+ this.element.addEventListener("touchstart", (I) => {
1835
+ this.beginScrollHandler() && (I.preventDefault(), e = this.scrollOffset, s = I.touches[0].screenY, h = s, l = Date.now(), r = 0);
1836
+ }), this.element.addEventListener("touchmove", (I) => {
1837
+ if (this.beginScrollHandler()) {
1838
+ I.preventDefault();
1839
+ const d = I.touches[0].screenY, m = d - s, f = d - h, p = f > 0 ? "down" : f < 0 ? "up" : "none";
1840
+ t !== p ? (t = p, e = this.scrollOffset, s = d, l = Date.now()) : this.scrollOffset = e - m, h = d, c = Date.now(), this.limitScrollOffset(), this.calcLayout(!0);
1841
+ }
1842
+ }), this.element.addEventListener("touchend", (I) => {
1843
+ if (this.beginScrollHandler()) {
1844
+ I.preventDefault(), s = 0;
1845
+ const d = Date.now();
1846
+ if (d - c > 100)
1847
+ return this.endScrollHandler();
1848
+ const m = d - l;
1849
+ r = (this.scrollOffset - e) / m * 1e3;
1850
+ let f = 0;
1851
+ const p = Symbol("amll-scroll");
1852
+ n = p;
1853
+ const y = (u) => {
1854
+ f || (f = u), n === p && this.beginScrollHandler() && (this.scrollOffset += r * (u - f) / 1e3, r *= 0.99, this.limitScrollOffset(), this.calcLayout(!0), Math.abs(r) > 1 && !this.scrollBoundary.includes(this.scrollOffset) && requestAnimationFrame(y), this.endScrollHandler(), f = u);
1855
+ };
1856
+ requestAnimationFrame(y), this.endScrollHandler();
1857
+ }
1858
+ }), this.element.addEventListener("wheel", (I) => {
1859
+ this.beginScrollHandler() && (I.deltaMode === I.DOM_DELTA_PIXEL ? (this.scrollOffset += I.deltaY, this.limitScrollOffset(), this.calcLayout(!0)) : (this.scrollOffset += I.deltaY * 50, this.limitScrollOffset(), this.calcLayout(!1)), this.endScrollHandler());
1860
+ });
1861
+ }
1862
+ _getIsNonDynamic() {
1863
+ return this.isNonDynamic;
1864
+ }
1865
+ /**
1866
+ * 设置是否使用物理弹簧算法实现歌词动画效果,默认启用
1867
+ *
1868
+ * 如果启用,则会通过弹簧算法实时处理歌词位置,但是需要性能足够强劲的电脑方可流畅运行
1869
+ *
1870
+ * 如果不启用,则会回退到基于 `transition` 的过渡效果,对低性能的机器比较友好,但是效果会比较单一
1871
+ */
1872
+ setEnableSpring(e = !0) {
1873
+ this.disableSpring = !e, e ? this.element.classList.remove(this.style.classes.disableSpring) : this.element.classList.add(this.style.classes.disableSpring), this.calcLayout(!0);
1874
+ }
1875
+ /**
1876
+ * 获取当前是否启用了物理弹簧
1877
+ * @returns 是否启用物理弹簧
1878
+ */
1879
+ getEnableSpring() {
1880
+ return !this.disableSpring;
1881
+ }
1882
+ /**
1883
+ * 是否启用歌词行缩放效果,默认启用
1884
+ *
1885
+ * 如果启用,非选中的歌词行会轻微缩小以凸显当前播放歌词行效果
1886
+ *
1887
+ * 此效果对性能影响微乎其微,推荐启用
1888
+ * @param enable 是否启用歌词行缩放效果
1889
+ */
1890
+ setEnableScale(e = !0) {
1891
+ this.enableScale = e, this.calcLayout();
1892
+ }
1893
+ /**
1894
+ * 获取当前是否启用了歌词行缩放效果
1895
+ * @returns 是否启用歌词行缩放效果
1896
+ */
1897
+ getEnableScale() {
1898
+ return this.enableScale;
1899
+ }
1900
+ get baseFontSize() {
1901
+ return this._baseFontSize;
1902
+ }
1903
+ beginScrollHandler() {
1904
+ const e = this.allowScroll;
1905
+ return e && (this.isScrolled = !0, this.invokedByScrollEvent = !0, clearTimeout(this.scrolledHandler), this.scrolledHandler = setTimeout(() => {
1906
+ this.isScrolled = !1, this.scrollOffset = 0;
1907
+ }, 5e3)), e;
1908
+ }
1909
+ endScrollHandler() {
1910
+ this.invokedByScrollEvent = !1;
1911
+ }
1912
+ limitScrollOffset() {
1913
+ this.scrollOffset = Math.max(
1914
+ Math.min(this.scrollBoundary[1], this.scrollOffset),
1915
+ this.scrollBoundary[0]
1916
+ );
1917
+ }
1918
+ /**
1919
+ * 获取当前播放时间里是否处于间奏区间
1920
+ * 如果是则会返回单位为毫秒的始末时间
1921
+ * 否则返回 undefined
1922
+ *
1923
+ * 这个只允许内部调用
1924
+ * @returns [开始时间,结束时间,大概处于的歌词行ID,下一句是否为对唱歌词] 或 undefined 如果不处于间奏区间
1925
+ */
1926
+ getCurrentInterlude() {
1927
+ var s, l, r;
1928
+ if (this.bufferedLines.size > 0)
1929
+ return;
1930
+ const e = this.currentTime + 20, t = this.scrollToIndex;
1931
+ if (t === 0) {
1932
+ if ((s = this.processedLines[0]) != null && s.startTime && this.processedLines[0].startTime > e)
1933
+ return [
1934
+ e,
1935
+ Math.max(e, this.processedLines[0].startTime - 250),
1936
+ -2,
1937
+ this.processedLines[0].isDuet
1938
+ ];
1939
+ } else if ((l = this.processedLines[t]) != null && l.endTime && ((r = this.processedLines[t + 1]) != null && r.startTime) && this.processedLines[t + 1].startTime > e && this.processedLines[t].endTime < e)
1940
+ return [
1941
+ Math.max(this.processedLines[t].endTime, e),
1942
+ this.processedLines[t + 1].startTime,
1943
+ t,
1944
+ this.processedLines[t + 1].isDuet
1945
+ ];
1946
+ }
1947
+ /**
1948
+ * 重建样式
1949
+ *
1950
+ * 这个只允许内部调用
1951
+ */
1952
+ rebuildStyle() {
1953
+ this._baseFontSize = parseFloat(getComputedStyle(this.element).fontSize);
1954
+ let e = "";
1955
+ e += "--amll-lyric-player-width:", e += this.innerSize[0] - this.padding * 2, e += "px;", e += "--amll-lyric-player-height:", e += this.innerSize[1] - this.padding * 2, e += "px;", this.element.setAttribute("style", e);
1956
+ }
1957
+ /**
1958
+ * 设置是否隐藏已经播放过的歌词行,默认不隐藏
1959
+ * @param hide 是否隐藏已经播放过的歌词行,默认不隐藏
1960
+ */
1961
+ setHidePassedLines(e) {
1962
+ this.hidePassedLines = e, this.calcLayout();
1963
+ }
1964
+ /**
1965
+ * 设置是否启用歌词行的模糊效果
1966
+ * @param enable 是否启用
1967
+ */
1968
+ setEnableBlur(e) {
1969
+ this.enableBlur !== e && (this.enableBlur = e, this.calcLayout());
1970
+ }
1971
+ /**
1972
+ * 设置当前播放歌词,要注意传入后这个数组内的信息不得修改,否则会发生错误
1973
+ * @param lines 歌词数组
1974
+ */
1975
+ setLyricLines(e) {
1976
+ for (const s of e)
1977
+ for (const l of s.words)
1978
+ l.word = l.word.replace(/\s+/g, " ");
1979
+ this.lyricLines = e;
1980
+ const t = 750;
1981
+ this.processedLines = e.filter(
1982
+ (s) => s.words.reduce((l, r) => l + r.word.trim().length, 0) > 0
1983
+ ).map((s, l, r) => {
1984
+ if (s.isBG)
1985
+ return {
1986
+ ...s
1987
+ };
1988
+ if (l === 0)
1989
+ return {
1990
+ ...s,
1991
+ startTime: Math.max(s.startTime - t, 0)
1992
+ };
1993
+ const n = r[l - 1], h = r[l - 2];
1994
+ if (n != null && n.isBG && h) {
1995
+ if (h.endTime < s.startTime)
1996
+ return {
1997
+ ...s,
1998
+ startTime: Math.max(h.endTime, s.startTime - t) || s.startTime
1999
+ };
2000
+ } else if (n != null && n.endTime && n.endTime < s.startTime)
2001
+ return {
2002
+ ...s,
2003
+ startTime: Math.max(n == null ? void 0 : n.endTime, s.startTime - t) || s.startTime
2004
+ };
2005
+ return {
2006
+ ...s
2007
+ };
2008
+ }), this.isNonDynamic = !0;
2009
+ for (const s of this.processedLines)
2010
+ if (s.words.length > 1) {
2011
+ this.isNonDynamic = !1;
2012
+ break;
2013
+ }
2014
+ this.processedLines.forEach((s, l, r) => {
2015
+ const n = r[l + 1], h = s.words[s.words.length - 1];
2016
+ h && k(h) && (n ? n.startTime > s.endTime && (s.endTime = Math.min(s.endTime + 1500, n.startTime)) : s.endTime = s.endTime + 1500);
2017
+ }), this.processedLines.forEach((s, l, r) => {
2018
+ if (s.isBG)
2019
+ return;
2020
+ const n = r[l + 1];
2021
+ n != null && n.isBG && (n.startTime = Math.min(n.startTime, s.startTime));
2022
+ }), this.lyricLinesEl.forEach((s) => {
2023
+ s.removeMouseEventListener("click", this.onLineClickedHandler), s.removeMouseEventListener("contextmenu", this.onLineClickedHandler), s.dispose();
2024
+ }), this.lyricLinesEl = this.processedLines.map((s) => {
2025
+ const l = new st(this, s);
2026
+ return l.addMouseEventListener("click", this.onLineClickedHandler), l.addMouseEventListener("contextmenu", this.onLineClickedHandler), l;
2027
+ }), this.lyricLinesEl.forEach((s, l) => {
2028
+ this.element.appendChild(s.getElement()), this.lyricLinesIndexes.set(s, l), s.updateMaskImage();
2029
+ }), this.interludeDots.setInterlude(void 0), this.hotLines.clear(), this.bufferedLines.clear(), this.setLinePosXSpringParams({}), this.setLinePosYSpringParams({}), this.setLineScaleSpringParams({}), this.setCurrentTime(0, !0), this.calcLayout(!0, !0);
2030
+ }
2031
+ /**
2032
+ * 重置用户滚动状态
2033
+ *
2034
+ * 请在用户完成滚动点击跳转歌词时调用本事件再调用 `calcLayout` 以正确滚动到目标位置
2035
+ */
2036
+ resetScroll() {
2037
+ this.isScrolled = !1, this.scrollOffset = 0, this.invokedByScrollEvent = !1, clearTimeout(this.scrolledHandler), this.scrolledHandler = 0;
2038
+ }
2039
+ /**
2040
+ * 重新布局定位歌词行的位置,调用完成后再逐帧调用 `update`
2041
+ * 函数即可让歌词通过动画移动到目标位置。
2042
+ *
2043
+ * 函数有一个 `force` 参数,用于指定是否强制修改布局,也就是不经过动画直接调整元素位置和大小。
2044
+ *
2045
+ * 此函数还有一个 `reflow` 参数,用于指定是否需要重新计算布局
2046
+ *
2047
+ * 因为计算布局必定会导致浏览器重排布局,所以会大幅度影响流畅度和性能,故请只在以下情况下将其​设置为 true:
2048
+ *
2049
+ * 1. 歌词页面大小发生改变时(这个组件会自行处理)
2050
+ * 2. 加载了新的歌词时(不论前后歌词是否完全一样)
2051
+ * 3. 用户自行跳转了歌曲播放位置(不论距离远近)
2052
+ *
2053
+ * @param force 是否不经过动画直接修改布局定位
2054
+ * @param reflow 是否进行重新布局(重新计算每行歌词大小)
2055
+ */
2056
+ calcLayout(e = !1, t = !1) {
2057
+ var y;
2058
+ t && (this.emUnit = parseFloat(getComputedStyle(this.element).fontSize), this.lyricLinesEl.forEach((u) => {
2059
+ const g = u.measureSize();
2060
+ this.lyricLinesSize.set(u, g), u.lineSize = g;
2061
+ }), this.interludeDotsSize[0] = this.interludeDots.getElement().clientWidth, this.interludeDotsSize[1] = this.interludeDots.getElement().clientHeight, this.bottomLine.lineSize = this.bottomLine.measureSize());
2062
+ const s = this.getCurrentInterlude();
2063
+ let l = -this.scrollOffset, r = this.scrollToIndex, n = 0;
2064
+ s ? (n = s[1] - s[0], n >= 5e3 && this.lyricLinesEl[s[2] + 1] && (r = s[2] + 1)) : this.interludeDots.setInterlude(void 0);
2065
+ const h = this.enableScale ? 0.95 : 1, c = this.lyricLinesEl.slice(0, r).reduce(
2066
+ (u, g) => {
2067
+ var E;
2068
+ return u + (g.getLine().isBG ? 0 : ((E = this.lyricLinesSize.get(g)) == null ? void 0 : E[1]) ?? 0);
2069
+ },
2070
+ 0
2071
+ );
2072
+ this.scrollBoundary[0] = -c, l -= c, l += this.size[1] * this.alignPosition;
2073
+ const I = this.lyricLinesEl[r];
2074
+ if (I) {
2075
+ const u = ((y = this.lyricLinesSize.get(I)) == null ? void 0 : y[1]) ?? 0;
2076
+ switch (this.alignAnchor) {
2077
+ case "bottom":
2078
+ l -= u;
2079
+ break;
2080
+ case "center":
2081
+ l -= u / 2;
2082
+ break;
2083
+ }
2084
+ }
2085
+ const d = Math.max(...this.bufferedLines);
2086
+ let m = 0, f = 0.05, p = !1;
2087
+ this.lyricLinesEl.forEach((u, g) => {
2088
+ var S, M, x;
2089
+ const E = this.bufferedLines.has(g), L = E || g >= this.scrollToIndex && g < d, w = u.getLine();
2090
+ w.isDuet && this.size[0] - (((S = this.lyricLinesSize.get(u)) == null ? void 0 : S[0]) ?? 0), !p && n >= 5e3 && (g === this.scrollToIndex && (s == null ? void 0 : s[2]) === -2 || g === this.scrollToIndex + 1) && (p = !0, this.interludeDots.setTransform(this.padding - 20, l + 10), s && this.interludeDots.setInterlude([s[0], s[1]]), l += this.interludeDotsSize[1] + 40);
2091
+ let T = 1;
2092
+ !L && g <= (s ? s[2] : this.scrollToIndex) ? this.hidePassedLines ? T = 0 : this.isNonDynamic ? T = 0.25 : T = 0.15 : E ? this.isNonDynamic ? T = 0.85 : T = 1 : this.isNonDynamic ? T = 0.25 : T = 0.5, this.invokedByScrollEvent && (this.isNonDynamic ? T = 0.85 : T = 1);
2093
+ let b = 0;
2094
+ this.enableBlur && (L ? b = 0 : (b = 1, g < this.scrollToIndex ? b += Math.abs(this.scrollToIndex - g) / 2 : b += Math.abs(
2095
+ g - Math.max(this.scrollToIndex, d)
2096
+ ))), this.invokedByScrollEvent && (b = 0), u.setTransform(
2097
+ this.padding,
2098
+ l,
2099
+ L ? 1 : h,
2100
+ T,
2101
+ b * 1.5,
2102
+ e,
2103
+ m
2104
+ ), w.isBG && L ? l += ((M = this.lyricLinesSize.get(u)) == null ? void 0 : M[1]) ?? 0 : w.isBG || (l += ((x = this.lyricLinesSize.get(u)) == null ? void 0 : x[1]) ?? 0), l >= 0 && (m += f, f /= 1.2);
2105
+ }), this.scrollBoundary[1] = l + this.scrollOffset - this.size[1] / 2, this.bottomLine.setTransform(this.padding, l, e, m);
2106
+ }
2107
+ /**
2108
+ * 获取当前歌词的播放位置
2109
+ *
2110
+ * 一般和最后调用 `setCurrentTime` 给予的参数一样
2111
+ * @returns 当前播放位置
2112
+ */
2113
+ getCurrentTime() {
2114
+ return this.currentTime;
2115
+ }
2116
+ /**
2117
+ * 获取当前歌词数组
2118
+ *
2119
+ * 一般和最后调用 `setLyricLines` 给予的参数一样
2120
+ * @returns 当前歌词数组
2121
+ */
2122
+ getLyricLines() {
2123
+ return this.lyricLines;
2124
+ }
2125
+ getElement() {
2126
+ return this.element;
2127
+ }
2128
+ /**
2129
+ * 获取一个特殊的底栏元素,默认是空白的,可以往内部添加任意元素
2130
+ *
2131
+ * 这个元素始终在歌词的底部,可以用于显示歌曲创作者等信息
2132
+ *
2133
+ * 但是请勿删除该元素,只能在内部存放元素
2134
+ *
2135
+ * @returns 一个元素,可以往内部添加任意元素
2136
+ */
2137
+ getBottomLineElement() {
2138
+ return this.bottomLine.getElement();
2139
+ }
2140
+ /**
2141
+ * 设置目标歌词行的对齐方式,默认为 `center`
2142
+ *
2143
+ * - 设置成 `top` 的话将会向目标歌词行的顶部对齐
2144
+ * - 设置成 `bottom` 的话将会向目标歌词行的底部对齐
2145
+ * - 设置成 `center` 的话将会向目标歌词行的垂直中心对齐
2146
+ * @param alignAnchor 歌词行对齐方式,详情见函数说明
2147
+ */
2148
+ setAlignAnchor(e) {
2149
+ this.alignAnchor = e;
2150
+ }
2151
+ /**
2152
+ * 设置默认的歌词行对齐位置,相对于整个歌词播放组件的大小位置,默认为 `0.5`
2153
+ * @param alignPosition 一个 `[0.0-1.0]` 之间的任意数字,代表组件高度由上到下的比例位置
2154
+ */
2155
+ setAlignPosition(e) {
2156
+ this.alignPosition = e;
2157
+ }
2158
+ /**
2159
+ * 设置当前播放进度,单位为毫秒且**必须是整数**,此时将会更新内部的歌词进度信息
2160
+ * 内部会根据调用间隔和播放进度自动决定如何滚动和显示歌词,所以这个的调用频率越快越准确越好
2161
+ *
2162
+ * 调用完成后,可以每帧调用 `update` 函数来执行歌词动画效果
2163
+ * @param time 当前播放进度,单位为毫秒
2164
+ */
2165
+ setCurrentTime(e, t = !1) {
2166
+ if (this.currentTime = e, !this.isPageVisible || (!this._getIsNonDynamic() && !this.supportMaskImage && this.element.style.setProperty("--amll-player-time", `${e}`), this.isScrolled))
2167
+ return;
2168
+ const s = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set();
2169
+ if (t)
2170
+ for (const n of this.lyricLinesEl)
2171
+ n.setMaskAnimationState(e);
2172
+ this.hotLines.forEach((n) => {
2173
+ const h = this.processedLines[n];
2174
+ if (h) {
2175
+ if (h.isBG)
2176
+ return;
2177
+ const c = this.processedLines[n + 1];
2178
+ if (c != null && c.isBG) {
2179
+ const I = this.processedLines[n + 2], d = Math.min(h.startTime, c == null ? void 0 : c.startTime), m = Math.min(
2180
+ Math.max(h.endTime, (I == null ? void 0 : I.startTime) ?? Number.MAX_VALUE),
2181
+ Math.max(h.endTime, c == null ? void 0 : c.endTime)
2182
+ );
2183
+ (d > e || m <= e) && (this.hotLines.delete(n), s.add(n), this.hotLines.delete(n + 1), s.add(n + 1), t && (this.lyricLinesEl[n].disable(e), this.lyricLinesEl[n + 1].disable(e)));
2184
+ } else
2185
+ (h.startTime > e || h.endTime <= e) && (this.hotLines.delete(n), s.add(n), t && this.lyricLinesEl[n].disable(e));
2186
+ } else
2187
+ this.hotLines.delete(n), s.add(n), t && this.lyricLinesEl[n].disable(e);
2188
+ }), this.processedLines.forEach((n, h, c) => {
2189
+ var I;
2190
+ !n.isBG && n.startTime <= e && n.endTime > e && (this.hotLines.has(h) || (this.hotLines.add(h), r.add(h), t && this.lyricLinesEl[h].enable(e), (I = c[h + 1]) != null && I.isBG && (this.hotLines.add(h + 1), r.add(h + 1), t && this.lyricLinesEl[h + 1].enable(e))));
2191
+ }), this.bufferedLines.forEach((n) => {
2192
+ this.hotLines.has(n) || (l.add(n), t && this.lyricLinesEl[n].disable(e));
2193
+ }), t ? (this.bufferedLines.size > 0 ? this.scrollToIndex = Math.min(...this.bufferedLines) : this.scrollToIndex = this.processedLines.findIndex(
2194
+ (n) => n.startTime >= e
2195
+ ), this.bufferedLines.clear(), this.hotLines.forEach((n) => this.bufferedLines.add(n)), this.calcLayout(!0)) : (l.size > 0 || r.size > 0) && (l.size === 0 && r.size > 0 ? (r.forEach((n) => {
2196
+ this.bufferedLines.add(n), this.lyricLinesEl[n].enable(e);
2197
+ }), this.scrollToIndex = Math.min(...this.bufferedLines), this.calcLayout()) : r.size === 0 && l.size > 0 ? Fe(l, this.bufferedLines) && (this.bufferedLines.forEach((n) => {
2198
+ this.hotLines.has(n) || (this.bufferedLines.delete(n), this.lyricLinesEl[n].disable(e));
2199
+ }), this.calcLayout()) : (r.forEach((n) => {
2200
+ this.bufferedLines.add(n), this.lyricLinesEl[n].enable(e);
2201
+ }), l.forEach((n) => {
2202
+ this.bufferedLines.delete(n), this.lyricLinesEl[n].disable(e);
2203
+ }), this.bufferedLines.size > 0 && (this.scrollToIndex = Math.min(...this.bufferedLines)), this.calcLayout()));
2204
+ }
2205
+ /**
2206
+ * 暂停部分效果演出,目前会暂停播放间奏点的动画
2207
+ */
2208
+ pause() {
2209
+ this.interludeDots.pause();
2210
+ for (const e of this.lyricLinesEl)
2211
+ e.pause();
2212
+ }
2213
+ /**
2214
+ * 恢复部分效果演出,目前会恢复播放间奏点的动画
2215
+ */
2216
+ resume() {
2217
+ this.interludeDots.resume();
2218
+ for (const e of this.lyricLinesEl)
2219
+ e.resume();
2220
+ }
2221
+ /**
2222
+ * 更新动画,这个函数应该被逐帧调用或者在以下情况下调用一次:
2223
+ *
2224
+ * 1. 刚刚调用完设置歌词函数的时候
2225
+ * @param delta 距离上一次被调用到现在的时长,单位为毫秒(可为浮点数)
2226
+ */
2227
+ update(e = 0) {
2228
+ if (!this.isPageVisible)
2229
+ return;
2230
+ const t = e / 1e3;
2231
+ this.interludeDots.update(e), this.bottomLine.update(t), this.lyricLinesEl.forEach((s) => s.update(t));
2232
+ }
2233
+ /**
2234
+ * 设置所有歌词行在横坐标上的弹簧属性,包括重量、弹力和阻力。
2235
+ *
2236
+ * @param params 需要设置的弹簧属性,提供的属性将会覆盖原来的属性,未提供的属性将会保持原样
2237
+ */
2238
+ setLinePosXSpringParams(e) {
2239
+ this.posXSpringParams = {
2240
+ ...this.posXSpringParams,
2241
+ ...e
2242
+ }, this.bottomLine.lineTransforms.posX.updateParams(this.posXSpringParams), this.lyricLinesEl.forEach(
2243
+ (t) => t.lineTransforms.posX.updateParams(this.posXSpringParams)
2244
+ );
2245
+ }
2246
+ /**
2247
+ * 设置所有歌词行在​纵坐标上的弹簧属性,包括重量、弹力和阻力。
2248
+ *
2249
+ * @param params 需要设置的弹簧属性,提供的属性将会覆盖原来的属性,未提供的属性将会保持原样
2250
+ */
2251
+ setLinePosYSpringParams(e) {
2252
+ this.posYSpringParams = {
2253
+ ...this.posYSpringParams,
2254
+ ...e
2255
+ }, this.bottomLine.lineTransforms.posY.updateParams(this.posYSpringParams), this.lyricLinesEl.forEach(
2256
+ (t) => t.lineTransforms.posY.updateParams(this.posYSpringParams)
2257
+ );
2258
+ }
2259
+ /**
2260
+ * 设置所有歌词行在​缩放大小上的弹簧属性,包括重量、弹力和阻力。
2261
+ *
2262
+ * @param params 需要设置的弹簧属性,提供的属性将会覆盖原来的属性,未提供的属性将会保持原样
2263
+ */
2264
+ setLineScaleSpringParams(e) {
2265
+ this.scaleSpringParams = {
2266
+ ...this.scaleSpringParams,
2267
+ ...e
2268
+ }, this.lyricLinesEl.forEach(
2269
+ (t) => t.lineTransforms.scale.updateParams(this.scaleSpringParams)
2270
+ );
2271
+ }
2272
+ dispose() {
2273
+ this.element.remove(), this.resizeObserver.disconnect(), this.style.detach(), this.lyricLinesEl.forEach((e) => e.dispose()), window.removeEventListener("pageshow", this.onPageShow), this.bottomLine.dispose(), this.interludeDots.dispose();
2274
+ }
2275
+ }
2276
+ export {
2277
+ ye as AbstractBaseRenderer,
2278
+ le as BackgroundRender,
2279
+ te as BaseRenderer,
2280
+ J as EplorRenderer,
2281
+ gt as LyricPlayer,
2282
+ pt as PixiRenderer
2283
+ };
2284
+ //# sourceMappingURL=amll-core.js.map