@@ -631,6 +631,26 @@ export const MusicPlayer = () => {
631631 return s . playlist [ s . currentIndex ]
632632 }
633633
634+ // ===== 底栏滚动歌词:复用 parseLRC,外部 .lrc 优先于内嵌歌词 =====
635+ // 仅在歌词文本变化时才重新解析(依赖 currentIndex / externalLyrics / 当前 item.lyrics)
636+ const miniLyricLines = createMemo ( ( ) => {
637+ const ext = playerState ( ) . externalLyrics
638+ if ( ext ) return parseLRC ( ext )
639+ return parseLRC ( currentItem ( ) ?. lyrics ?? "" )
640+ } )
641+ // 当前命中的歌词行索引(依赖 currentTime;找不到时返回 -1)
642+ const currentMiniLyricIdx = ( ) => {
643+ const lines = miniLyricLines ( )
644+ if ( lines . length === 0 ) return - 1
645+ const t = playerState ( ) . currentTime
646+ let idx = - 1
647+ for ( let i = 0 ; i < lines . length ; i ++ ) {
648+ if ( lines [ i ] . time <= t ) idx = i
649+ else break
650+ }
651+ return idx
652+ }
653+
634654 const handleSeek = ( e : MouseEvent ) => {
635655 const bar = e . currentTarget as HTMLDivElement
636656 const rect = bar . getBoundingClientRect ( )
@@ -723,13 +743,15 @@ export const MusicPlayer = () => {
723743 } }
724744 >
725745 { /* 左:封面 + 歌曲信息(点击展开歌词) */ }
746+ { /* 取消 flex:1,改为有限宽度,把剩余空间让给中间的歌词条 */ }
726747 < div
727748 style = { {
728749 display : "flex" ,
729750 "align-items" : "center" ,
730751 gap : "12px" ,
731- flex : "1 " ,
752+ width : "260px " ,
732753 "min-width" : "0" ,
754+ "flex-shrink" : "0" ,
733755 cursor : "pointer" ,
734756 } }
735757 onClick = { ( ) =>
@@ -791,6 +813,80 @@ export const MusicPlayer = () => {
791813 </ div >
792814 </ div >
793815
816+ { /* 中-左:滚动歌词条(专辑信息 与 播放控制 之间)
817+ - flex:1 占据剩余空间;min-width:0 保证 ellipsis 生效
818+ - 点击同样可展开全屏歌词页
819+ - 双行:上方为当前行(高亮),下方为下一行预览
820+ - 没有歌词时显示淡占位以保持布局稳定 */ }
821+ < div
822+ onClick = { ( ) =>
823+ setPlayerState ( ( s ) => ( { ...s , showLyrics : true } ) )
824+ }
825+ title = "点击查看完整歌词"
826+ style = { {
827+ flex : "1" ,
828+ "min-width" : "0" ,
829+ display : "flex" ,
830+ "flex-direction" : "column" ,
831+ "justify-content" : "center" ,
832+ gap : "2px" ,
833+ cursor : "pointer" ,
834+ padding : "0 14px" ,
835+ "text-align" : "center" ,
836+ "user-select" : "none" ,
837+ } }
838+ >
839+ < Show
840+ when = { miniLyricLines ( ) . length > 0 }
841+ fallback = {
842+ < div
843+ style = { {
844+ color : "rgba(148,163,184,0.4)" ,
845+ "font-size" : "13px" ,
846+ "white-space" : "nowrap" ,
847+ overflow : "hidden" ,
848+ "text-overflow" : "ellipsis" ,
849+ } }
850+ >
851+ 🎵 暂无歌词
852+ </ div >
853+ }
854+ >
855+ < div
856+ style = { {
857+ color : "#f1f5f9" ,
858+ "font-size" : "14px" ,
859+ "font-weight" : "500" ,
860+ "white-space" : "nowrap" ,
861+ overflow : "hidden" ,
862+ "text-overflow" : "ellipsis" ,
863+ "letter-spacing" : "-0.01em" ,
864+ transition : "color 0.3s" ,
865+ } }
866+ >
867+ { currentMiniLyricIdx ( ) >= 0
868+ ? miniLyricLines ( ) [ currentMiniLyricIdx ( ) ] . text || "♪"
869+ : miniLyricLines ( ) [ 0 ] ?. text || "♪" }
870+ </ div >
871+ < div
872+ style = { {
873+ color : "rgba(148,163,184,0.55)" ,
874+ "font-size" : "12px" ,
875+ "white-space" : "nowrap" ,
876+ overflow : "hidden" ,
877+ "text-overflow" : "ellipsis" ,
878+ } }
879+ >
880+ { ( ( ) => {
881+ const lines = miniLyricLines ( )
882+ const i = currentMiniLyricIdx ( )
883+ const next = i >= 0 ? lines [ i + 1 ] : lines [ 1 ]
884+ return next ?. text ?? ""
885+ } ) ( ) }
886+ </ div >
887+ </ Show >
888+ </ div >
889+
794890 { /* 中:播放控制 */ }
795891 < div
796892 style = { {
0 commit comments