mirror of
https://github.com/imsyy/SPlayer.git
synced 2025-11-25 11:29:26 +08:00
🌈 style: 优化歌词与桌面歌词样式问题
This commit is contained in:
5
components.d.ts
vendored
5
components.d.ts
vendored
@@ -61,8 +61,11 @@ declare module 'vue' {
|
|||||||
NDrawerContent: typeof import('naive-ui')['NDrawerContent']
|
NDrawerContent: typeof import('naive-ui')['NDrawerContent']
|
||||||
NDropdown: typeof import('naive-ui')['NDropdown']
|
NDropdown: typeof import('naive-ui')['NDropdown']
|
||||||
NDynamicTags: typeof import('naive-ui')['NDynamicTags']
|
NDynamicTags: typeof import('naive-ui')['NDynamicTags']
|
||||||
|
NEllipsis: typeof import('naive-ui')['NEllipsis']
|
||||||
NEmpty: typeof import('naive-ui')['NEmpty']
|
NEmpty: typeof import('naive-ui')['NEmpty']
|
||||||
NFlex: typeof import('naive-ui')['NFlex']
|
NFlex: typeof import('naive-ui')['NFlex']
|
||||||
|
NFloatButton: typeof import('naive-ui')['NFloatButton']
|
||||||
|
NFloatButtonGroup: typeof import('naive-ui')['NFloatButtonGroup']
|
||||||
NForm: typeof import('naive-ui')['NForm']
|
NForm: typeof import('naive-ui')['NForm']
|
||||||
NFormItem: typeof import('naive-ui')['NFormItem']
|
NFormItem: typeof import('naive-ui')['NFormItem']
|
||||||
NFormItemGi: typeof import('naive-ui')['NFormItemGi']
|
NFormItemGi: typeof import('naive-ui')['NFormItemGi']
|
||||||
@@ -70,6 +73,7 @@ declare module 'vue' {
|
|||||||
NGlobalStyle: typeof import('naive-ui')['NGlobalStyle']
|
NGlobalStyle: typeof import('naive-ui')['NGlobalStyle']
|
||||||
NGrid: typeof import('naive-ui')['NGrid']
|
NGrid: typeof import('naive-ui')['NGrid']
|
||||||
NH1: typeof import('naive-ui')['NH1']
|
NH1: typeof import('naive-ui')['NH1']
|
||||||
|
NH2: typeof import('naive-ui')['NH2']
|
||||||
NH3: typeof import('naive-ui')['NH3']
|
NH3: typeof import('naive-ui')['NH3']
|
||||||
NIcon: typeof import('naive-ui')['NIcon']
|
NIcon: typeof import('naive-ui')['NIcon']
|
||||||
NImage: typeof import('naive-ui')['NImage']
|
NImage: typeof import('naive-ui')['NImage']
|
||||||
@@ -100,6 +104,7 @@ declare module 'vue' {
|
|||||||
NSelect: typeof import('naive-ui')['NSelect']
|
NSelect: typeof import('naive-ui')['NSelect']
|
||||||
NSkeleton: typeof import('naive-ui')['NSkeleton']
|
NSkeleton: typeof import('naive-ui')['NSkeleton']
|
||||||
NSlider: typeof import('naive-ui')['NSlider']
|
NSlider: typeof import('naive-ui')['NSlider']
|
||||||
|
NSpin: typeof import('naive-ui')['NSpin']
|
||||||
NSwitch: typeof import('naive-ui')['NSwitch']
|
NSwitch: typeof import('naive-ui')['NSwitch']
|
||||||
NTabPane: typeof import('naive-ui')['NTabPane']
|
NTabPane: typeof import('naive-ui')['NTabPane']
|
||||||
NTabs: typeof import('naive-ui')['NTabs']
|
NTabs: typeof import('naive-ui')['NTabs']
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
"@electron-toolkit/utils": "^4.0.0",
|
"@electron-toolkit/utils": "^4.0.0",
|
||||||
"@imsyy/color-utils": "^1.0.2",
|
"@imsyy/color-utils": "^1.0.2",
|
||||||
"@material/material-color-utilities": "^0.3.0",
|
"@material/material-color-utilities": "^0.3.0",
|
||||||
"@neteasecloudmusicapienhanced/api": "^4.29.15",
|
"@neteasecloudmusicapienhanced/api": "^4.29.16",
|
||||||
"@pixi/app": "^7.4.3",
|
"@pixi/app": "^7.4.3",
|
||||||
"@pixi/core": "^7.4.3",
|
"@pixi/core": "^7.4.3",
|
||||||
"@pixi/display": "^7.4.3",
|
"@pixi/display": "^7.4.3",
|
||||||
|
|||||||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@@ -34,8 +34,8 @@ importers:
|
|||||||
specifier: ^0.3.0
|
specifier: ^0.3.0
|
||||||
version: 0.3.0
|
version: 0.3.0
|
||||||
'@neteasecloudmusicapienhanced/api':
|
'@neteasecloudmusicapienhanced/api':
|
||||||
specifier: ^4.29.15
|
specifier: ^4.29.16
|
||||||
version: 4.29.15
|
version: 4.29.16
|
||||||
'@pixi/app':
|
'@pixi/app':
|
||||||
specifier: ^7.4.3
|
specifier: ^7.4.3
|
||||||
version: 7.4.3(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3))
|
version: 7.4.3(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3))
|
||||||
@@ -967,8 +967,8 @@ packages:
|
|||||||
'@material/material-color-utilities@0.3.0':
|
'@material/material-color-utilities@0.3.0':
|
||||||
resolution: {integrity: sha512-ztmtTd6xwnuh2/xu+Vb01btgV8SQWYCaK56CkRK8gEkWe5TuDyBcYJ0wgkMRn+2VcE9KUmhvkz+N9GHrqw/C0g==}
|
resolution: {integrity: sha512-ztmtTd6xwnuh2/xu+Vb01btgV8SQWYCaK56CkRK8gEkWe5TuDyBcYJ0wgkMRn+2VcE9KUmhvkz+N9GHrqw/C0g==}
|
||||||
|
|
||||||
'@neteasecloudmusicapienhanced/api@4.29.15':
|
'@neteasecloudmusicapienhanced/api@4.29.16':
|
||||||
resolution: {integrity: sha512-/dw0ON90NDXJnULEyKzGEvKjjkJyHYb9fJgKa1dxsN5AIN/tXNAu4AV2vMJcPGfA/NV7iRnLDEPS8ocJCbCU2w==}
|
resolution: {integrity: sha512-ml6cTErjJ/fn+E0wvlNGGoW74rDj3mfogO85xySuTCuX/Mdhuayv+pPtoSm5YDM6j26hHmS8+rV2ma4o16pUiw==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
@@ -5331,7 +5331,7 @@ snapshots:
|
|||||||
|
|
||||||
'@material/material-color-utilities@0.3.0': {}
|
'@material/material-color-utilities@0.3.0': {}
|
||||||
|
|
||||||
'@neteasecloudmusicapienhanced/api@4.29.15':
|
'@neteasecloudmusicapienhanced/api@4.29.16':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@unblockneteasemusic/server': 0.28.0
|
'@unblockneteasemusic/server': 0.28.0
|
||||||
axios: 1.13.2
|
axios: 1.13.2
|
||||||
|
|||||||
@@ -58,7 +58,10 @@
|
|||||||
]"
|
]"
|
||||||
:style="{
|
:style="{
|
||||||
filter: settingStore.lyricsBlur
|
filter: settingStore.lyricsBlur
|
||||||
? `blur(${Math.min(Math.abs(statusStore.lyricIndex - index) * 1.8, 10)}px)`
|
? (playSeek >= item.time && playSeek < item.endTime) ||
|
||||||
|
statusStore.lyricIndex === index
|
||||||
|
? 'blur(0)'
|
||||||
|
: `blur(${Math.min(Math.abs(statusStore.lyricIndex - index) * 1.8, 10)}px)`
|
||||||
: 'blur(0)',
|
: 'blur(0)',
|
||||||
}"
|
}"
|
||||||
@click="jumpSeek(item.time)"
|
@click="jumpSeek(item.time)"
|
||||||
|
|||||||
@@ -287,7 +287,10 @@
|
|||||||
</n-collapse-transition>
|
</n-collapse-transition>
|
||||||
</div>
|
</div>
|
||||||
<div class="set-list">
|
<div class="set-list">
|
||||||
<n-h3 prefix="bar"> Apple Music-like Lyrics </n-h3>
|
<n-h3 prefix="bar">
|
||||||
|
Apple Music-like Lyrics
|
||||||
|
<n-tag type="warning" size="small" round>Beta</n-tag>
|
||||||
|
</n-h3>
|
||||||
<n-card class="set-item">
|
<n-card class="set-item">
|
||||||
<div class="label">
|
<div class="label">
|
||||||
<n-text class="name">使用 Apple Music-like Lyrics</n-text>
|
<n-text class="name">使用 Apple Music-like Lyrics</n-text>
|
||||||
@@ -318,7 +321,10 @@
|
|||||||
</n-card>
|
</n-card>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isElectron" class="set-list">
|
<div v-if="isElectron" class="set-list">
|
||||||
<n-h3 prefix="bar"> 桌面歌词 </n-h3>
|
<n-h3 prefix="bar">
|
||||||
|
桌面歌词
|
||||||
|
<n-tag type="warning" size="small" round>Beta</n-tag>
|
||||||
|
</n-h3>
|
||||||
<n-card class="set-item">
|
<n-card class="set-item">
|
||||||
<div class="label">
|
<div class="label">
|
||||||
<n-text class="name">开启桌面歌词</n-text>
|
<n-text class="name">开启桌面歌词</n-text>
|
||||||
|
|||||||
@@ -195,6 +195,12 @@ const toGithub = () => {
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.n-h {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
.n-collapse-transition {
|
.n-collapse-transition {
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
&:last-child {
|
&:last-child {
|
||||||
|
|||||||
@@ -26,20 +26,20 @@ export const getLyricData = async (id: number) => {
|
|||||||
try {
|
try {
|
||||||
// 检测本地歌词覆盖
|
// 检测本地歌词覆盖
|
||||||
const getLyric = getLyricFun(settingStore.localLyricPath, id);
|
const getLyric = getLyricFun(settingStore.localLyricPath, id);
|
||||||
// 先加载 LRC,不阻塞到 TTML 完成
|
// 并发请求:如果 TTML 先到并且有效,则直接采用 TTML,不再等待或覆盖为 LRC
|
||||||
const lrcPromise = getLyric("lrc", songLyric);
|
const lrcPromise = getLyric("lrc", songLyric);
|
||||||
const ttmlPromise = settingStore.enableTTMLLyric ? getLyric("ttml", songLyricTTML) : null;
|
const ttmlPromise = settingStore.enableTTMLLyric ? getLyric("ttml", songLyricTTML) : null;
|
||||||
|
|
||||||
const { lyric: lyricRes, isLocal: lyricLocal } = await lrcPromise;
|
let settled = false; // 是否已采用某一种歌词并结束加载状态
|
||||||
parsedLyricsData(lyricRes, lyricLocal && !settingStore.enableExcludeLocalLyrics);
|
let ttmlAdopted = false; // 是否已采用 TTML
|
||||||
// LRC 到达后即可认为加载完成
|
|
||||||
statusStore.lyricLoading = false;
|
|
||||||
|
|
||||||
// TTML 并行加载,完成后增量更新,不阻塞整体流程
|
const adoptTTML = async () => {
|
||||||
if (ttmlPromise) {
|
if (!ttmlPromise) {
|
||||||
statusStore.usingTTMLLyric = false;
|
statusStore.usingTTMLLyric = false;
|
||||||
void ttmlPromise
|
return;
|
||||||
.then(({ lyric: ttmlContent, isLocal: ttmlLocal }) => {
|
}
|
||||||
|
try {
|
||||||
|
const { lyric: ttmlContent, isLocal: ttmlLocal } = await ttmlPromise;
|
||||||
if (!ttmlContent) {
|
if (!ttmlContent) {
|
||||||
statusStore.usingTTMLLyric = false;
|
statusStore.usingTTMLLyric = false;
|
||||||
return;
|
return;
|
||||||
@@ -54,33 +54,50 @@ export const getLyricData = async (id: number) => {
|
|||||||
const skipExclude = skipExcludeLocal || skipExcludeTTML;
|
const skipExclude = skipExcludeLocal || skipExcludeTTML;
|
||||||
const ttmlLyric = parseTTMLToAMLL(parsedResult, skipExclude);
|
const ttmlLyric = parseTTMLToAMLL(parsedResult, skipExclude);
|
||||||
const ttmlYrcLyric = parseTTMLToYrc(parsedResult, skipExclude);
|
const ttmlYrcLyric = parseTTMLToYrc(parsedResult, skipExclude);
|
||||||
console.log("TTML lyrics:", ttmlLyric, ttmlYrcLyric);
|
|
||||||
// 合并数据
|
|
||||||
const updates: Partial<{ yrcAMData: LyricLine[]; yrcData: LyricType[] }> = {};
|
const updates: Partial<{ yrcAMData: LyricLine[]; yrcData: LyricType[] }> = {};
|
||||||
if (ttmlLyric?.length) {
|
if (ttmlLyric?.length) updates.yrcAMData = ttmlLyric;
|
||||||
updates.yrcAMData = ttmlLyric;
|
if (ttmlYrcLyric?.length) updates.yrcData = ttmlYrcLyric;
|
||||||
console.log("✅ TTML AMLL lyrics success");
|
|
||||||
}
|
|
||||||
if (ttmlYrcLyric?.length) {
|
|
||||||
updates.yrcData = ttmlYrcLyric;
|
|
||||||
console.log("✅ TTML Yrc lyrics success");
|
|
||||||
}
|
|
||||||
if (Object.keys(updates).length) {
|
if (Object.keys(updates).length) {
|
||||||
musicStore.setSongLyric(updates);
|
musicStore.setSongLyric(updates);
|
||||||
statusStore.usingTTMLLyric = true;
|
statusStore.usingTTMLLyric = true;
|
||||||
|
ttmlAdopted = true;
|
||||||
|
if (!settled) {
|
||||||
|
statusStore.lyricLoading = false;
|
||||||
|
settled = true;
|
||||||
|
}
|
||||||
|
console.log("✅ TTML lyrics adopted (prefer TTML)");
|
||||||
} else {
|
} else {
|
||||||
statusStore.usingTTMLLyric = false;
|
statusStore.usingTTMLLyric = false;
|
||||||
}
|
}
|
||||||
})
|
} catch (err) {
|
||||||
.catch((err) => {
|
|
||||||
console.error("❌ Error loading TTML lyrics:", err);
|
console.error("❌ Error loading TTML lyrics:", err);
|
||||||
statusStore.usingTTMLLyric = false;
|
statusStore.usingTTMLLyric = false;
|
||||||
});
|
|
||||||
} else {
|
|
||||||
statusStore.usingTTMLLyric = false;
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
console.log("Lyrics: ", musicStore.songLyric);
|
const adoptLRC = async () => {
|
||||||
|
try {
|
||||||
|
const { lyric: lyricRes, isLocal: lyricLocal } = await lrcPromise;
|
||||||
|
// 如果 TTML 已采用,则忽略 LRC
|
||||||
|
if (ttmlAdopted) return;
|
||||||
|
parsedLyricsData(lyricRes, lyricLocal && !settingStore.enableExcludeLocalLyrics);
|
||||||
|
statusStore.usingTTMLLyric = false;
|
||||||
|
if (!settled) {
|
||||||
|
statusStore.lyricLoading = false;
|
||||||
|
settled = true;
|
||||||
|
}
|
||||||
|
console.log("✅ LRC lyrics adopted");
|
||||||
|
} catch (err) {
|
||||||
|
console.error("❌ Error loading LRC lyrics:", err);
|
||||||
|
if (!settled) statusStore.lyricLoading = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 启动并发任务:TTML 与 LRC 同时进行,哪个先成功就先用
|
||||||
|
void adoptLRC();
|
||||||
|
void adoptTTML();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("❌ Error loading lyrics:", error);
|
console.error("❌ Error loading lyrics:", error);
|
||||||
statusStore.usingTTMLLyric = false;
|
statusStore.usingTTMLLyric = false;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { isDev, isElectron } from "./env";
|
|||||||
import { useSettingStore } from "@/stores";
|
import { useSettingStore } from "@/stores";
|
||||||
import { getCookie } from "./cookie";
|
import { getCookie } from "./cookie";
|
||||||
import { isLogin } from "./auth";
|
import { isLogin } from "./auth";
|
||||||
import axiosRetry from "axios-retry";
|
// import axiosRetry from "axios-retry";
|
||||||
|
|
||||||
// 全局地址
|
// 全局地址
|
||||||
const baseURL: string = String(isDev ? "/api/netease" : import.meta.env["VITE_API_URL"]);
|
const baseURL: string = String(isDev ? "/api/netease" : import.meta.env["VITE_API_URL"]);
|
||||||
@@ -18,10 +18,10 @@ const server: AxiosInstance = axios.create({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 请求重试
|
// 请求重试
|
||||||
axiosRetry(server, {
|
// axiosRetry(server, {
|
||||||
// 重试次数
|
// // 重试次数
|
||||||
retries: 3,
|
// retries: 3,
|
||||||
});
|
// });
|
||||||
|
|
||||||
// 请求拦截器
|
// 请求拦截器
|
||||||
server.interceptors.request.use(
|
server.interceptors.request.use(
|
||||||
|
|||||||
@@ -118,7 +118,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Position, useRafFn } from "@vueuse/core";
|
import { useRafFn } from "@vueuse/core";
|
||||||
import { LyricContentType, LyricType } from "@/types/main";
|
import { LyricContentType, LyricType } from "@/types/main";
|
||||||
import { LyricConfig, LyricData, RenderLine } from "@/types/desktop-lyric";
|
import { LyricConfig, LyricData, RenderLine } from "@/types/desktop-lyric";
|
||||||
import defaultDesktopLyricConfig from "@/assets/data/lyricConfig";
|
import defaultDesktopLyricConfig from "@/assets/data/lyricConfig";
|
||||||
@@ -332,40 +332,50 @@ const dragState = reactive({
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 桌面歌词拖动开始
|
* 桌面歌词拖动开始
|
||||||
* @param _position 拖动位置
|
|
||||||
* @param event 指针事件
|
* @param event 指针事件
|
||||||
*/
|
*/
|
||||||
const lyricDragStart = async (_position: Position, event: PointerEvent) => {
|
const onDocPointerDown = async (event: PointerEvent) => {
|
||||||
if (lyricConfig.isLock) return;
|
if (lyricConfig.isLock) return;
|
||||||
|
// 仅左键触发
|
||||||
|
if (event.button !== 0) return;
|
||||||
|
const target = event?.target as HTMLElement | null;
|
||||||
|
if (!target) return;
|
||||||
|
// 过滤 header 中的按钮:不触发拖拽
|
||||||
|
if (target.closest(".menu-btn")) return;
|
||||||
|
startDrag(event);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 桌面歌词拖动开始
|
||||||
|
* @param event 指针事件
|
||||||
|
*/
|
||||||
|
const startDrag = async (event: PointerEvent) => {
|
||||||
dragState.isDragging = true;
|
dragState.isDragging = true;
|
||||||
const { x, y } = await window.electron.ipcRenderer.invoke("get-window-bounds");
|
const { x, y } = await window.electron.ipcRenderer.invoke("get-window-bounds");
|
||||||
const { width, height } = await window.api.store.get("lyric");
|
const { width, height } = await window.api.store.get("lyric");
|
||||||
// 直接限制最大宽高
|
window.electron.ipcRenderer.send("toggle-fixed-max-size", { width, height, fixed: true });
|
||||||
window.electron.ipcRenderer.send("toggle-fixed-max-size", {
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
fixed: true,
|
|
||||||
});
|
|
||||||
dragState.startX = event?.screenX ?? 0;
|
dragState.startX = event?.screenX ?? 0;
|
||||||
dragState.startY = event?.screenY ?? 0;
|
dragState.startY = event?.screenY ?? 0;
|
||||||
dragState.startWinX = x;
|
dragState.startWinX = x;
|
||||||
dragState.startWinY = y;
|
dragState.startWinY = y;
|
||||||
dragState.winWidth = width ?? 0;
|
dragState.winWidth = width ?? 0;
|
||||||
dragState.winHeight = height ?? 0;
|
dragState.winHeight = height ?? 0;
|
||||||
|
document.addEventListener("pointermove", onDocPointerMove, { capture: true });
|
||||||
|
document.addEventListener("pointerup", onDocPointerUp, { capture: true });
|
||||||
|
event.preventDefault();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 桌面歌词拖动移动
|
* 桌面歌词拖动移动
|
||||||
* @param _position 拖动位置
|
|
||||||
* @param event 指针事件
|
* @param event 指针事件
|
||||||
*/
|
*/
|
||||||
const lyricDragMove = async (_position: Position, event: PointerEvent) => {
|
const onDocPointerMove = async (event: PointerEvent) => {
|
||||||
if (!dragState.isDragging || lyricConfig.isLock) return;
|
if (!dragState.isDragging || lyricConfig.isLock) return;
|
||||||
const screenX = event?.screenX ?? 0;
|
const screenX = event?.screenX ?? 0;
|
||||||
const screenY = event?.screenY ?? 0;
|
const screenY = event?.screenY ?? 0;
|
||||||
let newWinX = Math.round(dragState.startWinX + (screenX - dragState.startX));
|
let newWinX = Math.round(dragState.startWinX + (screenX - dragState.startX));
|
||||||
let newWinY = Math.round(dragState.startWinY + (screenY - dragState.startY));
|
let newWinY = Math.round(dragState.startWinY + (screenY - dragState.startY));
|
||||||
// 可选:限制在屏幕边界(支持多屏)
|
// 是否限制在屏幕边界(支持多屏)
|
||||||
if (lyricConfig.limitBounds) {
|
if (lyricConfig.limitBounds) {
|
||||||
const { minX, minY, maxX, maxY } = await window.electron.ipcRenderer.invoke(
|
const { minX, minY, maxX, maxY } = await window.electron.ipcRenderer.invoke(
|
||||||
"get-virtual-screen-bounds",
|
"get-virtual-screen-bounds",
|
||||||
@@ -382,24 +392,19 @@ const lyricDragMove = async (_position: Position, event: PointerEvent) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 监听桌面歌词拖动
|
/**
|
||||||
useDraggable(desktopLyricRef, {
|
* 桌面歌词拖动结束
|
||||||
onStart: (position, event) => {
|
*/
|
||||||
lyricDragStart(position, event);
|
const onDocPointerUp = () => {
|
||||||
},
|
if (!dragState.isDragging) return;
|
||||||
onMove: (position, event) => {
|
|
||||||
lyricDragMove(position, event);
|
|
||||||
},
|
|
||||||
onEnd: () => {
|
|
||||||
// 关闭拖拽状态
|
// 关闭拖拽状态
|
||||||
dragState.isDragging = false;
|
dragState.isDragging = false;
|
||||||
|
// 移除全局监听
|
||||||
|
document.removeEventListener("pointermove", onDocPointerMove, { capture: true });
|
||||||
|
document.removeEventListener("pointerup", onDocPointerUp, { capture: true });
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
// 恢复拖拽前宽高
|
// 恢复拖拽前宽高
|
||||||
window.electron.ipcRenderer.send(
|
window.electron.ipcRenderer.send("update-lyric-size", dragState.winWidth, dragState.winHeight);
|
||||||
"update-lyric-size",
|
|
||||||
dragState.winWidth,
|
|
||||||
dragState.winHeight,
|
|
||||||
);
|
|
||||||
// 根据字体大小恢复一次高度
|
// 根据字体大小恢复一次高度
|
||||||
const height = fontSizeToHeight(lyricConfig.fontSize);
|
const height = fontSizeToHeight(lyricConfig.fontSize);
|
||||||
if (height) pushWindowHeight(height);
|
if (height) pushWindowHeight(height);
|
||||||
@@ -410,8 +415,7 @@ useDraggable(desktopLyricRef, {
|
|||||||
fixed: false,
|
fixed: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
});
|
|
||||||
|
|
||||||
// 监听窗口大小变化
|
// 监听窗口大小变化
|
||||||
const { height: winHeight } = useWindowSize();
|
const { height: winHeight } = useWindowSize();
|
||||||
@@ -547,11 +551,16 @@ onMounted(() => {
|
|||||||
} else {
|
} else {
|
||||||
pauseSeek();
|
pauseSeek();
|
||||||
}
|
}
|
||||||
|
// 拖拽入口
|
||||||
|
document.addEventListener("pointerdown", onDocPointerDown, { capture: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
// 关闭 RAF
|
// 关闭 RAF
|
||||||
pauseSeek();
|
pauseSeek();
|
||||||
|
// 解绑事件
|
||||||
|
document.removeEventListener("pointerdown", onDocPointerDown, { capture: true });
|
||||||
|
if (dragState.isDragging) onDocPointerUp();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -570,9 +579,10 @@ onBeforeUnmount(() => {
|
|||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: background-color 0.3s;
|
transition: background-color 0.3s;
|
||||||
cursor: move;
|
cursor: default;
|
||||||
.header {
|
.header {
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
|
cursor: default;
|
||||||
// 子内容三等分grid
|
// 子内容三等分grid
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 1fr 1fr;
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
@@ -752,6 +762,9 @@ onBeforeUnmount(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.lyric-container {
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user