44 <SvgIcon name =" Copy" />
55 </div >
66 <div class =" divider" />
7- <div class =" menu-icon" @click =" changeOffset(-500 )" >
7+ <div class =" menu-icon" @click =" changeOffset(-settingStore.lyricOffsetStep )" >
88 <SvgIcon name =" Replay5" />
99 </div >
10- <span class =" time" @click =" resetOffset()" >
11- {{ currentTimeOffsetValue }}
12- </span >
13- <div class =" menu-icon" @click =" changeOffset(500)" >
10+ <n-popover class =" player" trigger =" click" placement =" left" style =" padding : 8px " >
11+ <template #trigger >
12+ <span class =" time" >
13+ {{ currentTimeOffsetValue }}
14+ </span >
15+ </template >
16+ <n-flex class =" offset-menu" :size =" 4" vertical >
17+ <span class =" title" > 歌词偏移 </span >
18+ <span class =" tip" > 正值为歌词提前,单位毫秒 </span >
19+ <n-input-number
20+ v-model:value =" offsetMilliseconds"
21+ class =" offset-input"
22+ :precision =" 0"
23+ :step =" 100"
24+ placeholder =" 0"
25+ size =" small"
26+ >
27+ <template #suffix >ms</template >
28+ </n-input-number >
29+ <n-button
30+ class =" player"
31+ size =" small"
32+ secondary
33+ strong
34+ @click =" resetOffset"
35+ :disabled =" offsetMilliseconds == 0"
36+ >
37+ 清零
38+ </n-button >
39+ </n-flex >
40+ </n-popover >
41+ <div class =" menu-icon" @click =" changeOffset(settingStore.lyricOffsetStep)" >
1442 <SvgIcon name =" Forward5" />
1543 </div >
1644 <div class =" divider" />
2149</template >
2250
2351<script setup lang="ts">
24- import { useMusicStore , useStatusStore } from " @/stores" ;
52+ import { useMusicStore , useSettingStore , useStatusStore } from " @/stores" ;
2553import { openSetting , openCopyLyrics } from " @/utils/modal" ;
2654
2755const musicStore = useMusicStore ();
56+ const settingStore = useSettingStore ();
2857const statusStore = useStatusStore ();
2958
3059/**
@@ -33,13 +62,23 @@ const statusStore = useStatusStore();
3362const currentSongId = computed (() => musicStore .playSong ?.id as number | undefined );
3463
3564/**
36- * 当前进度偏移值(显示为秒,保留1位小数)
65+ * 当前进度偏移值
3766 */
3867const currentTimeOffsetValue = computed (() => {
3968 const currentTimeOffset = statusStore .getSongOffset (currentSongId .value );
40- // 将毫秒转换为秒显示(保留1位小数)
41- const offsetSeconds = (currentTimeOffset / 1000 ).toFixed (1 );
42- return currentTimeOffset > 0 ? ` +${offsetSeconds } ` : offsetSeconds ;
69+ if (currentTimeOffset === 0 ) return " 0" ;
70+ // 将毫秒转换为秒显示
71+ const offsetSeconds = parseFloat ((currentTimeOffset / 1000 ).toFixed (2 ));
72+ return currentTimeOffset > 0 ? ` +${offsetSeconds } ` : ` ${offsetSeconds } ` ;
73+ });
74+
75+ const offsetMilliseconds = computed ({
76+ get : () => {
77+ return statusStore .getSongOffset (currentSongId .value );
78+ },
79+ set : (val : number | null ) => {
80+ statusStore .setSongOffset (currentSongId .value , val || 0 );
81+ },
4382});
4483
4584/**
@@ -123,6 +162,36 @@ const resetOffset = () => {
123162 }
124163}
125164
165+ .offset-menu {
166+ width : 180px ;
167+ .title {
168+ font-size : 14px ;
169+ line-height : normal ;
170+ }
171+ .tip {
172+ font-size : 12px ;
173+ opacity : 0.6 ;
174+ }
175+ :deep (.n-input ) {
176+ --n-caret-color : rgb (var (--main-cover-color ));
177+ --n-color : rgba (var (--main-cover-color ), 0.1 );
178+ --n-color-focus : rgba (var (--main-cover-color ), 0.1 );
179+ --n-text-color : rgb (var (--main-cover-color ));
180+ --n-border-hover : 1px solid rgba (var (--main-cover-color ), 0.28 );
181+ --n-border-focus : 1px solid rgba (var (--main-cover-color ), 0.28 );
182+ --n-suffix-text-color : rgb (var (--main-cover-color ));
183+ --n-box-shadow-focus : 0 0 8px 0 rgba (var (--main-cover-color ), 0.3 );
184+ // 文本选中颜色
185+ input {
186+ & ::selection {
187+ background-color : rgba (var (--main-cover-color ));
188+ }
189+ }
190+ .n-button {
191+ --n-text-color : rgb (var (--main-cover-color ));
192+ }
193+ }
194+ }
126195.lyric ,
127196.lyric-am {
128197 & :hover {
0 commit comments