@applemusic-like-lyrics/core 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/amll-core.cjs +67 -63
- package/dist/amll-core.cjs.map +1 -1
- package/dist/amll-core.d.cts +15 -14
- package/dist/amll-core.d.mts +15 -14
- package/dist/amll-core.mjs +67 -63
- package/dist/amll-core.mjs.map +1 -1
- package/dist/style.css +45 -43
- package/package.json +3 -3
package/dist/amll-core.d.cts
CHANGED
|
@@ -882,13 +882,6 @@ interface RealWord extends LyricWord {
|
|
|
882
882
|
padding: number;
|
|
883
883
|
shouldEmphasize: boolean;
|
|
884
884
|
}
|
|
885
|
-
declare class RawLyricLineMouseEvent extends MouseEvent {
|
|
886
|
-
readonly line: LyricLineBase;
|
|
887
|
-
constructor(line: LyricLineBase, event: MouseEvent);
|
|
888
|
-
}
|
|
889
|
-
type MouseEventMap = { [evt in keyof HTMLElementEventMap]: HTMLElementEventMap[evt] extends MouseEvent ? evt : never };
|
|
890
|
-
type MouseEventTypes = MouseEventMap[keyof MouseEventMap];
|
|
891
|
-
type MouseEventListener = (this: LyricLineEl, ev: RawLyricLineMouseEvent) => void;
|
|
892
885
|
declare class LyricLineEl extends LyricLineBase {
|
|
893
886
|
private lyricPlayer;
|
|
894
887
|
private lyricLine;
|
|
@@ -906,10 +899,6 @@ declare class LyricLineEl extends LyricLineBase {
|
|
|
906
899
|
*/
|
|
907
900
|
private balancer?;
|
|
908
901
|
constructor(lyricPlayer: DomLyricPlayer, lyricLine?: LyricLine);
|
|
909
|
-
private listenersMap;
|
|
910
|
-
private readonly onMouseEvent;
|
|
911
|
-
addMouseEventListener(type: MouseEventTypes, callback: MouseEventListener | null, options?: boolean | AddEventListenerOptions | undefined): void;
|
|
912
|
-
removeMouseEventListener(type: MouseEventTypes, callback: MouseEventListener | null, options?: boolean | EventListenerOptions | undefined): void;
|
|
913
902
|
areWordsOnSameLine(word1: RealWord, word2: RealWord): boolean;
|
|
914
903
|
private isEnabled;
|
|
915
904
|
enable(maskAnimationTime?: number, shouldPlay?: boolean): Promise<void>;
|
|
@@ -941,6 +930,7 @@ declare class LyricLineEl extends LyricLineBase {
|
|
|
941
930
|
private applyAlphaToDom;
|
|
942
931
|
override setTransform(scale?: number, opacity?: number, blur?: number, force?: boolean, delay?: number, mode?: LyricLineRenderMode): void;
|
|
943
932
|
update(delta?: number): void;
|
|
933
|
+
/** @internal */
|
|
944
934
|
_getDebugTargetPos(): string;
|
|
945
935
|
teardownContent(): void;
|
|
946
936
|
private disposeElements;
|
|
@@ -965,7 +955,7 @@ declare class LyricLineGroup extends LyricLineGroupBase<LyricLineEl> {
|
|
|
965
955
|
//#endregion
|
|
966
956
|
//#region src/lyric-player/dom/index.d.ts
|
|
967
957
|
/**
|
|
968
|
-
*
|
|
958
|
+
* 歌词行鼠标相关事件,可以获取到歌词行的索引、主歌词行以及背景歌词行(如果有)元素
|
|
969
959
|
*/
|
|
970
960
|
declare class LyricLineMouseEvent extends MouseEvent {
|
|
971
961
|
/**
|
|
@@ -976,7 +966,17 @@ declare class LyricLineMouseEvent extends MouseEvent {
|
|
|
976
966
|
* 歌词行元素
|
|
977
967
|
*/
|
|
978
968
|
readonly line: LyricLineBase;
|
|
979
|
-
|
|
969
|
+
/**
|
|
970
|
+
* 背景人声歌词行元素 (如果存在)
|
|
971
|
+
*/
|
|
972
|
+
readonly bgLine: LyricLineBase | undefined;
|
|
973
|
+
/**
|
|
974
|
+
* 自定义标志位,用于记录外部是否调用了 `stopPropagation`
|
|
975
|
+
*/
|
|
976
|
+
isPropagationStopped: boolean;
|
|
977
|
+
constructor(lineIndex: number, line: LyricLineBase, bgLine: LyricLineBase | undefined, event: MouseEvent);
|
|
978
|
+
override stopPropagation(): void;
|
|
979
|
+
override stopImmediatePropagation(): void;
|
|
980
980
|
}
|
|
981
981
|
type LyricLineMouseEventListener = (evt: LyricLineMouseEvent) => void;
|
|
982
982
|
/**
|
|
@@ -985,12 +985,13 @@ type LyricLineMouseEventListener = (evt: LyricLineMouseEvent) => void;
|
|
|
985
985
|
* 尽可能贴切 Apple Music for iPad 的歌词效果设计,且做了力所能及的优化措施
|
|
986
986
|
*/
|
|
987
987
|
declare class DomLyricPlayer extends LyricPlayerBase {
|
|
988
|
+
private abortController;
|
|
988
989
|
override currentLyricGroups: LyricLineGroup[];
|
|
989
990
|
override onResize(): void;
|
|
990
991
|
readonly supportPlusLighter: boolean;
|
|
991
992
|
readonly supportMaskImage: boolean;
|
|
992
993
|
readonly innerSize: [number, number];
|
|
993
|
-
private readonly
|
|
994
|
+
private readonly onMouseEventHandler;
|
|
994
995
|
/**
|
|
995
996
|
* 是否为非逐词歌词
|
|
996
997
|
* @internal
|
package/dist/amll-core.d.mts
CHANGED
|
@@ -882,13 +882,6 @@ interface RealWord extends LyricWord {
|
|
|
882
882
|
padding: number;
|
|
883
883
|
shouldEmphasize: boolean;
|
|
884
884
|
}
|
|
885
|
-
declare class RawLyricLineMouseEvent extends MouseEvent {
|
|
886
|
-
readonly line: LyricLineBase;
|
|
887
|
-
constructor(line: LyricLineBase, event: MouseEvent);
|
|
888
|
-
}
|
|
889
|
-
type MouseEventMap = { [evt in keyof HTMLElementEventMap]: HTMLElementEventMap[evt] extends MouseEvent ? evt : never };
|
|
890
|
-
type MouseEventTypes = MouseEventMap[keyof MouseEventMap];
|
|
891
|
-
type MouseEventListener = (this: LyricLineEl, ev: RawLyricLineMouseEvent) => void;
|
|
892
885
|
declare class LyricLineEl extends LyricLineBase {
|
|
893
886
|
private lyricPlayer;
|
|
894
887
|
private lyricLine;
|
|
@@ -906,10 +899,6 @@ declare class LyricLineEl extends LyricLineBase {
|
|
|
906
899
|
*/
|
|
907
900
|
private balancer?;
|
|
908
901
|
constructor(lyricPlayer: DomLyricPlayer, lyricLine?: LyricLine);
|
|
909
|
-
private listenersMap;
|
|
910
|
-
private readonly onMouseEvent;
|
|
911
|
-
addMouseEventListener(type: MouseEventTypes, callback: MouseEventListener | null, options?: boolean | AddEventListenerOptions | undefined): void;
|
|
912
|
-
removeMouseEventListener(type: MouseEventTypes, callback: MouseEventListener | null, options?: boolean | EventListenerOptions | undefined): void;
|
|
913
902
|
areWordsOnSameLine(word1: RealWord, word2: RealWord): boolean;
|
|
914
903
|
private isEnabled;
|
|
915
904
|
enable(maskAnimationTime?: number, shouldPlay?: boolean): Promise<void>;
|
|
@@ -941,6 +930,7 @@ declare class LyricLineEl extends LyricLineBase {
|
|
|
941
930
|
private applyAlphaToDom;
|
|
942
931
|
override setTransform(scale?: number, opacity?: number, blur?: number, force?: boolean, delay?: number, mode?: LyricLineRenderMode): void;
|
|
943
932
|
update(delta?: number): void;
|
|
933
|
+
/** @internal */
|
|
944
934
|
_getDebugTargetPos(): string;
|
|
945
935
|
teardownContent(): void;
|
|
946
936
|
private disposeElements;
|
|
@@ -965,7 +955,7 @@ declare class LyricLineGroup extends LyricLineGroupBase<LyricLineEl> {
|
|
|
965
955
|
//#endregion
|
|
966
956
|
//#region src/lyric-player/dom/index.d.ts
|
|
967
957
|
/**
|
|
968
|
-
*
|
|
958
|
+
* 歌词行鼠标相关事件,可以获取到歌词行的索引、主歌词行以及背景歌词行(如果有)元素
|
|
969
959
|
*/
|
|
970
960
|
declare class LyricLineMouseEvent extends MouseEvent {
|
|
971
961
|
/**
|
|
@@ -976,7 +966,17 @@ declare class LyricLineMouseEvent extends MouseEvent {
|
|
|
976
966
|
* 歌词行元素
|
|
977
967
|
*/
|
|
978
968
|
readonly line: LyricLineBase;
|
|
979
|
-
|
|
969
|
+
/**
|
|
970
|
+
* 背景人声歌词行元素 (如果存在)
|
|
971
|
+
*/
|
|
972
|
+
readonly bgLine: LyricLineBase | undefined;
|
|
973
|
+
/**
|
|
974
|
+
* 自定义标志位,用于记录外部是否调用了 `stopPropagation`
|
|
975
|
+
*/
|
|
976
|
+
isPropagationStopped: boolean;
|
|
977
|
+
constructor(lineIndex: number, line: LyricLineBase, bgLine: LyricLineBase | undefined, event: MouseEvent);
|
|
978
|
+
override stopPropagation(): void;
|
|
979
|
+
override stopImmediatePropagation(): void;
|
|
980
980
|
}
|
|
981
981
|
type LyricLineMouseEventListener = (evt: LyricLineMouseEvent) => void;
|
|
982
982
|
/**
|
|
@@ -985,12 +985,13 @@ type LyricLineMouseEventListener = (evt: LyricLineMouseEvent) => void;
|
|
|
985
985
|
* 尽可能贴切 Apple Music for iPad 的歌词效果设计,且做了力所能及的优化措施
|
|
986
986
|
*/
|
|
987
987
|
declare class DomLyricPlayer extends LyricPlayerBase {
|
|
988
|
+
private abortController;
|
|
988
989
|
override currentLyricGroups: LyricLineGroup[];
|
|
989
990
|
override onResize(): void;
|
|
990
991
|
readonly supportPlusLighter: boolean;
|
|
991
992
|
readonly supportMaskImage: boolean;
|
|
992
993
|
readonly innerSize: [number, number];
|
|
993
|
-
private readonly
|
|
994
|
+
private readonly onMouseEventHandler;
|
|
994
995
|
/**
|
|
995
996
|
* 是否为非逐词歌词
|
|
996
997
|
* @internal
|
package/dist/amll-core.mjs
CHANGED
|
@@ -14,6 +14,7 @@ function clamp1(x) {
|
|
|
14
14
|
return Math.max(1, x);
|
|
15
15
|
}
|
|
16
16
|
var BaseRenderer = class extends AbstractBaseRenderer {
|
|
17
|
+
canvas;
|
|
17
18
|
observer;
|
|
18
19
|
flowSpeed = 1;
|
|
19
20
|
currerntRenderScale = .75;
|
|
@@ -538,10 +539,10 @@ function generateControlPoints(width, height, variationFraction = randomRange(.4
|
|
|
538
539
|
}
|
|
539
540
|
//#endregion
|
|
540
541
|
//#region \0raw:/home/runner/work/applemusic-like-lyrics/applemusic-like-lyrics/packages/core/src/bg-render/mesh-renderer/mesh.frag.glsl
|
|
541
|
-
var mesh_frag_default = "precision
|
|
542
|
+
var mesh_frag_default = "precision mediump float;\n\nvarying vec3 v_color;\nvarying vec2 v_uv;\nuniform sampler2D u_texture;\nuniform float u_volume;\nuniform float u_alpha;\nuniform float u_sinAngle;\nuniform float u_cosAngle;\n\n// 预计算常量\nconst float INV_255 = 1.0 / 255.0;\nconst float HALF_INV_255 = 0.5 / 255.0;\nconst float GRADIENT_NOISE_A = 52.9829189;\nconst vec2 GRADIENT_NOISE_B = vec2(0.06711056, 0.00583715);\n\nfloat gradientNoise(in vec2 uv) {\n return fract(GRADIENT_NOISE_A * fract(dot(uv, GRADIENT_NOISE_B)));\n}\n\nvoid main() {\n float volumeEffect = u_volume * 2.0;\n\n float dither = INV_255 * gradientNoise(gl_FragCoord.xy) - HALF_INV_255;\n\n vec2 centeredUV = v_uv - vec2(0.2);\n\n vec2 rotatedUV = vec2(\n u_cosAngle * centeredUV.x - u_sinAngle * centeredUV.y,\n u_sinAngle * centeredUV.x + u_cosAngle * centeredUV.y\n );\n\n vec2 finalUV = rotatedUV * max(0.001, 1.0 - volumeEffect) + vec2(0.5);\n \n vec4 result = texture2D(u_texture, finalUV);\n \n float alphaVolumeFactor = u_alpha * max(0.5, 1.0 - u_volume * 0.5);\n result.rgb *= v_color * alphaVolumeFactor;\n result.a *= alphaVolumeFactor;\n \n result.rgb += vec3(dither);\n \n float dist = distance(v_uv, vec2(0.5));\n float vignette = smoothstep(0.8, 0.3, dist);\n float mask = 0.6 + vignette * 0.4;\n result.rgb *= mask;\n \n gl_FragColor = result;\n}\n";
|
|
542
543
|
//#endregion
|
|
543
544
|
//#region \0raw:/home/runner/work/applemusic-like-lyrics/applemusic-like-lyrics/packages/core/src/bg-render/mesh-renderer/mesh.vert.glsl
|
|
544
|
-
var mesh_vert_default = "precision
|
|
545
|
+
var mesh_vert_default = "precision mediump float;\n\nattribute vec2 a_pos;\nattribute vec3 a_color;\nattribute vec2 a_uv;\nvarying vec3 v_color;\nvarying vec2 v_uv;\n\nuniform float u_aspect;\n\nvoid main() {\n v_color = a_color;\n v_uv = a_uv;\n vec2 pos = a_pos;\n if (u_aspect > 1.0) {\n pos.y *= u_aspect;\n } else {\n pos.x /= u_aspect;\n }\n gl_Position = vec4(pos, 0.0, 1.0);\n}\n";
|
|
545
546
|
//#endregion
|
|
546
547
|
//#region src/bg-render/mesh-renderer/index.ts
|
|
547
548
|
/**
|
|
@@ -572,6 +573,7 @@ function easeInOutSine(x) {
|
|
|
572
573
|
return -(Math.cos(Math.PI * x) - 1) / 2;
|
|
573
574
|
}
|
|
574
575
|
var GLProgram = class {
|
|
576
|
+
label;
|
|
575
577
|
gl;
|
|
576
578
|
program;
|
|
577
579
|
vertexShader;
|
|
@@ -653,6 +655,10 @@ var GLProgram = class {
|
|
|
653
655
|
}
|
|
654
656
|
};
|
|
655
657
|
var Mesh = class {
|
|
658
|
+
gl;
|
|
659
|
+
attrPos;
|
|
660
|
+
attrColor;
|
|
661
|
+
attrUV;
|
|
656
662
|
vertexWidth = 0;
|
|
657
663
|
vertexHeight = 0;
|
|
658
664
|
vertexBuffer;
|
|
@@ -1075,6 +1081,7 @@ var BHPMesh = class extends Mesh {
|
|
|
1075
1081
|
}
|
|
1076
1082
|
};
|
|
1077
1083
|
var GLTexture = class {
|
|
1084
|
+
gl;
|
|
1078
1085
|
tex;
|
|
1079
1086
|
constructor(gl, albumImageData) {
|
|
1080
1087
|
this.gl = gl;
|
|
@@ -1240,11 +1247,14 @@ var MeshGradientRenderer = class extends BaseRenderer {
|
|
|
1240
1247
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
1241
1248
|
this.mainProgram.use();
|
|
1242
1249
|
gl.activeTexture(gl.TEXTURE0);
|
|
1243
|
-
|
|
1250
|
+
const uTime = tickTime / 1e4;
|
|
1244
1251
|
this.mainProgram.setUniform1f("u_aspect", this.manualControl ? 1 : this.canvas.width / this.canvas.height);
|
|
1245
1252
|
this.mainProgram.setUniform1i("u_texture", 0);
|
|
1246
1253
|
this.mainProgram.setUniform1f("u_volume", this.volume);
|
|
1247
1254
|
this.mainProgram.setUniform1f("u_alpha", 1);
|
|
1255
|
+
const angle = (uTime + this.volume) * 2;
|
|
1256
|
+
this.mainProgram.setUniform1f("u_sinAngle", Math.sin(angle));
|
|
1257
|
+
this.mainProgram.setUniform1f("u_cosAngle", Math.cos(angle));
|
|
1248
1258
|
state.texture.bind();
|
|
1249
1259
|
state.mesh.bind();
|
|
1250
1260
|
state.mesh.draw();
|
|
@@ -1482,6 +1492,7 @@ var TimedContainer = class extends Container {
|
|
|
1482
1492
|
time = 0;
|
|
1483
1493
|
};
|
|
1484
1494
|
var PixiRenderer = class extends BaseRenderer {
|
|
1495
|
+
canvas;
|
|
1485
1496
|
app;
|
|
1486
1497
|
curContainer;
|
|
1487
1498
|
staticMode = false;
|
|
@@ -1711,7 +1722,6 @@ var lyric_player_module_default = {
|
|
|
1711
1722
|
"bgWrapperHidden": "FmKaba_bgWrapperHidden",
|
|
1712
1723
|
"bgWrapperTop": "FmKaba_bgWrapperTop",
|
|
1713
1724
|
"bottomLine": "FmKaba_bottomLine",
|
|
1714
|
-
"dirty": "FmKaba_dirty",
|
|
1715
1725
|
"disableSpring": "FmKaba_disableSpring",
|
|
1716
1726
|
"duet": "FmKaba_duet",
|
|
1717
1727
|
"emphasize": "FmKaba_emphasize",
|
|
@@ -2149,6 +2159,7 @@ function solveSpring(from, velocity, to, delay = 0, params) {
|
|
|
2149
2159
|
//#endregion
|
|
2150
2160
|
//#region src/lyric-player/base/bottom-line.ts
|
|
2151
2161
|
var BottomLineEl = class {
|
|
2162
|
+
lyricPlayer;
|
|
2152
2163
|
element = document.createElement("div");
|
|
2153
2164
|
left = 0;
|
|
2154
2165
|
top = 0;
|
|
@@ -3251,6 +3262,8 @@ var LyricPlayerBase = class extends EventTarget {
|
|
|
3251
3262
|
//#endregion
|
|
3252
3263
|
//#region src/lyric-player/base/group.ts
|
|
3253
3264
|
var LyricLineGroupBase = class {
|
|
3265
|
+
mainLine;
|
|
3266
|
+
bgLine;
|
|
3254
3267
|
posY = new Spring(0);
|
|
3255
3268
|
bgSlideY = new Spring(-80);
|
|
3256
3269
|
top = 0;
|
|
@@ -3334,6 +3347,7 @@ var LyricLineGroupBase = class {
|
|
|
3334
3347
|
//#endregion
|
|
3335
3348
|
//#region src/lyric-player/dom/lyric-group.ts
|
|
3336
3349
|
var LyricLineGroup = class extends LyricLineGroupBase {
|
|
3350
|
+
lyricPlayer;
|
|
3337
3351
|
element;
|
|
3338
3352
|
bgWrapper;
|
|
3339
3353
|
lastIsActive;
|
|
@@ -3583,6 +3597,7 @@ function getMeasurementContext() {
|
|
|
3583
3597
|
* 用于平衡歌词行在换行后的各行长度
|
|
3584
3598
|
*/
|
|
3585
3599
|
var LineBalancer = class {
|
|
3600
|
+
mainElement;
|
|
3586
3601
|
isBalancing = false;
|
|
3587
3602
|
lastBalancedContainerWidth = -1;
|
|
3588
3603
|
constructor(mainElement) {
|
|
@@ -3906,13 +3921,9 @@ function generateFadeGradient(width, padding = 0, bright = "rgba(0,0,0,var(--bri
|
|
|
3906
3921
|
const leftPos = (1 - widthInTotal) / 2;
|
|
3907
3922
|
return [`linear-gradient(to right,${bright} ${leftPos * 100}%,${dark} ${(leftPos + widthInTotal) * 100}%)`, totalAspect];
|
|
3908
3923
|
}
|
|
3909
|
-
var RawLyricLineMouseEvent = class extends MouseEvent {
|
|
3910
|
-
constructor(line, event) {
|
|
3911
|
-
super(event.type, event);
|
|
3912
|
-
this.line = line;
|
|
3913
|
-
}
|
|
3914
|
-
};
|
|
3915
3924
|
var LyricLineEl = class extends LyricLineBase {
|
|
3925
|
+
lyricPlayer;
|
|
3926
|
+
lyricLine;
|
|
3916
3927
|
element = document.createElement("div");
|
|
3917
3928
|
splittedWords = [];
|
|
3918
3929
|
built = false;
|
|
@@ -3953,33 +3964,6 @@ var LyricLineEl = class extends LyricLineBase {
|
|
|
3953
3964
|
if (LyricLineBase.wordSegmenter) this.balancer = new LineBalancer(main);
|
|
3954
3965
|
this.rebuildStyle();
|
|
3955
3966
|
}
|
|
3956
|
-
listenersMap = /* @__PURE__ */ new Map();
|
|
3957
|
-
onMouseEvent = (e) => {
|
|
3958
|
-
const wrapped = new RawLyricLineMouseEvent(this, e);
|
|
3959
|
-
for (const listener of this.listenersMap.get(e.type) ?? []) listener.call(this, wrapped);
|
|
3960
|
-
if (!this.dispatchEvent(wrapped) || wrapped.defaultPrevented) {
|
|
3961
|
-
e.preventDefault();
|
|
3962
|
-
e.stopPropagation();
|
|
3963
|
-
e.stopImmediatePropagation();
|
|
3964
|
-
}
|
|
3965
|
-
};
|
|
3966
|
-
addMouseEventListener(type, callback, options) {
|
|
3967
|
-
if (callback) {
|
|
3968
|
-
const listeners = this.listenersMap.get(type) ?? /* @__PURE__ */ new Set();
|
|
3969
|
-
if (listeners.size === 0) this.element.addEventListener(type, this.onMouseEvent, options);
|
|
3970
|
-
listeners.add(callback);
|
|
3971
|
-
this.listenersMap.set(type, listeners);
|
|
3972
|
-
}
|
|
3973
|
-
}
|
|
3974
|
-
removeMouseEventListener(type, callback, options) {
|
|
3975
|
-
if (callback) {
|
|
3976
|
-
const listeners = this.listenersMap.get(type);
|
|
3977
|
-
if (listeners) {
|
|
3978
|
-
listeners.delete(callback);
|
|
3979
|
-
if (listeners.size === 0) this.element.removeEventListener(type, this.onMouseEvent, options);
|
|
3980
|
-
}
|
|
3981
|
-
}
|
|
3982
|
-
}
|
|
3983
3967
|
areWordsOnSameLine(word1, word2) {
|
|
3984
3968
|
if (word1?.mainElement && word2?.mainElement) {
|
|
3985
3969
|
const word1el = word1.mainElement;
|
|
@@ -4096,7 +4080,7 @@ var LyricLineEl = class extends LyricLineBase {
|
|
|
4096
4080
|
const trans = this.element.children[1];
|
|
4097
4081
|
const roman = this.element.children[2];
|
|
4098
4082
|
if (this.lyricPlayer._getIsNonDynamic()) {
|
|
4099
|
-
main.
|
|
4083
|
+
main.textContent = this.lyricLine.words.map((w) => this.lyricPlayer.processObsceneWord(w)).join("");
|
|
4100
4084
|
this.setSubLinesText(trans, roman);
|
|
4101
4085
|
return;
|
|
4102
4086
|
}
|
|
@@ -4109,8 +4093,8 @@ var LyricLineEl = class extends LyricLineBase {
|
|
|
4109
4093
|
}
|
|
4110
4094
|
/** 设置翻译与音译行文本 */
|
|
4111
4095
|
setSubLinesText(trans, roman) {
|
|
4112
|
-
trans.
|
|
4113
|
-
roman.
|
|
4096
|
+
trans.textContent = this.lyricLine.translatedLyric;
|
|
4097
|
+
roman.textContent = this.lyricLine.romanLyric;
|
|
4114
4098
|
}
|
|
4115
4099
|
getRubyCharCount(word) {
|
|
4116
4100
|
return (word.ruby ?? []).reduce((total, ruby) => total + ruby.word.length, 0);
|
|
@@ -4128,7 +4112,7 @@ var LyricLineEl = class extends LyricLineBase {
|
|
|
4128
4112
|
const rubySegments = this.getRubySegments(word);
|
|
4129
4113
|
for (const ruby of rubySegments) {
|
|
4130
4114
|
const rubyPartEl = document.createElement("span");
|
|
4131
|
-
rubyPartEl.
|
|
4115
|
+
rubyPartEl.textContent = ruby.word;
|
|
4132
4116
|
rubyPartEl.dataset.startTime = String(ruby.startTime);
|
|
4133
4117
|
rubyPartEl.dataset.endTime = String(ruby.endTime);
|
|
4134
4118
|
rubyWordEl.appendChild(rubyPartEl);
|
|
@@ -4145,24 +4129,24 @@ var LyricLineEl = class extends LyricLineBase {
|
|
|
4145
4129
|
const trimmedWord = displayWord.trim();
|
|
4146
4130
|
if (LyricLineBase.graphemeSegmenter) for (const { segment } of LyricLineBase.graphemeSegmenter.segment(trimmedWord)) {
|
|
4147
4131
|
const charEl = document.createElement("span");
|
|
4148
|
-
charEl.
|
|
4132
|
+
charEl.textContent = segment;
|
|
4149
4133
|
subElements.push(charEl);
|
|
4150
4134
|
wordContainer.appendChild(charEl);
|
|
4151
4135
|
}
|
|
4152
4136
|
else for (const segment of Array.from(trimmedWord)) {
|
|
4153
4137
|
const charEl = document.createElement("span");
|
|
4154
|
-
charEl.
|
|
4138
|
+
charEl.textContent = segment;
|
|
4155
4139
|
subElements.push(charEl);
|
|
4156
4140
|
wordContainer.appendChild(charEl);
|
|
4157
4141
|
}
|
|
4158
4142
|
} else if (hasRomanLine) {
|
|
4159
4143
|
const wordEl = document.createElement("div");
|
|
4160
|
-
wordEl.
|
|
4144
|
+
wordEl.textContent = displayWord.trim();
|
|
4161
4145
|
wordContainer.appendChild(wordEl);
|
|
4162
|
-
} else if (romanWord.length === 0) wordContainer.
|
|
4146
|
+
} else if (romanWord.length === 0) wordContainer.textContent = displayWord.trim();
|
|
4163
4147
|
if (hasRomanLine) {
|
|
4164
4148
|
const romanWordEl = document.createElement("div");
|
|
4165
|
-
romanWordEl.
|
|
4149
|
+
romanWordEl.textContent = romanWord.length > 0 ? romanWord : "\xA0";
|
|
4166
4150
|
romanWordEl.classList.add(lyric_player_module_default.romanWord);
|
|
4167
4151
|
wordContainer.appendChild(romanWordEl);
|
|
4168
4152
|
}
|
|
@@ -4276,7 +4260,7 @@ var LyricLineEl = class extends LyricLineBase {
|
|
|
4276
4260
|
const glow = el.animate(frames, {
|
|
4277
4261
|
duration: animateDu,
|
|
4278
4262
|
delay: Number.isFinite(wordDe) ? wordDe : 0,
|
|
4279
|
-
id: `emphasize-word-${el.
|
|
4263
|
+
id: `emphasize-word-${el.textContent}-${i}`,
|
|
4280
4264
|
iterations: 1,
|
|
4281
4265
|
composite: "replace",
|
|
4282
4266
|
fill: "both"
|
|
@@ -4562,6 +4546,7 @@ var LyricLineEl = class extends LyricLineBase {
|
|
|
4562
4546
|
this.updateMaskAlphaTargets(currentScale);
|
|
4563
4547
|
this.applyAlphaToDom(delta);
|
|
4564
4548
|
}
|
|
4549
|
+
/** @internal */
|
|
4565
4550
|
_getDebugTargetPos() {
|
|
4566
4551
|
return `[位移: ${this.top}; 缩放: ${this.scale}; 延时: ${this.delay}]`;
|
|
4567
4552
|
}
|
|
@@ -4602,13 +4587,29 @@ var LyricLineEl = class extends LyricLineBase {
|
|
|
4602
4587
|
//#endregion
|
|
4603
4588
|
//#region src/lyric-player/dom/index.ts
|
|
4604
4589
|
/**
|
|
4605
|
-
*
|
|
4590
|
+
* 歌词行鼠标相关事件,可以获取到歌词行的索引、主歌词行以及背景歌词行(如果有)元素
|
|
4606
4591
|
*/
|
|
4607
4592
|
var LyricLineMouseEvent = class extends MouseEvent {
|
|
4608
|
-
|
|
4593
|
+
lineIndex;
|
|
4594
|
+
line;
|
|
4595
|
+
bgLine;
|
|
4596
|
+
/**
|
|
4597
|
+
* 自定义标志位,用于记录外部是否调用了 `stopPropagation`
|
|
4598
|
+
*/
|
|
4599
|
+
isPropagationStopped = false;
|
|
4600
|
+
constructor(lineIndex, line, bgLine, event) {
|
|
4609
4601
|
super(`line-${event.type}`, event);
|
|
4610
4602
|
this.lineIndex = lineIndex;
|
|
4611
4603
|
this.line = line;
|
|
4604
|
+
this.bgLine = bgLine;
|
|
4605
|
+
}
|
|
4606
|
+
stopPropagation() {
|
|
4607
|
+
this.isPropagationStopped = true;
|
|
4608
|
+
super.stopPropagation();
|
|
4609
|
+
}
|
|
4610
|
+
stopImmediatePropagation() {
|
|
4611
|
+
this.isPropagationStopped = true;
|
|
4612
|
+
super.stopImmediatePropagation();
|
|
4612
4613
|
}
|
|
4613
4614
|
};
|
|
4614
4615
|
/**
|
|
@@ -4617,6 +4618,7 @@ var LyricLineMouseEvent = class extends MouseEvent {
|
|
|
4617
4618
|
* 尽可能贴切 Apple Music for iPad 的歌词效果设计,且做了力所能及的优化措施
|
|
4618
4619
|
*/
|
|
4619
4620
|
var DomLyricPlayer = class extends LyricPlayerBase {
|
|
4621
|
+
abortController = new AbortController();
|
|
4620
4622
|
currentLyricGroups = [];
|
|
4621
4623
|
onResize() {
|
|
4622
4624
|
const computedStyles = getComputedStyle(this.element);
|
|
@@ -4626,10 +4628,18 @@ var DomLyricPlayer = class extends LyricPlayerBase {
|
|
|
4626
4628
|
supportPlusLighter = CSS.supports("mix-blend-mode", "plus-lighter");
|
|
4627
4629
|
supportMaskImage = CSS.supports("mask-image", "none");
|
|
4628
4630
|
innerSize = [0, 0];
|
|
4629
|
-
|
|
4630
|
-
const
|
|
4631
|
-
if (!
|
|
4632
|
-
|
|
4631
|
+
onMouseEventHandler = (e) => {
|
|
4632
|
+
const target = e.target;
|
|
4633
|
+
if (!(target instanceof Element)) return;
|
|
4634
|
+
const groupEl = target.closest(`.${lyric_player_module_default.lyricLineWrapper}`);
|
|
4635
|
+
if (!groupEl) return;
|
|
4636
|
+
const group = this.lyricGroupElementMap.get(groupEl);
|
|
4637
|
+
if (!group) return;
|
|
4638
|
+
const mainLine = group.mainLine;
|
|
4639
|
+
const bgLine = group.bgLine;
|
|
4640
|
+
const evt = new LyricLineMouseEvent(this.lyricLinesIndexes.get(mainLine) ?? -1, mainLine, bgLine, e);
|
|
4641
|
+
if (!this.dispatchEvent(evt) || evt.defaultPrevented) e.preventDefault();
|
|
4642
|
+
if (evt.isPropagationStopped) {
|
|
4633
4643
|
e.stopPropagation();
|
|
4634
4644
|
e.stopImmediatePropagation();
|
|
4635
4645
|
}
|
|
@@ -4650,6 +4660,8 @@ var DomLyricPlayer = class extends LyricPlayerBase {
|
|
|
4650
4660
|
this.onResize();
|
|
4651
4661
|
this.element.classList.add("amll-lyric-player", "dom");
|
|
4652
4662
|
if (this.disableSpring) this.element.classList.add(lyric_player_module_default.disableSpring);
|
|
4663
|
+
this.element.addEventListener("click", this.onMouseEventHandler, { signal: this.abortController.signal });
|
|
4664
|
+
this.element.addEventListener("contextmenu", this.onMouseEventHandler, { signal: this.abortController.signal });
|
|
4653
4665
|
}
|
|
4654
4666
|
rebuildStyle() {}
|
|
4655
4667
|
setWordFadeWidth(value = .5) {
|
|
@@ -4669,21 +4681,12 @@ var DomLyricPlayer = class extends LyricPlayerBase {
|
|
|
4669
4681
|
if (this.hasDuetLine) this.element.classList.add(lyric_player_module_default.hasDuetLine);
|
|
4670
4682
|
else this.element.classList.remove(lyric_player_module_default.hasDuetLine);
|
|
4671
4683
|
if (!this.supportMaskImage) this.element.style.setProperty("--amll-player-time", `${initialTime}`);
|
|
4672
|
-
for (const group of this.currentLyricGroups)
|
|
4673
|
-
const linesToDispose = [group.mainLine, group.bgLine].filter((line) => !!line);
|
|
4674
|
-
for (const line of linesToDispose) {
|
|
4675
|
-
line.removeMouseEventListener("click", this.onLineClickedHandler);
|
|
4676
|
-
line.removeMouseEventListener("contextmenu", this.onLineClickedHandler);
|
|
4677
|
-
}
|
|
4678
|
-
group.dispose();
|
|
4679
|
-
}
|
|
4684
|
+
for (const group of this.currentLyricGroups) group.dispose();
|
|
4680
4685
|
this.currentLyricGroups = [];
|
|
4681
4686
|
let currentGroup = null;
|
|
4682
4687
|
for (let i = 0; i < this.processedLines.length; i++) {
|
|
4683
4688
|
const line = this.processedLines[i];
|
|
4684
4689
|
const lineEl = new LyricLineEl(this, line);
|
|
4685
|
-
lineEl.addMouseEventListener("click", this.onLineClickedHandler);
|
|
4686
|
-
lineEl.addMouseEventListener("contextmenu", this.onLineClickedHandler);
|
|
4687
4690
|
this.lyricLinesIndexes.set(lineEl, i);
|
|
4688
4691
|
if (!line.isBG || !currentGroup) {
|
|
4689
4692
|
currentGroup = new LyricLineGroup(this, lineEl);
|
|
@@ -4726,6 +4729,7 @@ var DomLyricPlayer = class extends LyricPlayerBase {
|
|
|
4726
4729
|
}
|
|
4727
4730
|
dispose() {
|
|
4728
4731
|
super.dispose();
|
|
4732
|
+
this.abortController.abort();
|
|
4729
4733
|
this.element.remove();
|
|
4730
4734
|
for (const group of this.currentLyricGroups) group.dispose();
|
|
4731
4735
|
this.bottomLine.dispose();
|