feat(播放界面): 新增音量图标并优化播放器布局

- 添加新的音量图标组件 speaker.vue
- 调整播放器界面布局,将歌曲信息与操作按钮重新排列
- 优化播放控制按钮的视觉效果,统一模糊效果实现方式
This commit is contained in:
Astrian Zheng 2025-05-26 12:18:06 +10:00
parent c07f430009
commit b6574d8093
Signed by: Astrian
SSH Key Fingerprint: SHA256:rVnhx3DAKjujCwWE13aDl7uV6+9U1MvydLkNRXJrBiA
2 changed files with 99 additions and 39 deletions

View File

@ -0,0 +1,13 @@
<script setup lang="ts">
defineProps<{
size: number
}>()
</script>
<template>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" :class="`w-${size} h-${size}`">
<path
d="M6.60282 10.0001L10 7.22056V16.7796L6.60282 14.0001H3V10.0001H6.60282ZM2 16.0001H5.88889L11.1834 20.3319C11.2727 20.405 11.3846 20.4449 11.5 20.4449C11.7761 20.4449 12 20.2211 12 19.9449V4.05519C12 3.93977 11.9601 3.8279 11.887 3.73857C11.7121 3.52485 11.3971 3.49335 11.1834 3.66821L5.88889 8.00007H2C1.44772 8.00007 1 8.44778 1 9.00007V15.0001C1 15.5524 1.44772 16.0001 2 16.0001ZM23 12C23 15.292 21.5539 18.2463 19.2622 20.2622L17.8445 18.8444C19.7758 17.1937 21 14.7398 21 12C21 9.26016 19.7758 6.80629 17.8445 5.15557L19.2622 3.73779C21.5539 5.75368 23 8.70795 23 12ZM18 12C18 10.0883 17.106 8.38548 15.7133 7.28673L14.2842 8.71584C15.3213 9.43855 16 10.64 16 12C16 13.36 15.3213 14.5614 14.2842 15.2841L15.7133 16.7132C17.106 15.6145 18 13.9116 18 12Z">
</path>
</svg>
</template>

View File

@ -19,6 +19,7 @@ import EllipsisHorizontalIcon from '../assets/icons/ellipsishorizontal.vue'
import XIcon from '../assets/icons/x.vue' import XIcon from '../assets/icons/x.vue'
import ShuffleIcon from '../assets/icons/shuffle.vue' import ShuffleIcon from '../assets/icons/shuffle.vue'
import CycleTwoArrowsIcon from '../assets/icons/cycletwoarrows.vue' import CycleTwoArrowsIcon from '../assets/icons/cycletwoarrows.vue'
import SpeakerIcon from '../assets/icons/speaker.vue'
const playQueueStore = usePlayQueueStore() const playQueueStore = usePlayQueueStore()
gsap.registerPlugin(Draggable) gsap.registerPlugin(Draggable)
@ -147,7 +148,8 @@ function makePlayQueueListDismiss() {
<div class="flex flex-col w-96 gap-4"> <div class="flex flex-col w-96 gap-4">
<img :src="playQueueStore.list[playQueueStore.currentIndex].album?.coverUrl" <img :src="playQueueStore.list[playQueueStore.currentIndex].album?.coverUrl"
class="rounded-2xl shadow-2xl border border-white/20 w-96 h-96" /> class="rounded-2xl shadow-2xl border border-white/20 w-96 h-96" />
<div class="relative"> <div class="flex justify-between items-center">
<div class="relative flex-auto w-0">
<div class=""> <div class="">
<div class="text-black/90 blur-lg text-lg font-medium truncate"> <div class="text-black/90 blur-lg text-lg font-medium truncate">
{{ playQueueStore.list[playQueueStore.currentIndex].song.name }} {{ playQueueStore.list[playQueueStore.currentIndex].song.name }}
@ -170,6 +172,13 @@ function makePlayQueueListDismiss() {
</div> </div>
<div class="relative">
<button class="h-10 w-10 flex justify-center items-center rounded-full bg-black/10 backdrop-blur-3xl">
<span class="text-white"><StarEmptyIcon :size="6" /></span>
</button>
</div>
</div>
<div class="flex flex-col gap-1"> <div class="flex flex-col gap-1">
<div class="w-full p-[0.125rem] bg-white/20 shadow-[0_.125rem_1rem_0_#00000010] rounded-full backdrop-blur-3xl"> <div class="w-full p-[0.125rem] bg-white/20 shadow-[0_.125rem_1rem_0_#00000010] rounded-full backdrop-blur-3xl">
<div class="w-full" ref="progressBarContainer"> <div class="w-full" ref="progressBarContainer">
@ -179,7 +188,8 @@ function makePlayQueueListDismiss() {
<div class="w-full flex justify-between"> <div class="w-full flex justify-between">
<div class="font-medium flex-1 text-left relative"> <div class="font-medium flex-1 text-left relative">
<span class="text-black blur-lg absolute top-0">{{ timeFormatter(Math.floor(playQueueStore.currentTime)) }}</span> <span
class="text-black blur-lg absolute top-0">{{ timeFormatter(Math.floor(playQueueStore.currentTime)) }}</span>
<span class="text-white/90">{{ timeFormatter(Math.floor(playQueueStore.currentTime)) }}</span> <span class="text-white/90">{{ timeFormatter(Math.floor(playQueueStore.currentTime)) }}</span>
</div> </div>
<div class="text-xs text-center relative"> <div class="text-xs text-center relative">
@ -188,9 +198,9 @@ function makePlayQueueListDismiss() {
</div> </div>
<div class="flex flex-1"> <div class="flex flex-1">
<div class="flex-1" /> <div class="flex-1" />
<button class="text-white/90 font-medium text-right relative" <button class="text-white/90 font-medium text-right relative" @click="displayTimeLeft = !displayTimeLeft">
@click="displayTimeLeft = !displayTimeLeft"> <span
<span class="text-black blur-lg absolute top-0">{{ `${displayTimeLeft? '-' : ''}${timeFormatter(displayTimeLeft? Math.floor(playQueueStore.duration) - Math.floor(playQueueStore.currentTime) : playQueueStore.duration)}` }}</span> class="text-black blur-lg absolute top-0">{{ `${displayTimeLeft ? '-' : ''}${timeFormatter(displayTimeLeft ? Math.floor(playQueueStore.duration) - Math.floor(playQueueStore.currentTime) : playQueueStore.duration)}` }}</span>
<span>{{ `${displayTimeLeft ? '-' : ''}${timeFormatter(displayTimeLeft ? Math.floor(playQueueStore.duration) - Math.floor(playQueueStore.currentTime) : playQueueStore.duration)}` }}</span> <span>{{ `${displayTimeLeft ? '-' : ''}${timeFormatter(displayTimeLeft ? Math.floor(playQueueStore.duration) - Math.floor(playQueueStore.currentTime) : playQueueStore.duration)}` }}</span>
</button> </button>
</div> </div>
@ -203,15 +213,23 @@ function makePlayQueueListDismiss() {
<div class="flex-1 text-left flex gap-1"> <div class="flex-1 text-left flex gap-1">
<button class="h-8 w-8 flex justify-center items-center rounded-full hover:bg-white/25"> <button class="h-8 w-8 flex justify-center items-center rounded-full hover:bg-white/25">
<div class="w-6 h-6 relative"> <div class="w-6 h-6 relative">
<span class="text-black blur-md absolute top-0 left-0"><StarEmptyIcon :size="6" /></span> <span class="text-black blur-md absolute top-0 left-0">
<span class="text-white"><StarEmptyIcon :size="6" /></span> <SpeakerIcon :size="6" />
</span>
<span class="text-white">
<SpeakerIcon :size="6" />
</span>
</div> </div>
</button> </button>
<button class="text-white h-8 w-8 flex justify-center items-center rounded-full hover:bg-white/25" <button class="text-white h-8 w-8 flex justify-center items-center rounded-full hover:bg-white/25"
@click="makePlayQueueListPresent"> @click="makePlayQueueListPresent">
<div class="w-6 h-6 relative"> <div class="w-6 h-6 relative">
<span class="text-black blur-md absolute top-0 left-0"><MusicListIcon :size="6" /></span> <span class="text-black blur-md absolute top-0 left-0">
<span class="text-white"><MusicListIcon :size="6" /></span> <MusicListIcon :size="6" />
</span>
<span class="text-white">
<MusicListIcon :size="6" />
</span>
</div> </div>
</button> </button>
</div> </div>
@ -221,8 +239,12 @@ function makePlayQueueListDismiss() {
<button class="text-white flex-1 h-10 flex justify-center items-center rounded-lg hover:bg-white/25" <button class="text-white flex-1 h-10 flex justify-center items-center rounded-lg hover:bg-white/25"
@click="playPrevious"> @click="playPrevious">
<div class="w-8 h-8 relative"> <div class="w-8 h-8 relative">
<span class="text-black/80 blur-lg absolute top-0 left-0"><RewindIcon :size="8" /></span> <span class="text-black/80 blur-lg absolute top-0 left-0">
<span class="text-white"><RewindIcon :size="8" /></span> <RewindIcon :size="8" />
</span>
<span class="text-white">
<RewindIcon :size="8" />
</span>
</div> </div>
</button> </button>
@ -230,18 +252,30 @@ function makePlayQueueListDismiss() {
@click="playQueueStore.isPlaying = !playQueueStore.isPlaying"> @click="playQueueStore.isPlaying = !playQueueStore.isPlaying">
<div v-if="playQueueStore.isPlaying"> <div v-if="playQueueStore.isPlaying">
<div v-if="playQueueStore.isBuffering" class="w-6 h-6 relative"> <div v-if="playQueueStore.isBuffering" class="w-6 h-6 relative">
<span class="text-black/80 blur-lg absolute top-0 left-0"><LoadingIndicator :size="6" /></span> <span class="text-black/80 blur-lg absolute top-0 left-0">
<span class="text-white"><LoadingIndicator :size="6" /></span> <LoadingIndicator :size="6" />
</span>
<span class="text-white">
<LoadingIndicator :size="6" />
</span>
</div> </div>
<div v-else class="w-8 h-8 relative"> <div v-else class="w-8 h-8 relative">
<span class="text-black/80 blur-lg absolute top-0 left-0"><PauseIcon :size="8" /></span> <span class="text-black blur-md absolute top-0 left-0">
<span class="text-white"><PauseIcon :size="8" /></span> <PauseIcon :size="8" />
</span>
<span class="text-white">
<PauseIcon :size="8" />
</span>
</div> </div>
</div> </div>
<div v-else> <div v-else>
<div class="w-8 h-8 relative"> <div class="w-8 h-8 relative">
<span class="text-black/80 blur-lg absolute top-0 left-0"><PlayIcon :size="8" /></span> <span class="text-black/80 blur-lg absolute top-0 left-0">
<span class="text-white"><PlayIcon :size="8" /></span> <PlayIcon :size="8" />
</span>
<span class="text-white">
<PlayIcon :size="8" />
</span>
</div> </div>
</div> </div>
</button> </button>
@ -249,8 +283,12 @@ function makePlayQueueListDismiss() {
<button class="text-white flex-1 h-10 flex justify-center items-center rounded-lg hover:bg-white/25" <button class="text-white flex-1 h-10 flex justify-center items-center rounded-lg hover:bg-white/25"
@click="playNext"> @click="playNext">
<div class="w-8 h-8 relative"> <div class="w-8 h-8 relative">
<span class="text-black/80 blur-lg absolute top-0 left-0"><ForwardIcon :size="8" /></span> <span class="text-black/80 blur-lg absolute top-0 left-0">
<span class="text-white"><ForwardIcon :size="8" /></span> <ForwardIcon :size="8" />
</span>
<span class="text-white">
<ForwardIcon :size="8" />
</span>
</div> </div>
</button> </button>
</div> </div>
@ -259,14 +297,22 @@ function makePlayQueueListDismiss() {
<div class="flex-1" /> <div class="flex-1" />
<button class="text-white h-8 w-8 flex justify-center items-center rounded-full hover:bg-white/25"> <button class="text-white h-8 w-8 flex justify-center items-center rounded-full hover:bg-white/25">
<div class="w-6 h-6 relative"> <div class="w-6 h-6 relative">
<span class="text-black blur-md absolute top-0 left-0"><ChatBubbleQuoteIcon :size="6" /></span> <span class="text-black blur-md absolute top-0 left-0">
<span class="text-white"><ChatBubbleQuoteIcon :size="6" /></span> <ChatBubbleQuoteIcon :size="6" />
</span>
<span class="text-white">
<ChatBubbleQuoteIcon :size="6" />
</span>
</div> </div>
</button> </button>
<button class="text-white h-8 w-8 flex justify-center items-center rounded-full hover:bg-white/25"> <button class="text-white h-8 w-8 flex justify-center items-center rounded-full hover:bg-white/25">
<div class="w-6 h-6 relative"> <div class="w-6 h-6 relative">
<span class="text-black blur-sm absolute top-0 left-0"><EllipsisHorizontalIcon :size="6" /></span> <span class="text-black blur-sm absolute top-0 left-0">
<span class="text-white"><EllipsisHorizontalIcon :size="6" /></span> <EllipsisHorizontalIcon :size="6" />
</span>
<span class="text-white">
<EllipsisHorizontalIcon :size="6" />
</span>
</div> </div>
</button> </button>
</div> </div>
@ -327,7 +373,8 @@ function makePlayQueueListDismiss() {
<div class="flex flex-col text-left flex-auto w-0"> <div class="flex flex-col text-left flex-auto w-0">
<div class="text-white text-base font-medium truncate">{{ track.song.name }}</div> <div class="text-white text-base font-medium truncate">{{ track.song.name }}</div>
<div class="text-white/75 text-sm truncate">{{ artistsOrganize(track.song.artists ?? []) }} <div class="text-white/75 text-sm truncate">{{ artistsOrganize(track.song.artists ?? []) }}
{{ track.album?.name ?? '未知专辑' }}</div> {{ track.album?.name ?? '未知专辑' }}
</div>
</div> </div>
</div> </div>
</button> </button>