mirror of
https://github.com/imsyy/SPlayer.git
synced 2025-11-25 03:14:57 +08:00
🌈 style: 优化桌面歌词样式
This commit is contained in:
@@ -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;
|
||||
});
|
||||
|
||||
// 发送主程序事件
|
||||
|
||||
@@ -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");
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 创建主窗口
|
||||
|
||||
@@ -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) {
|
||||
|
||||
6
src/types/desktop-lyric.d.ts
vendored
6
src/types/desktop-lyric.d.ts
vendored
@@ -23,10 +23,8 @@ export interface LyricConfig {
|
||||
playedColor: string;
|
||||
/** 未播放颜色 */
|
||||
unplayedColor: string;
|
||||
/** 描边 */
|
||||
stroke: string;
|
||||
/** 描边宽度 */
|
||||
strokeWidth: number;
|
||||
/** 阴影颜色 */
|
||||
shadowColor: string;
|
||||
/** 字体 */
|
||||
fontFamily: string;
|
||||
/** 字体大小 */
|
||||
|
||||
@@ -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">
|
||||
|
||||
</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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user