@applemusic-like-lyrics/core 0.2.0-alpha.3 → 0.2.0-alpha.4

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.
@@ -1,6 +1,6 @@
1
- import { LyricPlayer } from '.';
2
- import { Disposable, HasElement, LyricLine, LyricWord } from '../../interfaces';
3
- import { Spring } from '../../utils/spring';
1
+ import { DomLyricPlayer } from '.';
2
+ import { LyricLine, LyricWord } from '../../interfaces.ts';
3
+ import { LyricLineBase } from '../base.ts';
4
4
  interface RealWord extends LyricWord {
5
5
  mainElement: HTMLSpanElement;
6
6
  subElements: HTMLSpanElement[];
@@ -11,7 +11,6 @@ interface RealWord extends LyricWord {
11
11
  padding: number;
12
12
  shouldEmphasize: boolean;
13
13
  }
14
- export declare function shouldEmphasize(word: LyricWord): boolean;
15
14
  export declare class RawLyricLineMouseEvent extends MouseEvent {
16
15
  readonly line: LyricLineEl;
17
16
  constructor(line: LyricLineEl, event: MouseEvent);
@@ -21,58 +20,49 @@ type MouseEventMap = {
21
20
  };
22
21
  type MouseEventTypes = MouseEventMap[keyof MouseEventMap];
23
22
  type MouseEventListener = (this: LyricLineEl, ev: RawLyricLineMouseEvent) => void;
24
- export declare class LyricLineEl extends EventTarget implements HasElement, Disposable {
23
+ export declare class LyricLineEl extends LyricLineBase {
25
24
  private lyricPlayer;
26
25
  private lyricLine;
27
26
  private element;
28
- private left;
29
- private top;
30
- private scale;
31
- private blur;
32
- private delay;
33
27
  private splittedWords;
34
28
  lineSize: number[];
35
- readonly lineTransforms: {
36
- posX: Spring;
37
- posY: Spring;
38
- scale: Spring;
39
- };
40
- constructor(lyricPlayer: LyricPlayer, lyricLine?: LyricLine);
29
+ constructor(lyricPlayer: DomLyricPlayer, lyricLine?: LyricLine);
41
30
  private listenersMap;
42
31
  private readonly onMouseEvent;
43
32
  addMouseEventListener(type: MouseEventTypes, callback: MouseEventListener | null, options?: boolean | AddEventListenerOptions | undefined): void;
44
33
  removeMouseEventListener(type: MouseEventTypes, callback: MouseEventListener | null, options?: boolean | EventListenerOptions | undefined): void;
45
34
  areWordsOnSameLine(word1: RealWord, word2: RealWord): boolean;
46
35
  private isEnabled;
47
- private hasFaded;
48
36
  enable(maskAnimationTime?: number): Promise<void>;
49
- disable(maskAnimationTime?: number): void;
37
+ disable(): void;
50
38
  private lastWord?;
51
- resume(currentTime?: number): void;
52
- pause(currentTime?: number): void;
39
+ resume(): Promise<void>;
40
+ pause(): Promise<void>;
53
41
  setMaskAnimationState(maskAnimationTime?: number): void;
54
- measureSize(): [number, number];
55
- setLine(line: LyricLine): void;
42
+ private measureLockMark;
43
+ private measureLock;
44
+ measureSize(): Promise<[number, number]>;
56
45
  getLine(): LyricLine;
57
46
  private _hide;
58
47
  private _prevParentEl;
59
48
  private lastStyle;
60
49
  show(): void;
61
50
  hide(): void;
62
- rebuildStyle(): void;
51
+ private rebuildStyle;
63
52
  rebuildElement(): void;
64
53
  private initFloatAnimation;
65
54
  private initEmphasizeAnimation;
66
55
  private get totalDuration();
67
56
  private maskImageDirty;
68
- private markImageDirtyPromises;
69
- markMaskImageDirty(): Promise<void>;
57
+ private markImageDirtyPromiseResolve;
58
+ private markImageDirtyPromise;
59
+ markMaskImageDirty(_debugReason?: string): Promise<void>;
70
60
  waitMaskImageUpdated(): Promise<void>;
71
61
  updateMaskImage(): Promise<void>;
72
62
  private generateCalcBasedMaskImage;
73
63
  private generateWebAnimationBasedMaskImage;
74
64
  getElement(): HTMLElement;
75
- setTransform(left?: number, top?: number, scale?: number, opacity?: number, subopacity?: number, blur?: number, force?: boolean, delay?: number): void;
65
+ setTransform(top?: number, scale?: number, opacity?: number, blur?: number, force?: boolean, delay?: number): void;
76
66
  update(delta?: number): void;
77
67
  _getDebugTargetPos(): string;
78
68
  get isInSight(): boolean;
@@ -0,0 +1,33 @@
1
+ import { LyricLine } from '../../interfaces.ts';
2
+ import { LyricPlayerBase } from '../base.ts';
3
+ import { LyricLineEl } from './lyric-line.ts';
4
+ /**
5
+ * 歌词播放组件,本框架的核心组件
6
+ *
7
+ * 尽可能贴切 Apple Music for iPad 的歌词效果设计,且做了力所能及的优化措施
8
+ */
9
+ export declare class DomSlimLyricPlayer extends LyricPlayerBase {
10
+ currentLyricLineObjects: LyricLineEl[];
11
+ private debounceCalcLayout;
12
+ onResize(): void;
13
+ readonly supportPlusLighter: boolean;
14
+ readonly supportMaskImage: boolean;
15
+ readonly innerSize: [number, number];
16
+ private readonly onLineClickedHandler;
17
+ private _baseFontSize;
18
+ get baseFontSize(): number;
19
+ constructor();
20
+ private rebuildStyle;
21
+ setWordFadeWidth(value?: number): void;
22
+ /**
23
+ * 设置当前播放歌词,要注意传入后这个数组内的信息不得修改,否则会发生错误
24
+ * @param lines 歌词数组
25
+ * @param initialTime 初始时间,默认为 0
26
+ */
27
+ setLyricLines(lines: LyricLine[], initialTime?: number): void;
28
+ pause(): void;
29
+ resume(): void;
30
+ update(delta?: number): void;
31
+ calcLayout(force?: boolean, reflow?: boolean): Promise<void>;
32
+ dispose(): void;
33
+ }
@@ -0,0 +1,22 @@
1
+ import { Disposable, HasElement } from '../../interfaces.ts';
2
+ export declare class InterludeDots implements HasElement, Disposable {
3
+ private element;
4
+ private dot0;
5
+ private dot1;
6
+ private dot2;
7
+ private left;
8
+ private top;
9
+ private playing;
10
+ private lastStyle;
11
+ private currentInterlude?;
12
+ private currentTime;
13
+ private targetBreatheDuration;
14
+ constructor();
15
+ getElement(): HTMLElement;
16
+ setTransform(left?: number, top?: number): void;
17
+ setInterlude(interlude?: [number, number]): void;
18
+ pause(): void;
19
+ resume(): void;
20
+ update(delta?: number): void;
21
+ dispose(): void;
22
+ }
@@ -0,0 +1,71 @@
1
+ import { LyricLine, LyricWord } from '../../interfaces.ts';
2
+ import { LyricLineBase } from '../base.ts';
3
+ import { DomSlimLyricPlayer } from './index.ts';
4
+ interface RealWord extends LyricWord {
5
+ mainElement: HTMLSpanElement;
6
+ subElements: HTMLSpanElement[];
7
+ elementAnimations: Animation[];
8
+ maskAnimations: Animation[];
9
+ width: number;
10
+ height: number;
11
+ padding: number;
12
+ shouldEmphasize: boolean;
13
+ }
14
+ export declare class RawLyricLineMouseEvent extends MouseEvent {
15
+ readonly line: LyricLineEl;
16
+ constructor(line: LyricLineEl, event: MouseEvent);
17
+ }
18
+ type MouseEventMap = {
19
+ [evt in keyof HTMLElementEventMap]: HTMLElementEventMap[evt] extends MouseEvent ? evt : never;
20
+ };
21
+ type MouseEventTypes = MouseEventMap[keyof MouseEventMap];
22
+ type MouseEventListener = (this: LyricLineEl, ev: RawLyricLineMouseEvent) => void;
23
+ export declare class LyricLineEl extends LyricLineBase {
24
+ private lyricPlayer;
25
+ private lyricLine;
26
+ private element;
27
+ private splittedWords;
28
+ lineSize: number[];
29
+ constructor(lyricPlayer: DomSlimLyricPlayer, lyricLine?: LyricLine);
30
+ private listenersMap;
31
+ private readonly onMouseEvent;
32
+ addMouseEventListener(type: MouseEventTypes, callback: MouseEventListener | null, options?: boolean | AddEventListenerOptions | undefined): void;
33
+ removeMouseEventListener(type: MouseEventTypes, callback: MouseEventListener | null, options?: boolean | EventListenerOptions | undefined): void;
34
+ areWordsOnSameLine(word1: RealWord, word2: RealWord): boolean;
35
+ private isEnabled;
36
+ enable(maskAnimationTime?: number): Promise<void>;
37
+ disable(): void;
38
+ private lastWord?;
39
+ resume(): Promise<void>;
40
+ pause(): Promise<void>;
41
+ setMaskAnimationState(maskAnimationTime?: number): void;
42
+ private measureLockMark;
43
+ private measureLock;
44
+ measureSize(): Promise<[number, number]>;
45
+ getLine(): LyricLine;
46
+ private _prevParentEl;
47
+ private lastStyle;
48
+ show(): void;
49
+ hide(): void;
50
+ private rebuildStyle;
51
+ rebuildElement(): void;
52
+ private initFloatAnimation;
53
+ private initEmphasizeAnimation;
54
+ private get totalDuration();
55
+ private maskImageDirty;
56
+ private markImageDirtyPromiseResolve;
57
+ private markImageDirtyPromise;
58
+ markMaskImageDirty(_debugReason?: string): Promise<void>;
59
+ waitMaskImageUpdated(): Promise<void>;
60
+ updateMaskImage(): Promise<void>;
61
+ private generateCalcBasedMaskImage;
62
+ private generateWebAnimationBasedMaskImage;
63
+ getElement(): HTMLElement;
64
+ setTransform(top?: number, scale?: number, opacity?: number, blur?: number, force?: boolean, delay?: number): void;
65
+ update(delta?: number): void;
66
+ _getDebugTargetPos(): string;
67
+ get isInSight(): boolean;
68
+ private disposeElements;
69
+ dispose(): void;
70
+ }
71
+ export {};
@@ -1,9 +1,9 @@
1
- import { Disposable, HasElement } from '../interfaces';
2
- export * from './dom';
3
- export declare abstract class LyricPlayerBase extends EventTarget implements HasElement, Disposable {
4
- protected element: HTMLElement;
5
- constructor();
6
- protected onResize(): void;
7
- getElement(): HTMLElement;
8
- dispose(): void;
9
- }
1
+ import { DomLyricPlayer } from './dom/index.ts';
2
+ export { LyricPlayerBase } from './base.ts';
3
+ export * from './canvas/index.ts';
4
+ export * from './dom-slim/index.ts';
5
+ export * from './dom/index.ts';
6
+ /**
7
+ * 默认导出的歌词播放组件
8
+ */
9
+ export declare const LyricPlayer: typeof DomLyricPlayer;
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- ._lyricLine_kocao_6{-webkit-backface-visibility:hidden;backface-visibility:hidden;transform-origin:0;width:var(--amll-lp-line-width,100%);min-width:var(--amll-lp-line-width,100%);max-width:var(--amll-lp-line-width,100%);padding:2vh var(--amll-lp-line-padding-x,1em);contain:content;box-sizing:content-box;border-radius:16px;height:-moz-fit-content;height:fit-content;transition:filter .2s,background-color .25s,box-shadow .25s;position:absolute}._lyricLine_kocao_6:has(>*):hover{background-color:var(--amll-lp-hover-bg-color,#fff1);box-shadow:0 0 0 4px var(--amll-lp-hover-bg-color,#fff1)}._lyricLine_kocao_6:has(>*):active{box-shadow:0 0 0 var(--amll-lp-hover-bg-color,#fff1)}._lyricBgLine_kocao_31{opacity:0;font-size:max(calc(100%*var(--amll-lp-bg-line-scale,70%)),10px);padding:1vh calc(var(--amll-lp-line-padding-x,1em)/var(--amll-lp-bg-line-scale,.7));transition:opacity .25s,scale .5s,filter .2s,background-color .25s,box-shadow .25s}._lyricBgLine_kocao_31._active_kocao_40{opacity:.4;transition:opacity .5s .25s,scale 1.5s cubic-bezier(0,1,0,1) .25s,filter .2s,background-color .25s,box-shadow .25s}._lyricDuetLine_kocao_47{text-align:right;transform-origin:100%}._lyricMainLine_kocao_52{margin:-1em;padding:1em;transition:opacity .3s .1s}._lyricMainLine_kocao_52 span{display:inline-block}._lyricMainLine_kocao_52>span{white-space:pre-wrap;margin:-1em;padding:1em;display:inline-block}._lyricMainLine_kocao_52>span._emphasize_kocao_62{-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:-1em;padding:1em}._lyricMainLine_kocao_52>span._emphasize_kocao_62>span{will-change:transform;-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:-1em;padding:1em}._lyricMainLine_kocao_52>span span._emphasize_kocao_62{-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:-1em;padding:1em}._lyricMainLine_kocao_52>span span._emphasize_kocao_62>span{will-change:transform;-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:-1em;padding:1em}._lyricMainLine_kocao_52 span._emphasizeWrapper_kocao_62{white-space:pre-wrap;margin:-1em;padding:1em;display:inline-block}._lyricMainLine_kocao_52 span._emphasizeWrapper_kocao_62._emphasize_kocao_62{-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:-1em;padding:1em}._lyricMainLine_kocao_52 span._emphasizeWrapper_kocao_62._emphasize_kocao_62>span{will-change:transform;-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:-1em;padding:1em}._lyricMainLine_kocao_52 span._emphasizeWrapper_kocao_62 span._emphasize_kocao_62{-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:-1em;padding:1em}._lyricMainLine_kocao_52 span._emphasizeWrapper_kocao_62 span._emphasize_kocao_62>span{will-change:transform;-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:-1em;padding:1em}._lyricSubLine_kocao_84{opacity:.3;font-size:max(.5em,10px);line-height:1.5em;transition:opacity .2s .25s}._disableSpring_kocao_91>*{transition:filter .25s,transform .5s,background-color .25s,box-shadow .25s}._interludeDots_kocao_96{transform-origin:50%;padding:2.5% calc(var(--amll-lp-line-padding-x,1em)*.6);gap:.25em;width:-moz-fit-content;width:fit-content;height:max(.5em,min(1vh,3em));display:flex;position:absolute;left:1em}._interludeDots_kocao_96>*{aspect-ratio:1;background-color:var(--amll-lp-color,white);border-radius:50%;height:max(.5em,min(1vh,3em));margin-right:4px;display:inline-block}._interludeDots_kocao_96._duet_kocao_115{transform-origin:50%;right:1em}@supports (mix-blend-mode:plus-lighter){._lyricSubLine_kocao_84{opacity:.3}}._tmpDisableTransition_kocao_127{transition:none!important}.amll-lyric-player.dom{--amll-lp-line-width-aspect:.8;--amll-lp-line-padding-x:1em;--amll-lp-bg-line-scale:.7;-webkit-user-select:none;user-select:none;font-size:var(--amll-lp-font-size,max(max(4.7vh,3.2vw),12px));box-sizing:content-box;z-index:1;color:var(--amll-lp-color,white);mix-blend-mode:plus-lighter;contain:strict;width:100%;max-width:100%;height:100%;margin:-1em;padding:1em;line-height:1.2em;overflow:hidden}.amll-lyric-player.dom:hover .lyric-line{filter:unset!important}@media screen and (max-width:768px){.amll-lyric-player{--amll-lp-line-width-aspect:1;--amll-lp-line-padding-x:0}}
1
+ .amll-lyric-player{color:var(--amll-lp-color,white);contain:strict;mix-blend-mode:plus-lighter;font-size:var(--amll-lp-font-size,max(max(4.7vh,3.2vw),12px));width:100%;max-width:100%;height:100%;overflow:hidden}.amll-lyric-player.dom{--amll-lp-line-width-aspect:.8;--amll-lp-line-padding-x:1em;--amll-lp-bg-line-scale:.7;-webkit-user-select:none;user-select:none;box-sizing:content-box;z-index:1;line-height:1.2em}.amll-lyric-player.dom-slim{--amll-lp-line-width-aspect:.8;--amll-lp-line-padding-x:1em;--amll-lp-bg-line-scale:.7;-webkit-user-select:none;user-select:none;box-sizing:content-box;z-index:1;min-width:0;min-height:0;line-height:1.2em;overflow:hidden auto}.amll-lyric-player.dom-slim::-webkit-scrollbar{display:none}.amll-lyric-player.dom-slim:hover::-webkit-scrollbar{display:block}@media screen and (max-width:768px){.amll-lyric-player{--amll-lp-line-width-aspect:1;--amll-lp-line-padding-x:0}}._lyricLine_lennj_6{-webkit-backface-visibility:hidden;backface-visibility:hidden;transform-origin:0;width:var(--amll-lp-width,100%);min-width:var(--amll-lp-width,100%);max-width:var(--amll-lp-width,100%);contain:content;will-change:transform;box-sizing:border-box;border-radius:.25em;width:100%;height:-moz-fit-content;height:fit-content;padding:2vh 1em;transition:opacity .25s,filter .2s,background-color .25s,box-shadow .25s;position:absolute}._lyricLine_lennj_6._dirty_lennj_26{opacity:0;visibility:hidden}._lyricLine_lennj_6:has(>*):hover{background-color:var(--amll-lp-hover-bg-color,#fff1)}._lyricLine_lennj_6:has(>*):active{background-color:var(--amll-lp-hover-bg-color,#ffffff05)}._lyricBgLine_lennj_42{opacity:0;font-size:max(calc(1em*var(--amll-lp-bg-line-scale,.7)),10px);padding:1vh calc(var(--amll-lp-line-padding-x,1em)/var(--amll-lp-bg-line-scale,.7));transition:opacity .25s,scale .5s,filter .2s,background-color .25s,box-shadow .25s}._lyricBgLine_lennj_42._active_lennj_51{opacity:.4;transition:opacity .5s .25s,scale 1.5s cubic-bezier(0,1,0,1) .25s,filter .2s,background-color .25s,box-shadow .25s}.amll-lyric-player:hover ._lyricLine_lennj_6{filter:unset!important}.amll-lyric-player._hasDuetLine_lennj_63 ._lyricLine_lennj_6:not(._lyricDuetLine_lennj_64){padding-right:15%}.amll-lyric-player._hasDuetLine_lennj_63 ._lyricDuetLine_lennj_64{padding-left:15%}._lyricDuetLine_lennj_64{text-align:right;transform-origin:100%}._lyricMainLine_lennj_78{margin:-1em;padding:1em;transition:opacity .3s .1s}._lyricMainLine_lennj_78 span{display:inline-block}._lyricMainLine_lennj_78>span{white-space:pre-wrap;will-change:transform;margin:-1em;padding:1em;display:inline-block}._lyricMainLine_lennj_78>span._emphasize_lennj_88{-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:-1em;padding:1em}._lyricMainLine_lennj_78>span._emphasize_lennj_88>span{will-change:transform;-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:-1em;padding:1em}._lyricMainLine_lennj_78>span span._emphasize_lennj_88{-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:-1em;padding:1em}._lyricMainLine_lennj_78>span span._emphasize_lennj_88>span{will-change:transform;-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:-1em;padding:1em}._lyricMainLine_lennj_78 span._emphasizeWrapper_lennj_88{white-space:pre-wrap;will-change:transform;margin:-1em;padding:1em;display:inline-block}._lyricMainLine_lennj_78 span._emphasizeWrapper_lennj_88._emphasize_lennj_88{-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:-1em;padding:1em}._lyricMainLine_lennj_78 span._emphasizeWrapper_lennj_88._emphasize_lennj_88>span{will-change:transform;-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:-1em;padding:1em}._lyricMainLine_lennj_78 span._emphasizeWrapper_lennj_88 span._emphasize_lennj_88{-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:-1em;padding:1em}._lyricMainLine_lennj_78 span._emphasizeWrapper_lennj_88 span._emphasize_lennj_88>span{will-change:transform;-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:-1em;padding:1em}._lyricSubLine_lennj_111{opacity:.3;font-size:max(.5em,10px);line-height:1.5em;transition:opacity .2s .25s}._disableSpring_lennj_118>*{transition:filter .25s,transform .5s,background-color .25s,box-shadow .25s}._interludeDots_lennj_123{transform-origin:50%;opacity:0;gap:.25em;width:-moz-fit-content;width:fit-content;height:max(.5em,min(1vh,3em));padding:2.5% .75em;transition:opacity .25s;display:flex;position:absolute;left:0}._interludeDots_lennj_123._enabled_lennj_135{opacity:1}._interludeDots_lennj_123>*{aspect-ratio:1;background-color:var(--amll-lp-color,white);border-radius:50%;width:max(.5em,min(1vh,3em));height:max(.5em,min(1vh,3em));margin-right:4px;display:inline-block}._interludeDots_lennj_123._duet_lennj_149{transform-origin:50%;right:0}@supports (mix-blend-mode:plus-lighter){._lyricSubLine_lennj_111{opacity:.3}}._tmpDisableTransition_lennj_161{transition:none!important}._lyricLine_1ygrf_6{width:var(--amll-lp-width,100%);min-width:var(--amll-lp-width,100%);max-width:var(--amll-lp-width,100%);contain:content;box-sizing:border-box;border-radius:.25em;width:100%;height:-moz-fit-content;height:fit-content;padding:2vh 1em;transition:opacity .25s,filter .2s,background-color .25s,box-shadow .25s}._lyricLine_1ygrf_6:has(>*):hover{background-color:var(--amll-lp-hover-bg-color,#fff1)}._lyricLine_1ygrf_6:has(>*):active{background-color:var(--amll-lp-hover-bg-color,#ffffff05)}._lyricBgLine_1ygrf_33{opacity:0;font-size:max(calc(1em*var(--amll-lp-bg-line-scale,.7)),10px);padding:1vh calc(var(--amll-lp-line-padding-x,1em)/var(--amll-lp-bg-line-scale,.7));transition:opacity .25s,scale .5s,filter .2s,background-color .25s,box-shadow .25s}._lyricBgLine_1ygrf_33._active_1ygrf_42{opacity:.4;transition:opacity .5s .25s,scale 1.5s cubic-bezier(0,1,0,1) .25s,filter .2s,background-color .25s,box-shadow .25s}.amll-lyric-player:hover ._lyricLine_1ygrf_6{filter:unset!important}.amll-lyric-player._hasDuetLine_1ygrf_54 ._lyricLine_1ygrf_6:not(._lyricDuetLine_1ygrf_55){padding-right:15%}.amll-lyric-player._hasDuetLine_1ygrf_54 ._lyricDuetLine_1ygrf_55{padding-left:15%}._lyricDuetLine_1ygrf_55{text-align:right;transform-origin:100%}._lyricMainLine_1ygrf_69{contain:content paint;transition:opacity .3s .1s}._lyricMainLine_1ygrf_69 span{white-space:pre;display:inline-block}._lyricSubLine_1ygrf_79{opacity:.3;font-size:max(.5em,10px);line-height:1.5em;transition:opacity .2s .25s}._interludeDots_1ygrf_86{transform-origin:50%;opacity:0;gap:.25em;width:-moz-fit-content;width:fit-content;height:max(.5em,min(1vh,3em));padding:2.5% .75em;transition:opacity .25s;display:flex;left:0}._interludeDots_1ygrf_86._enabled_1ygrf_97{opacity:1}._interludeDots_1ygrf_86>*{aspect-ratio:1;background-color:var(--amll-lp-color,white);border-radius:50%;width:max(.5em,min(1vh,3em));height:max(.5em,min(1vh,3em));margin-right:4px;display:inline-block}._interludeDots_1ygrf_86._duet_1ygrf_111{transform-origin:50%;right:0}@supports (mix-blend-mode:plus-lighter){._lyricSubLine_1ygrf_79{opacity:.3}}._tmpDisableTransition_1ygrf_123{transition:none!important}
@@ -0,0 +1 @@
1
+ export declare const isCJK: (char: string) => boolean;
@@ -0,0 +1,11 @@
1
+ import { LyricWord } from '../interfaces.ts';
2
+ /**
3
+ * 将输入的单词重新分组,之间没有空格的单词将会组合成一个单词数组
4
+ *
5
+ * 例如输入:`["Life", " ", "is", " a", " su", "gar so", "sweet"]`
6
+ *
7
+ * 应该返回:`["Life", " ", "is", " a", [" su", "gar"], "so", "sweet"]`
8
+ * @param words 输入的单词数组
9
+ * @returns 重新分组后的单词数组
10
+ */
11
+ export declare function chunkAndSplitLyricWords(words: LyricWord[]): (LyricWord | LyricWord[])[];
@@ -0,0 +1,2 @@
1
+ export declare function mutexifyFunction<F extends (...args: Args) => Promise<Result>, Args extends any[], Result>(func: F): F;
2
+ export default mutexifyFunction;
@@ -1,4 +1,4 @@
1
- import { Disposable } from '..';
1
+ import { Disposable } from '../interfaces.ts';
2
2
  export interface SpringParams {
3
3
  mass: number;
4
4
  damping: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applemusic-like-lyrics/core",
3
- "version": "0.2.0-alpha.3",
3
+ "version": "0.2.0-alpha.4",
4
4
  "description": "AMLL 的纯 JS 核心组件框架,包括歌词显示组件和背景组件等其它可以复用的组件",
5
5
  "repository": {
6
6
  "url": "https://github.com/Steve-xmh/applemusic-like-lyrics.git",
@@ -31,18 +31,18 @@
31
31
  }
32
32
  },
33
33
  "devDependencies": {
34
- "@applemusic-like-lyrics/lyric": "^0.0.2",
35
- "@biomejs/biome": "^1.8.3",
34
+ "@applemusic-like-lyrics/lyric": "^0.2.4",
35
+ "@biomejs/biome": "^1.9.4",
36
36
  "@types/deep-freeze": "^0.1.5",
37
37
  "@types/stats.js": "^0.17.3",
38
38
  "@types/ungap__structured-clone": "^1.2.0",
39
- "lil-gui": "^0.18.2",
39
+ "lil-gui": "^0.19.2",
40
40
  "stats.js": "^0.17.0",
41
- "typedoc": "^0.26.5",
42
- "typedoc-plugin-markdown": "^4.2.3",
43
- "typescript": "^5.5.4",
44
- "vite": "^5.4.0",
45
- "vite-plugin-dts": "^4.0.3",
41
+ "typedoc": "^0.26.10",
42
+ "typedoc-plugin-markdown": "^4.2.9",
43
+ "typescript": "^5.6.3",
44
+ "vite": "^5.4.10",
45
+ "vite-plugin-dts": "^4.3.0",
46
46
  "vite-plugin-glsl": "^1.3.0",
47
47
  "vite-plugin-top-level-await": "^1.4.4",
48
48
  "vite-plugin-wasm": "^3.3.0",
@@ -61,7 +61,7 @@
61
61
  "@ungap/structured-clone": "^1.2.0",
62
62
  "bezier-easing": "^2.1.0",
63
63
  "deep-freeze": "^0.0.1",
64
- "gl-matrix": "^4.0.0-beta.2"
64
+ "gl-matrix": "4.0.0-beta.2"
65
65
  },
66
66
  "scripts": {
67
67
  "build:docs": "typedoc --plugin typedoc-plugin-markdown --out docs src/index.ts",
@@ -1,2 +0,0 @@
1
- export declare class LyricLayouter {
2
- }