feat: 优化播放样式 优化歌曲背景色 优化 mv播放样式 添加循环播放 等控制功能

This commit is contained in:
alger
2024-11-23 22:42:23 +08:00
parent 3027a5f6ff
commit 0bb14902f2
9 changed files with 1137 additions and 92 deletions
+101 -18
View File
@@ -1,5 +1,10 @@
<template>
<n-drawer :show="musicFull" height="100vh" placement="bottom" :style="{ background: background }">
<n-drawer
:show="musicFull"
height="100vh"
placement="bottom"
:style="{ background: currentBackground || background }"
>
<div id="drawer-target">
<div class="drawer-back"></div>
<div class="music-img">
@@ -48,25 +53,22 @@
<script setup lang="ts">
import { useDebounceFn } from '@vueuse/core';
import { onBeforeUnmount, ref, watch } from 'vue';
import {
addCorrectionTime,
lrcArray,
nowIndex,
playMusic,
reduceCorrectionTime,
setAudioTime,
useLyricProgress,
} from '@/hooks/MusicHook';
import { lrcArray, nowIndex, playMusic, setAudioTime, useLyricProgress } from '@/hooks/MusicHook';
import { getImgUrl } from '@/utils';
import { animateGradient, getHoverBackgroundColor, getTextColors } from '@/utils/linearColor';
const { getLrcStyle } = useLyricProgress();
// const isPlaying = computed(() => store.state.play as boolean);
// 获取歌词滚动dom
// 定义 refs
const lrcSider = ref<any>(null);
const isMouse = ref(false);
const lrcContainer = ref<HTMLElement | null>(null);
const currentBackground = ref('');
const animationFrame = ref<number | null>(null);
const isDark = ref(false);
// 初始化 textColors
const textColors = ref(getTextColors());
const props = defineProps({
musicFull: {
@@ -122,6 +124,73 @@ watch(
},
);
// 监听背景变化
watch(
() => props.background,
(newBg) => {
if (!newBg) {
textColors.value = getTextColors();
document.documentElement.style.setProperty('--hover-bg-color', getHoverBackgroundColor(false));
document.documentElement.style.setProperty('--text-color-primary', textColors.value.primary);
document.documentElement.style.setProperty('--text-color-active', textColors.value.active);
return;
}
if (currentBackground.value) {
if (animationFrame.value) {
cancelAnimationFrame(animationFrame.value);
}
animationFrame.value = animateGradient(currentBackground.value, newBg, (gradient) => {
currentBackground.value = gradient;
});
} else {
currentBackground.value = newBg;
}
textColors.value = getTextColors(newBg);
isDark.value = textColors.value.active === '#000000';
document.documentElement.style.setProperty('--hover-bg-color', getHoverBackgroundColor(isDark.value));
document.documentElement.style.setProperty('--text-color-primary', textColors.value.primary);
document.documentElement.style.setProperty('--text-color-active', textColors.value.active);
},
{ immediate: true },
);
// 修改 useLyricProgress 的使用方式
const { getLrcStyle: originalLrcStyle } = useLyricProgress();
// 修改 getLrcStyle 函数
const getLrcStyle = (index: number) => {
const colors = textColors.value || getTextColors;
const originalStyle = originalLrcStyle(index);
if (index === nowIndex.value) {
// 当前播放的歌词,使用渐变效果
return {
...originalStyle,
backgroundImage: originalStyle.backgroundImage
?.replace(/#ffffff/g, colors.active)
.replace(/#ffffff8a/g, `${colors.primary}`),
backgroundClip: 'text',
WebkitBackgroundClip: 'text',
color: 'transparent',
};
}
// 非当前播放的歌词,使用普通颜色
return {
color: colors.primary,
};
};
// 组件卸载时清理动画
onBeforeUnmount(() => {
if (animationFrame.value) {
cancelAnimationFrame(animationFrame.value);
}
});
defineExpose({
lrcScroll,
});
@@ -185,19 +254,29 @@ defineExpose({
height: 550px;
&-text {
@apply text-2xl cursor-pointer font-bold px-2 py-4;
color: #ffffff8a;
// transition: all 0.5s ease;
transition: all 0.3s ease;
background-color: transparent;
span {
padding-right: 100px;
display: inline-block;
background-clip: text !important;
-webkit-background-clip: text !important;
}
&:hover {
@apply font-bold opacity-100 rounded-xl;
background-color: #ffffff26;
color: #fff;
background-color: var(--hover-bg-color);
span {
color: var(--text-color-active) !important;
}
}
&-tr {
@apply font-normal;
opacity: 0.7;
color: var(--text-color-primary);
}
}
}
@@ -214,4 +293,8 @@ defineExpose({
}
}
}
.music-drawer {
transition: none; // 移除之前的过渡效果,现在使用 JS 动画
}
</style>
+36 -4
View File
@@ -43,12 +43,12 @@
<i class="iconfont icon-next"></i>
</div>
</div>
<div class="music-time">
<div class="music-time custom-slider">
<div class="time">{{ getNowTime }}</div>
<n-slider v-model:value="timeSlider" :step="0.05" :tooltip="false"></n-slider>
<div class="time">{{ getAllTime }}</div>
</div>
<div class="audio-volume">
<div class="audio-volume custom-slider">
<div>
<i class="iconfont icon-notificationfill"></i>
</div>
@@ -267,8 +267,7 @@ const scrollToPlayList = (val: boolean) => {
}
&-name {
@apply text-xs mt-1;
@apply text-gray-400;
@apply text-xs mt-1 text-gray-100;
}
}
}
@@ -376,4 +375,37 @@ const scrollToPlayList = (val: boolean) => {
flex: 1;
}
}
// 添加自定义 slider 样式
.custom-slider {
:deep(.n-slider) {
--n-rail-height: 4px;
--n-rail-color: rgba(255, 255, 255, 0.2);
--n-fill-color: var(--primary-color);
--n-handle-size: 12px;
--n-handle-color: var(--primary-color);
&:hover {
--n-rail-height: 6px;
--n-handle-size: 14px;
}
.n-slider-rail {
@apply overflow-hidden;
}
.n-slider-handle {
@apply transition-opacity duration-200;
opacity: 0;
}
&:hover .n-slider-handle {
opacity: 1;
}
}
}
:root {
--primary-color: #18a058;
}
</style>