🌈 style: 优化桌面歌词样式

This commit is contained in:
imsyy
2025-11-06 01:07:04 +08:00
parent 9fcd5b0e98
commit a556a2e102
5 changed files with 148 additions and 50 deletions

View File

@@ -62,9 +62,14 @@ const initLyricIpc = (): void => {
});
// 更新歌词窗口配置
ipcMain.on("update-desktop-lyric-option", (_, option) => {
ipcMain.on("update-desktop-lyric-option", (_, option, callback: boolean = false) => {
if (!option || !isWinAlive(lyricWin)) return;
lyricWin.webContents.send("desktop-lyric-option-change", option);
store.set("lyric.config", option);
// 触发窗口更新
if (callback && isWinAlive(lyricWin)) {
lyricWin.webContents.send("update-desktop-lyric-option", option);
}
mainWin?.webContents.send("update-desktop-lyric-option", option);
});
// 播放状态更改
@@ -132,18 +137,14 @@ const initLyricIpc = (): void => {
});
// 获取配置
ipcMain.handle("get-desktop-lyric-option", () => {
return store.get("lyric");
});
ipcMain.handle("request-desktop-lyric-option", () => {
const config = store.get("lyric.config");
console.log(config);
// 保存配置
ipcMain.on("set-desktop-lyric-option", (_, option, callback: boolean = false) => {
store.set("lyric", option);
// 触发窗口更新
if (callback && isWinAlive(lyricWin)) {
lyricWin.webContents.send("desktop-lyric-option-change", option);
if (isWinAlive(lyricWin)) {
lyricWin.webContents.send("update-desktop-lyric-option", config);
}
mainWin?.webContents.send("desktop-lyric-option-change", option);
return config;
});
// 发送主程序事件

View File

@@ -2,6 +2,7 @@ import { BrowserWindow } from "electron";
import { createWindow } from "./index";
import { useStore } from "../store";
import { lyricWinUrl } from "../utils/config";
import mainWindow from "./main-window";
class LyricWindow {
private win: BrowserWindow | null = null;
@@ -25,6 +26,11 @@ class LyricWindow {
store.set("lyric", { ...store.get("lyric"), width, height });
}
});
// 歌词窗口关闭
this.win?.on("close", () => {
const mainWin = mainWindow?.getWin();
mainWin?.webContents.send("closeDesktopLyric");
});
}
/**
* 创建主窗口

View File

@@ -331,6 +331,60 @@
@update:value="player.toggleDesktopLyric"
/>
</n-card>
<n-card class="set-item">
<div class="label">
<n-text class="name">锁定桌面歌词位置</n-text>
<n-text class="tip" :depth="3">是否锁定桌面歌词位置防止误触或遮挡内容</n-text>
</div>
<n-switch
v-model:value="desktopLyricConfig.isLock"
:round="false"
class="set"
@update:value="saveDesktopLyricConfig"
/>
</n-card>
<n-card class="set-item">
<div class="label">
<n-text class="name">双行歌词</n-text>
<n-text class="tip" :depth="3">是否启用双行歌词交替显示当前句和下一句</n-text>
</div>
<n-switch
v-model:value="desktopLyricConfig.isDoubleLine"
:round="false"
class="set"
@update:value="saveDesktopLyricConfig"
/>
</n-card>
<n-card class="set-item">
<div class="label">
<n-text class="name">限制歌词位置</n-text>
<n-text class="tip" :depth="3">是否限制桌面歌词位置在当前屏幕内</n-text>
</div>
<n-switch
v-model:value="desktopLyricConfig.limitBounds"
:round="false"
class="set"
@update:value="saveDesktopLyricConfig"
/>
</n-card>
<!-- position -->
<n-card class="set-item">
<div class="label">
<n-text class="name">对齐方式</n-text>
<n-text class="tip" :depth="3">桌面歌词对齐方式</n-text>
</div>
<n-select
v-model:value="desktopLyricConfig.position"
:options="[
{ label: '左对齐', value: 'left' },
{ label: '居中对齐', value: 'center' },
{ label: '右对齐', value: 'right' },
{ label: '左右分离', value: 'both' },
]"
class="set"
@update:value="saveDesktopLyricConfig"
/>
</n-card>
<n-card class="set-item">
<div class="label">
<n-text class="name">桌面歌词文字大小</n-text>
@@ -352,11 +406,24 @@
</n-card>
<n-card class="set-item">
<div class="label">
<n-text class="name">主题色</n-text>
<n-text class="tip" :depth="3">桌面歌词文字</n-text>
<n-text class="name">已播放文字</n-text>
<n-text class="tip" :depth="3">桌面歌词已播放文字</n-text>
</div>
<n-color-picker
v-model:value="desktopLyricConfig.mainColor"
v-model:value="desktopLyricConfig.playedColor"
:show-alpha="false"
:modes="['hex']"
class="set"
@complete="saveDesktopLyricConfig"
/>
</n-card>
<n-card class="set-item">
<div class="label">
<n-text class="name">未播放文字</n-text>
<n-text class="tip" :depth="3">桌面歌词未播放文字颜色</n-text>
</div>
<n-color-picker
v-model:value="desktopLyricConfig.unplayedColor"
:show-alpha="false"
:modes="['hex']"
class="set"
@@ -390,27 +457,34 @@
import { useSettingStore, useStatusStore } from "@/stores";
import { cloneDeep, isEqual } from "lodash-es";
import { isElectron } from "@/utils/env";
import player from "@/utils/player";
import { openLyricExclude } from "@/utils/modal";
import player from "@/utils/player";
import { LyricConfig } from "@/types/desktop-lyric";
const statusStore = useStatusStore();
const settingStore = useSettingStore();
// 桌面歌词配置
const defaultDesktopLyricConfig = {
fontSize: 30,
mainColor: "#fff",
isLock: false,
playedColor: "#fe7971",
unplayedColor: "#ccc",
shadowColor: "rgba(0, 0, 0, 0.5)",
};
const desktopLyricConfig = reactive({ ...defaultDesktopLyricConfig });
fontFamily: "system-ui",
fontSize: 24,
isDoubleLine: true,
position: "both",
limitBounds: false,
} as LyricConfig;
const desktopLyricConfig = reactive<LyricConfig>({ ...defaultDesktopLyricConfig });
// 获取桌面歌词配置
const getDesktopLyricConfig = async () => {
if (!isElectron) return;
const config = await window.electron.ipcRenderer.invoke("get-desktop-lyric-option");
const config = await window.electron.ipcRenderer.invoke("request-desktop-lyric-option");
if (config) Object.assign(desktopLyricConfig, config);
// 监听更新
window.electron.ipcRenderer.on("desktop-lyric-option-change", (_, config) => {
window.electron.ipcRenderer.on("update-desktop-lyric-option", (_, config) => {
if (config && !isEqual(desktopLyricConfig, config)) {
Object.assign(desktopLyricConfig, config);
}
@@ -423,7 +497,7 @@ const saveDesktopLyricConfig = () => {
if (!isElectron) return;
console.log(cloneDeep(desktopLyricConfig));
window.electron.ipcRenderer.send(
"set-desktop-lyric-option",
"update-desktop-lyric-option",
cloneDeep(desktopLyricConfig),
true,
);
@@ -439,7 +513,11 @@ const saveDesktopLyricConfig = () => {
const restoreDesktopLyricConfig = () => {
try {
if (!isElectron) return;
window.electron.ipcRenderer.send("set-desktop-lyric-option", defaultDesktopLyricConfig, true);
window.electron.ipcRenderer.send(
"update-desktop-lyric-option",
defaultDesktopLyricConfig,
true,
);
window.$message.success("桌面歌词配置已恢复默认");
console.log(defaultDesktopLyricConfig, desktopLyricConfig);
} catch (error) {

View File

@@ -23,10 +23,8 @@ export interface LyricConfig {
playedColor: string;
/** 未播放颜色 */
unplayedColor: string;
/** 描边 */
stroke: string;
/** 描边宽度 */
strokeWidth: number;
/** 阴影颜色 */
shadowColor: string;
/** 字体 */
fontFamily: string;
/** 字体大小 */

View File

@@ -1,7 +1,7 @@
<template>
<n-config-provider :theme="null">
<div
ref="desktopLyricsRef"
ref="desktopLyricRef"
:class="[
'desktop-lyric',
{
@@ -23,17 +23,17 @@
<span class="song-name">{{ lyricData.playName }}</span>
</n-flex>
<n-flex :wrap="false" align="center" justify="center" size="small" @pointerdown.stop>
<div class="menu-btn" title="上一曲" @click.stop="sendToMain('playPrev')">
<div class="menu-btn" title="上一曲" @click.stop="sendToMainWin('playPrev')">
<SvgIcon name="SkipPrev" />
</div>
<div
class="menu-btn"
:title="lyricData.playStatus ? '暂停' : '播放'"
@click.stop="sendToMain('playOrPause')"
@click.stop="sendToMainWin('playOrPause')"
>
<SvgIcon :name="lyricData.playStatus ? 'Pause' : 'Play'" />
</div>
<div class="menu-btn" title="下一曲" @click.stop="sendToMain('playNext')">
<div class="menu-btn" title="下一曲" @click.stop="sendToMainWin('playNext')">
<SvgIcon name="SkipNext" />
</div>
</n-flex>
@@ -44,7 +44,7 @@
<div class="menu-btn" title="解锁">
<SvgIcon name="LockOpen" />
</div>
<div class="menu-btn" title="关闭">
<div class="menu-btn" title="关闭" @click.stop="sendToMain('closeDesktopLyric')">
<SvgIcon name="Close" />
</div>
</n-flex>
@@ -53,6 +53,7 @@
:style="{
fontSize: lyricConfig.fontSize + 'px',
fontFamily: lyricConfig.fontFamily,
textShadow: `0 0 4px ${lyricConfig.shadowColor}`,
}"
:class="['lyric-container', lyricConfig.position]"
vertical
@@ -67,6 +68,10 @@
>
{{ line.text }}
</span>
<!-- 占位 -->
<span v-if="lyricConfig.isDoubleLine && renderLyricLines.length === 1" class="lyric-line">
&nbsp;
</span>
</n-flex>
</div>
</n-config-provider>
@@ -91,8 +96,7 @@ const lyricConfig = reactive<LyricConfig>({
isLock: false,
playedColor: "#fe7971",
unplayedColor: "#ccc",
stroke: "#000",
strokeWidth: 2,
shadowColor: "rgba(0, 0, 0, 0.5)",
fontFamily: "system-ui",
fontSize: 24,
isDoubleLine: true,
@@ -101,7 +105,7 @@ const lyricConfig = reactive<LyricConfig>({
});
// 桌面歌词元素
const desktopLyricsRef = useTemplateRef<HTMLElement>("desktopLyricsRef");
const desktopLyricRef = ref<HTMLElement>();
/**
* 渲染的歌词行
@@ -207,7 +211,7 @@ const lyricDragMove = async (_position: Position, event: PointerEvent) => {
};
// 监听桌面歌词拖动
useDraggable(desktopLyricsRef, {
useDraggable(desktopLyricRef, {
onStart: (position, event) => {
lyricDragStart(position, event);
},
@@ -219,28 +223,27 @@ useDraggable(desktopLyricsRef, {
},
});
// 发送至主窗口
// 发送至主进程
const sendToMain = (eventName: string, ...args: any[]) => {
// 特殊处理
if (eventName === "win-show") {
window.electron.ipcRenderer.send("win-show");
return;
}
window.electron.ipcRenderer.send("send-to-main", eventName, ...args);
window.electron.ipcRenderer.send(eventName, ...args);
};
// 处理歌词数据
const handleLyricData = (data: LyricData) => {
Object.assign(lyricData, data);
// 发送至主窗口
const sendToMainWin = (eventName: string, ...args: any[]) => {
window.electron.ipcRenderer.send("send-to-main", eventName, ...args);
};
onMounted(() => {
// 接收歌词数据
window.electron.ipcRenderer.on("update-desktop-lyric-data", (_event, data: LyricData) => {
handleLyricData(data);
Object.assign(lyricData, data);
});
window.electron.ipcRenderer.on("update-desktop-lyric-option", (_event, config: LyricConfig) => {
Object.assign(lyricConfig, config);
});
// 请求歌词数据及配置
window.electron.ipcRenderer.send("request-desktop-lyric-data");
window.electron.ipcRenderer.invoke("request-desktop-lyric-option");
});
</script>
@@ -254,7 +257,6 @@ onMounted(() => {
background-color: transparent;
padding: 12px;
border-radius: 12px;
height: 100%;
overflow: hidden;
transition: background-color 0.3s;
cursor: move;
@@ -305,16 +307,29 @@ onMounted(() => {
}
.lyric-container {
padding: 0 8px;
.lyric-line {
// 单行
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&.center {
align-items: center;
.lyric-line {
text-align: center;
}
}
&.right {
align-items: flex-end;
.lyric-line {
text-align: right;
}
}
&.both {
.lyric-line {
&:nth-child(2n) {
margin-left: auto;
text-align: right;
}
}
}