Files
AlgerMusicPlayer/src/layout/components/MusicFull.vue
T

218 lines
5.0 KiB
Vue
Raw Normal View History

2021-11-09 11:34:09 +08:00
<template>
<n-drawer :show="musicFull" height="100vh" placement="bottom" :style="{ background: background }">
<div id="drawer-target">
<div class="drawer-back"></div>
<div class="music-img">
<n-image ref="PicImgRef" :src="getImgUrl(playMusic?.picUrl, '300y300')" class="img" lazy preview-disabled />
<div>
<div class="music-content-name">{{ playMusic.name }}</div>
<div class="music-content-singer">
<span v-for="(item, index) in playMusic.song.artists" :key="index">
{{ item.name }}{{ index < playMusic.song.artists.length - 1 ? ' / ' : '' }}
</span>
</div>
</div>
</div>
<div class="music-content">
<n-layout
ref="lrcSider"
class="music-lrc"
style="height: 60vh"
:native-scrollbar="false"
@mouseover="mouseOverLayout"
@mouseleave="mouseLeaveLayout"
>
<div ref="lrcContainer">
<div
v-for="(item, index) in lrcArray"
:id="`music-lrc-text-${index}`"
:key="index"
class="music-lrc-text"
:class="{ 'now-text': index === nowIndex }"
2023-12-18 15:24:57 +08:00
@click="setAudioTime(index, audio)"
>
<span :style="getLrcStyle(index)">{{ item.text }}</span>
<div class="music-lrc-text-tr">{{ item.trText }}</div>
</div>
</div>
</n-layout>
<!-- 时间矫正 -->
<!-- <div class="music-content-time">
2023-12-27 14:39:52 +08:00
<n-button @click="reduceCorrectionTime(0.2)">-</n-button>
<n-button @click="addCorrectionTime(0.2)">+</n-button>
</div> -->
2021-11-09 11:34:09 +08:00
</div>
</div>
2023-12-18 15:24:57 +08:00
</n-drawer>
2021-11-09 11:34:09 +08:00
</template>
<script setup lang="ts">
import { useDebounceFn } from '@vueuse/core';
import {
addCorrectionTime,
lrcArray,
nowIndex,
playMusic,
reduceCorrectionTime,
setAudioTime,
useLyricProgress,
} from '@/hooks/MusicHook';
import { getImgUrl } from '@/utils';
const { getLrcStyle } = useLyricProgress();
2021-11-09 11:34:09 +08:00
// const isPlaying = computed(() => store.state.play as boolean);
// 获取歌词滚动dom
const lrcSider = ref<any>(null);
const isMouse = ref(false);
const lrcContainer = ref<HTMLElement | null>(null);
2021-11-09 11:34:09 +08:00
const props = defineProps({
musicFull: {
type: Boolean,
default: false,
2021-11-09 11:34:09 +08:00
},
audio: {
type: HTMLAudioElement,
default: null,
},
background: {
type: String,
default: '',
},
});
2021-11-09 11:34:09 +08:00
// 歌词滚动方法
const lrcScroll = (behavior = 'smooth') => {
const nowEl = document.querySelector(`#music-lrc-text-${nowIndex.value}`);
if (props.musicFull && !isMouse.value && nowEl && lrcContainer.value) {
const containerRect = lrcContainer.value.getBoundingClientRect();
const nowElRect = nowEl.getBoundingClientRect();
const relativeTop = nowElRect.top - containerRect.top;
const scrollTop = relativeTop - lrcSider.value.$el.getBoundingClientRect().height / 2;
lrcSider.value.scrollTo({ top: scrollTop, behavior });
2021-11-09 11:34:09 +08:00
}
};
const debouncedLrcScroll = useDebounceFn(lrcScroll, 200);
2021-11-09 11:34:09 +08:00
const mouseOverLayout = () => {
isMouse.value = true;
};
2021-11-09 11:34:09 +08:00
const mouseLeaveLayout = () => {
setTimeout(() => {
isMouse.value = false;
lrcScroll();
}, 2000);
};
watch(nowIndex, () => {
debouncedLrcScroll();
});
watch(
() => props.musicFull,
() => {
if (props.musicFull) {
nextTick(() => {
lrcScroll('instant');
});
}
},
);
defineExpose({
2023-12-18 15:24:57 +08:00
lrcScroll,
});
2021-11-09 11:34:09 +08:00
</script>
<style scoped lang="scss">
2023-12-22 09:50:03 +08:00
@keyframes round {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.drawer-back {
@apply absolute bg-cover bg-center;
2023-12-22 09:50:03 +08:00
z-index: -1;
width: 200%;
height: 200%;
top: -50%;
left: -50%;
}
2023-12-27 14:39:52 +08:00
.drawer-back.paused {
animation-play-state: paused;
}
2021-11-09 11:34:09 +08:00
#drawer-target {
@apply top-0 left-0 absolute overflow-hidden rounded px-24 flex items-center justify-center w-full h-full pb-8;
backdrop-filter: blur(20px);
2021-11-09 11:34:09 +08:00
animation-duration: 300ms;
2021-11-09 11:34:09 +08:00
.music-img {
@apply flex-1 flex justify-center mr-16 flex-col;
max-width: 360px;
max-height: 360px;
2021-11-09 11:34:09 +08:00
.img {
@apply rounded-xl w-full h-full shadow-2xl;
2021-11-09 11:34:09 +08:00
}
}
.music-content {
@apply flex flex-col justify-center items-center relative;
2021-11-09 11:34:09 +08:00
&-name {
@apply font-bold text-xl pb-1 pt-4;
2021-11-09 11:34:09 +08:00
}
2021-11-09 11:34:09 +08:00
&-singer {
@apply text-base;
2021-11-09 11:34:09 +08:00
}
}
.music-content-time {
2023-12-27 14:39:52 +08:00
display: none;
@apply flex justify-center items-center;
2023-12-27 14:39:52 +08:00
}
2021-11-09 11:34:09 +08:00
.music-lrc {
background-color: inherit;
2023-12-19 14:42:53 +08:00
width: 500px;
2021-11-09 11:34:09 +08:00
height: 550px;
&-text {
@apply text-2xl cursor-pointer font-bold px-2 py-4;
color: #ffffff8a;
// transition: all 0.5s ease;
span {
padding-right: 100px;
}
2021-11-09 11:34:09 +08:00
&:hover {
@apply font-bold opacity-100 rounded-xl;
background-color: #ffffff26;
color: #fff;
2021-11-09 11:34:09 +08:00
}
&-tr {
@apply font-normal;
}
2021-11-09 11:34:09 +08:00
}
}
}
2024-05-23 17:12:35 +08:00
.mobile {
#drawer-target {
@apply flex-col p-4 pt-8;
.music-img {
display: none;
}
.music-lrc {
height: calc(100vh - 260px) !important;
}
}
}
2023-12-18 15:24:57 +08:00
</style>