From 9967bcb102e9d400d278ed2f5d262dce3641cb32 Mon Sep 17 00:00:00 2001 From: imsyy Date: Tue, 28 Oct 2025 00:33:40 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=88=20style:=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=92=AD=E6=94=BE=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Player/FullPlayer.vue | 57 +----- src/components/Player/PlayerBackground.vue | 130 +++++++------- src/components/Player/PlayerData.vue | 14 +- src/components/Setting/PlaySetting.vue | 6 - src/utils/fluidBackground.ts | 195 --------------------- src/utils/lyric.ts | 11 ++ src/utils/player.ts | 8 +- 7 files changed, 89 insertions(+), 332 deletions(-) delete mode 100644 src/utils/fluidBackground.ts diff --git a/src/components/Player/FullPlayer.vue b/src/components/Player/FullPlayer.vue index ad59e7f..7aa14f9 100644 --- a/src/components/Player/FullPlayer.vue +++ b/src/components/Player/FullPlayer.vue @@ -8,27 +8,8 @@ class="full-player" @mouseleave="playerLeave" > - - -
- - cover - - -
-
+ +
{ backdrop-filter: blur(80px); overflow: hidden; z-index: 1000; - .overlay { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - overflow: hidden; - z-index: -1; - &::after { - content: ""; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.5); - backdrop-filter: blur(20px); - } - &.blur { - display: flex; - align-items: center; - justify-content: center; - .overlay-img { - width: 100%; - height: auto; - transform: scale(1.5); - filter: blur(80px) contrast(1.2); - } - } - } .lrc-instant { position: absolute; top: 0; @@ -269,8 +220,8 @@ onBeforeUnmount(() => { justify-content: center; transition: width 0.3s, - opacity 0.3s, - transform 0.3s; + opacity 0.5s cubic-bezier(0.34, 1.56, 0.64, 1), + transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); } .content-right { position: absolute; diff --git a/src/components/Player/PlayerBackground.vue b/src/components/Player/PlayerBackground.vue index 9f04ea1..746fc60 100644 --- a/src/components/Player/PlayerBackground.vue +++ b/src/components/Player/PlayerBackground.vue @@ -1,71 +1,71 @@ - + + diff --git a/src/components/Player/PlayerData.vue b/src/components/Player/PlayerData.vue index 32b5d20..8357499 100644 --- a/src/components/Player/PlayerData.vue +++ b/src/components/Player/PlayerData.vue @@ -127,13 +127,6 @@ const jumpPage = debounce( line-clamp: 2; -webkit-line-clamp: 2; } - .extra-info { - position: absolute; - right: -34px; - display: flex; - align-items: center; - justify-content: center; - } .n-icon { margin-left: 12px; transform: translateY(1px); @@ -210,6 +203,13 @@ const jumpPage = debounce( .name-text { font-size: 30px; } + .extra-info { + position: absolute; + right: -34px; + display: flex; + align-items: center; + justify-content: center; + } } } &.center { diff --git a/src/components/Setting/PlaySetting.vue b/src/components/Setting/PlaySetting.vue index e42b884..67a65db 100644 --- a/src/components/Setting/PlaySetting.vue +++ b/src/components/Setting/PlaySetting.vue @@ -128,14 +128,8 @@ }, { label: '封面主色', - disabled: true, value: 'color', }, - { - label: '无背景', - disabled: true, - value: 'none', - }, ]" class="set" /> diff --git a/src/utils/fluidBackground.ts b/src/utils/fluidBackground.ts deleted file mode 100644 index 13c0c1c..0000000 --- a/src/utils/fluidBackground.ts +++ /dev/null @@ -1,195 +0,0 @@ -import type { RGB } from "@/types/main"; - -// 配置选项 -interface FluidBackgroundType { - canvas: HTMLCanvasElement; - colors?: RGB[]; - totalParticles?: number; - maxRadius?: number; - minRadius?: number; - speed?: number; -} - -// App 类,负责管理整个画布和动画的主逻辑 -export class FluidBackground { - private canvas: HTMLCanvasElement; - private ctx: CanvasRenderingContext2D; - private pixelRatio: number; - private colors: RGB[]; - private totalParticles: number; - private maxRadius: number; - private minRadius: number; - private speed: number; - private particles: GlowParticle[]; - private stageWidth!: number; - private stageHeight!: number; - - constructor({ - canvas, - colors, - totalParticles, - maxRadius, - minRadius, - speed, - }: FluidBackgroundType) { - // 使用传入的 canvas 元素 - this.canvas = canvas; - - // 获取 2D 绘图上下文 - this.ctx = this.canvas.getContext("2d")!; - - // 根据设备像素比设置比例,处理高清屏幕的显示问题 - this.pixelRatio = window.devicePixelRatio > 1 ? 2 : 1; - - // 设置颜色数组,粒子的颜色将从这个数组中选择 - this.colors = colors || [ - { r: 45, g: 74, b: 227 }, - { r: 250, g: 255, b: 89 }, - { r: 255, g: 104, b: 248 }, - { r: 44, g: 209, b: 252 }, - { r: 54, g: 233, b: 84 }, - ]; - - // 设置色块球的数量,默认值为 15 - this.totalParticles = totalParticles || 15; - - // 设置色块球的最大和最小半径,默认值分别为 200 和 150 - this.maxRadius = maxRadius || 200; - this.minRadius = minRadius || 150; - - // 设置色块球的运动速度,默认值为 2 - this.speed = speed || 2; - - // 保存色块球的数组 - this.particles = []; - - // 监听窗口大小变化,调整画布尺寸 - window.addEventListener("resize", this.resize.bind(this), false); - - // 初始化画布大小和色块球 - this.resize(); - - // 启动动画 - this.animate(); - } - - // 处理画布大小调整的方法 - private resize() { - // 获取当前窗口的宽度和高度 - this.stageWidth = window.innerWidth; - this.stageHeight = window.innerHeight; - - // 设置画布的宽度和高度,并根据设备像素比进行缩放 - this.canvas.width = this.stageWidth * this.pixelRatio; - this.canvas.height = this.stageHeight * this.pixelRatio; - this.ctx.scale(this.pixelRatio, this.pixelRatio); - - // 设置混合模式,使色块球重叠时产生更丰富的颜色效果 - this.ctx.globalCompositeOperation = "saturation"; - - // 创建色块球 - this.createParticles(); - } - - // 创建色块球的逻辑 - private createParticles() { - let curColor = 0; - this.particles = []; // 清空粒子数组 - for (let i = 0; i < this.totalParticles; i++) { - // 随机生成色块球的初始位置和半径 - this.particles.push( - new GlowParticle( - Math.random() * this.stageWidth, // 随机生成 X 位置 - Math.random() * this.stageHeight, // 随机生成 Y 位置 - Math.random() * (this.maxRadius - this.minRadius) + this.minRadius, // 随机生成半径 - this.colors[curColor % this.colors.length], // 循环选择颜色 - this.speed, // 传递速度 - ), - ); - curColor++; // 颜色索引递增 - } - } - - // 动画帧渲染方法 - private animate() { - // 使用 requestAnimationFrame 来创建动画循环 - window.requestAnimationFrame(this.animate.bind(this)); - - // 清除画布上的内容 - this.ctx.clearRect(0, 0, this.stageWidth, this.stageHeight); - - // 遍历每个色块球并调用其 animate 方法进行绘制和更新位置 - for (let i = 0; i < this.totalParticles; i++) { - const item = this.particles[i]; - item.animate(this.ctx, this.stageWidth, this.stageHeight); - } - } -} - -// GlowParticle 类,表示单个色块球 -class GlowParticle { - private x: number; - private y: number; - private radius: number; - private rgb: RGB; - private vx: number; - private vy: number; - private sinValue: number; - - constructor(x: number, y: number, radius: number, rgb: RGB, speed: number) { - this.x = x; // 初始 X 位置 - this.y = y; // 初始 Y 位置 - this.radius = radius; // 半径 - this.rgb = rgb; // 颜色对象 {r, g, b} - this.vx = Math.random() * speed; // 随机生成 X 方向的速度 - this.vy = Math.random() * speed; // 随机生成 Y 方向的速度 - this.sinValue = Math.random(); // 用于控制半径变化的正弦值 - } - - // 动画方法,更新位置和绘制色块球 - animate(ctx: CanvasRenderingContext2D, stageWidth: number, stageHeight: number) { - // 更新正弦值,使色块球的半径产生波动效果 - this.sinValue += 0.01; - this.radius += Math.sin(this.sinValue); // 半径在正弦波动下变化 - - // 更新 X 和 Y 位置 - this.x += this.vx; - this.y += this.vy; - - // 边界检测,如果超出画布边界则反向运动 - if (this.x < -10 || this.x > stageWidth + 10) { - this.vx *= -1; - } - if (this.y < -10 || this.y > stageHeight + 10) { - this.vy *= -1; - } - - // 开始绘制色块球 - ctx.beginPath(); - - // 创建径向渐变,用于色块球的颜色过渡效果 - const g = ctx.createRadialGradient( - this.x, - this.y, - this.radius * 0.01, // 渐变起始半径 - this.x, - this.y, - this.radius, // 渐变结束半径 - ); - - // 定义渐变颜色的起始点和结束点 - g.addColorStop(0, `rgba(${this.rgb.r},${this.rgb.g},${this.rgb.b},1)`); - g.addColorStop(1, `rgba(${this.rgb.r},${this.rgb.g},${this.rgb.b},0)`); - - // 设置填充样式为渐变 - ctx.fillStyle = g; - - // 画一个圆,表示色块球 - ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false); - - // 填充圆形 - ctx.fill(); - } -} - -export default FluidBackground; diff --git a/src/utils/lyric.ts b/src/utils/lyric.ts index 491ccde..4ff6c5b 100644 --- a/src/utils/lyric.ts +++ b/src/utils/lyric.ts @@ -48,6 +48,8 @@ export const resetSongLyric = () => { yrcAMData: [], }; statusStore.usingTTMLLyric = false; + // 重置歌词索引 + statusStore.lyricIndex = -1; }; /** @@ -58,6 +60,7 @@ export const resetSongLyric = () => { */ export const parsedLyricsData = (lyricData: any, skipExclude: boolean = false): void => { const musicStore = useMusicStore(); + const statusStore = useStatusStore(); if (lyricData.code !== 200) { resetSongLyric(); return; @@ -105,6 +108,8 @@ export const parsedLyricsData = (lyricData: any, skipExclude: boolean = false): lrcAMData: parseAMData(lrcParseData, tlyricParseData, romalrcParseData, skipExclude), yrcAMData: parseAMData(yrcParseData, ytlrcParseData, yromalrcParseData, skipExclude), }; + // 重置歌词索引 + statusStore.lyricIndex = -1; }; /** @@ -257,6 +262,7 @@ export const parseLocalLyric = (lyric: string, format: "lrc" | "ttml") => { */ const parseLocalLyricLrc = (lyric: string) => { const musicStore = useMusicStore(); + const statusStore = useStatusStore(); const settingStore = useSettingStore(); // 解析 const lrc: LyricLine[] = parseLrc(lyric); @@ -290,6 +296,8 @@ const parseLocalLyricLrc = (lyric: string) => { yrcData: [], yrcAMData: [], }; + // 重置歌词索引 + statusStore.lyricIndex = -1; }; /** @@ -298,6 +306,7 @@ const parseLocalLyricLrc = (lyric: string) => { */ const parseLocalLyricAM = (lyric: string) => { const musicStore = useMusicStore(); + const statusStore = useStatusStore(); const settingStore = useSettingStore(); const skipExcludeLocal = !settingStore.enableExcludeLocalLyrics; @@ -313,6 +322,8 @@ const parseLocalLyricAM = (lyric: string) => { yrcAMData, yrcData, }; + // 重置歌词索引 + statusStore.lyricIndex = -1; }; /** diff --git a/src/utils/player.ts b/src/utils/player.ts index 01b973c..4df1c4f 100644 --- a/src/utils/player.ts +++ b/src/utils/player.ts @@ -693,14 +693,12 @@ class Player { } // 只有一首歌的特殊处理 if (playListLength === 1) { - statusStore.lyricIndex = -1; this.setSeek(0); await this.play(); return; } // 单曲循环 if (playSongMode === "repeat-once" && autoEnd && !playHeartbeatMode) { - statusStore.lyricIndex = -1; this.setSeek(0); await this.play(); return; @@ -723,8 +721,7 @@ class Player { } else if (statusStore.playIndex >= playListLength) { statusStore.playIndex = 0; } - // 重置播放进度和歌词索引(切换歌曲时必须重置) - statusStore.lyricIndex = -1; + // 重置播放进度(切换歌曲时必须重置) statusStore.currentTime = 0; statusStore.progress = 0; // 暂停 @@ -995,8 +992,7 @@ class Player { } // 更改状态 statusStore.playIndex = index; - // 重置播放进度和歌词索引(切换歌曲时必须重置) - statusStore.lyricIndex = -1; + // 重置播放进度(切换歌曲时必须重置) statusStore.currentTime = 0; statusStore.progress = 0;