Merge pull request #484 from MoYingJi/feat

feat: 支持为日语单独设置字体
This commit is contained in:
底层用户
2025-10-13 09:06:02 +08:00
committed by GitHub
5 changed files with 75 additions and 3 deletions

View File

@@ -8,6 +8,7 @@
:enableBlur="settingStore.lyricsBlur" :style="{
'--amll-lyric-view-color': mainColor,
'--amll-lyric-player-font-size': settingStore.lyricFontSize + 'px',
'--ja-font-family': settingStore.japaneseLyricFont !== 'follow' ? settingStore.japaneseLyricFont : '',
'font-weight': settingStore.lyricFontBold ? 'bold' : 'normal',
'font-family': settingStore.LyricFont !== 'follow' ? settingStore.LyricFont : '',
}" class="am-lyric" @line-click="jumpSeek" />
@@ -20,7 +21,9 @@ import { LyricPlayer } from "@applemusic-like-lyrics/vue";
import { LyricLine } from "@applemusic-like-lyrics/core";
import { useMusicStore, useSettingStore, useStatusStore } from "@/stores";
import { msToS } from "@/utils/time";
import { getLyricLanguage } from "@/utils/lyric";
import player from "@/utils/player";
import { watch } from "vue";
const musicStore = useMusicStore();
const statusStore = useStatusStore();
@@ -86,9 +89,30 @@ const jumpSeek = (line: any) => {
player.play();
};
// 处理歌词语言
const processLyricLanguage = () => {
const lyricLinesEl = lyricPlayerRef.value?.lyricPlayer?.lyricLinesEl ?? [];
// 遍历歌词行
for (let e of lyricLinesEl) {
// 获取歌词行内容 (合并逐字歌词为一句)
const content = e.lyricLine.words.map((word: any) => word.word).join("");
// 获取歌词语言
const lang = getLyricLanguage(content);
// 为主歌词设置 lang 属性 (firstChild 获取主歌词 不为翻译和音译设置属性)
e.element.firstChild.setAttribute("lang", lang);
}
};
// 切换歌曲时处理歌词语言
watch(amLyricsData, () => {
nextTick(() => processLyricLanguage());
});
onMounted(() => {
// 恢复进度
resumeSeek();
// 处理歌词语言
nextTick(() => processLyricLanguage());
});
onBeforeUnmount(() => {
@@ -134,5 +158,9 @@ onBeforeUnmount(() => {
}
}
}
:lang(ja) {
font-family: var(--ja-font-family);
}
}
</style>

View File

@@ -5,6 +5,7 @@
'--lrc-tran-size': settingStore.lyricTranFontSize + 'px',
'--lrc-roma-size': settingStore.lyricRomaFontSize + 'px',
'--lrc-bold': settingStore.lyricFontBold ? 'bold' : 'normal',
'--ja-font-family': settingStore.japaneseLyricFont !== 'follow' ? settingStore.japaneseLyricFont : '',
'font-family': settingStore.LyricFont !== 'follow' ? settingStore.LyricFont : '',
cursor: statusStore.playerMetaShow ? 'auto' : 'none',
}"
@@ -60,8 +61,8 @@
'end-with-space': text.endsWithSpace,
}"
>
<span class="word" :lang="/[\u4e00-\u9fa5]/.test(text.content) ? 'zh-CN' : 'en'">{{ text.content }}</span>
<span class="filler" :style="getYrcStyle(text, index)" :lang="/[\u4e00-\u9fa5]/.test(text.content) ? 'zh-CN' : 'en'">
<span class="word" :lang="getLyricLanguage(text.content)">{{ text.content }}</span>
<span class="filler" :style="getYrcStyle(text, index)" :lang="getLyricLanguage(text.content)">
{{ text.content }}
</span>
</div>
@@ -113,7 +114,7 @@
@click="jumpSeek(item.time)"
>
<!-- 歌词 -->
<span class="content" :lang="/[\u4e00-\u9fa5]/.test(item.content) ? 'zh-CN' : 'en'">{{ item.content }}</span>
<span class="content" :lang="getLyricLanguage(item.content)">{{ item.content }}</span>
<!-- 翻译 -->
<span v-if="item.tran && settingStore.showTran" class="tran" lang="en">{{ item.tran }}</span>
<!-- 音译 -->
@@ -151,6 +152,7 @@ import { NScrollbar } from "naive-ui";
import { useMusicStore, useSettingStore, useStatusStore } from "@/stores";
import { openSetting } from "@/utils/modal";
import player from "@/utils/player";
import { getLyricLanguage } from "@/utils/lyric";
const musicStore = useMusicStore();
const statusStore = useStatusStore();
@@ -389,6 +391,9 @@ onBeforeUnmount(() => {
}
}
}
&:lang(ja) {
font-family: var(--ja-font-family);
}
}
.tran {
margin-top: 8px;

View File

@@ -191,6 +191,33 @@
/>
</n-flex>
</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-flex>
<Transition name="fade" mode="out-in">
<n-button
v-if="settingStore.japaneseLyricFont !== 'follow'"
type="primary"
strong
secondary
@click="settingStore.japaneseLyricFont = 'follow'"
>
恢复默认
</n-button>
</Transition>
<n-select
v-model:value="settingStore.japaneseLyricFont"
:options="[
{ label: '跟随全局', value: 'follow' },
...allFontsData.filter((v) => v.value !== 'default'),
]"
class="set"
/>
</n-flex>
</n-card>
<n-card class="set-item">
<div class="label">
<n-text class="name">关闭软件时</n-text>

View File

@@ -20,6 +20,7 @@ interface SettingState {
themeFollowCover: boolean;
globalFont: "default" | string;
LyricFont: "follow" | string;
japaneseLyricFont: "follow" | string;
showCloseAppTip: boolean;
closeAppMethod: "exit" | "hide";
showTaskbarProgress: boolean;
@@ -100,6 +101,7 @@ export const useSettingStore = defineStore("setting", {
themeGlobalColor: false, // 全局着色
globalFont: "default", // 全局字体
LyricFont: "follow", // 歌词区域字体
japaneseLyricFont: "follow", // 日语歌词字体
hideVipTag: false, // 隐藏 VIP 标签
showSearchHistory: true, // 显示搜索历史
menuShowCover: true, // 菜单显示封面

View File

@@ -254,3 +254,13 @@ export function parseTTMLToAMLL(ttmlContent: string): LyricLine[] {
return [];
}
}
// 检测语言
export const getLyricLanguage = (lyric: string): string => {
// 判断日语 根据平假名和片假名
if (/[\u3040-\u309f\u30a0-\u30ff]/.test(lyric)) return 'ja';
// 判断简体中文 根据中日韩统一表意文字基本区
if (/[\u4e00-\u9fa5]/.test(lyric)) return 'zh-CN';
// 默认英语
return 'en';
};