mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-03 13:36:04 +02:00
refactor: custom fonts
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
const APP_FONT_DEFAULT_KEY = 'inter';
|
||||
const APP_CJK_FONT_PACK_DEFAULT_KEY = 'noto';
|
||||
|
||||
const APP_FONT_CONFIG = Object.freeze({
|
||||
inter: {
|
||||
@@ -8,7 +9,7 @@ const APP_FONT_CONFIG = Object.freeze({
|
||||
noto_sans: {
|
||||
cssName: "'Noto Sans'",
|
||||
cssImport:
|
||||
"@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,100..700;1,100..700&family=Noto+Sans:ital,wght@0,100..900;1,100..900&family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap');"
|
||||
"@import url('https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap');"
|
||||
},
|
||||
source_sans_3: {
|
||||
cssName: "'Source Sans 3'",
|
||||
@@ -18,7 +19,7 @@ const APP_FONT_CONFIG = Object.freeze({
|
||||
ibm_plex_sans: {
|
||||
cssName: "'IBM Plex Sans'",
|
||||
cssImport:
|
||||
"@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,100..700;1,100..700&family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap');"
|
||||
"@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,100..700;1,100..700&display=swap');"
|
||||
},
|
||||
harmonyos_sans: {
|
||||
cssName: "'HarmonyOS Sans'",
|
||||
@@ -33,7 +34,7 @@ const APP_FONT_CONFIG = Object.freeze({
|
||||
roboto: {
|
||||
cssName: "'Roboto'",
|
||||
cssImport:
|
||||
"@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&family=Roboto:ital,wght@0,100..900;1,100..900&display=swap');"
|
||||
"@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap');"
|
||||
},
|
||||
fantasque_sans_mono: {
|
||||
cssName: "'Fantasque Sans Mono'",
|
||||
@@ -43,9 +44,69 @@ const APP_FONT_CONFIG = Object.freeze({
|
||||
system_ui: {
|
||||
cssName: 'system-ui',
|
||||
link: null
|
||||
},
|
||||
custom: {
|
||||
cssName: '',
|
||||
link: null
|
||||
}
|
||||
});
|
||||
|
||||
const APP_FONT_FAMILIES = Object.freeze(Object.keys(APP_FONT_CONFIG));
|
||||
|
||||
export { APP_FONT_CONFIG, APP_FONT_DEFAULT_KEY, APP_FONT_FAMILIES };
|
||||
const APP_CJK_FONT_PACK_CONFIG = Object.freeze({
|
||||
noto: {
|
||||
cssName: Object.freeze({
|
||||
jp: "'Noto Sans JP Variable'",
|
||||
kr: "'Noto Sans KR Variable'",
|
||||
sc: "'Noto Sans SC Variable'",
|
||||
tc: "'Noto Sans TC Variable'"
|
||||
}),
|
||||
link: null
|
||||
},
|
||||
pht: {
|
||||
cssName: Object.freeze({
|
||||
jp: "'PHT Sans JP'",
|
||||
kr: "'PHT Sans KR'",
|
||||
sc: "'PHT Sans SC'",
|
||||
tc: "'PHT Sans TC'"
|
||||
}),
|
||||
cssImport: [
|
||||
'/* Simplified Chinese */',
|
||||
"@font-face { font-family: 'PHT Sans SC'; src: url('https://cdn.jsdelivr.net/gh/map1en/pht@1.0.0/sc/phtsansSC-Regular.woff2') format('woff2'); font-weight: 400; font-display: swap; }",
|
||||
"@font-face { font-family: 'PHT Sans SC'; src: url('https://cdn.jsdelivr.net/gh/map1en/pht@1.0.0/sc/phtsansSC-Medium.woff2') format('woff2'); font-weight: 500; font-display: swap; }",
|
||||
"@font-face { font-family: 'PHT Sans SC'; src: url('https://cdn.jsdelivr.net/gh/map1en/pht@1.0.0/sc/phtsansSC-SemiBold.woff2') format('woff2'); font-weight: 600; font-display: swap; }",
|
||||
"@font-face { font-family: 'PHT Sans SC'; src: url('https://cdn.jsdelivr.net/gh/map1en/pht@1.0.0/sc/phtsansSC-Bold.woff2') format('woff2'); font-weight: 700; font-display: swap; }",
|
||||
'/* Traditional Chinese */',
|
||||
"@font-face { font-family: 'PHT Sans TC'; src: url('https://cdn.jsdelivr.net/gh/map1en/pht@1.0.0/tc/phtsansTC-55.woff2') format('woff2'); font-weight: 400; font-display: swap; }",
|
||||
"@font-face { font-family: 'PHT Sans TC'; src: url('https://cdn.jsdelivr.net/gh/map1en/pht@1.0.0/tc/phtsansTC-75.woff2') format('woff2'); font-weight: 600; font-display: swap; }",
|
||||
'/* Japanese */',
|
||||
"@font-face { font-family: 'PHT Sans JP'; src: url('https://cdn.jsdelivr.net/gh/map1en/pht@1.0.0/jp/phtsansJP-Regular.woff2') format('woff2'); font-weight: 400; font-display: swap; }",
|
||||
"@font-face { font-family: 'PHT Sans JP'; src: url('https://cdn.jsdelivr.net/gh/map1en/pht@1.0.0/jp/phtsansJP-Medium.woff2') format('woff2'); font-weight: 500; font-display: swap; }",
|
||||
"@font-face { font-family: 'PHT Sans JP'; src: url('https://cdn.jsdelivr.net/gh/map1en/pht@1.0.0/jp/phtsansJP-Bold.woff2') format('woff2'); font-weight: 700; font-display: swap; }",
|
||||
'/* Korean */',
|
||||
"@font-face { font-family: 'PHT Sans KR'; src: url('https://cdn.jsdelivr.net/gh/map1en/pht@1.0.0/kr/phtsansKR-Regular.woff2') format('woff2'); font-weight: 400; font-display: swap; }",
|
||||
"@font-face { font-family: 'PHT Sans KR'; src: url('https://cdn.jsdelivr.net/gh/map1en/pht@1.0.0/kr/phtsansKR-Medium.woff2') format('woff2'); font-weight: 500; font-display: swap; }",
|
||||
"@font-face { font-family: 'PHT Sans KR'; src: url('https://cdn.jsdelivr.net/gh/map1en/pht@1.0.0/kr/phtsansKR-Bold.woff2') format('woff2'); font-weight: 700; font-display: swap; }"
|
||||
].join('\n')
|
||||
},
|
||||
system: {
|
||||
cssName: Object.freeze({
|
||||
jp: 'system-ui',
|
||||
kr: 'system-ui',
|
||||
sc: 'system-ui',
|
||||
tc: 'system-ui'
|
||||
}),
|
||||
link: null
|
||||
}
|
||||
});
|
||||
|
||||
const APP_CJK_FONT_PACKS = Object.freeze(Object.keys(APP_CJK_FONT_PACK_CONFIG));
|
||||
|
||||
export {
|
||||
APP_FONT_CONFIG,
|
||||
APP_FONT_DEFAULT_KEY,
|
||||
APP_FONT_FAMILIES,
|
||||
APP_CJK_FONT_PACK_CONFIG,
|
||||
APP_CJK_FONT_PACK_DEFAULT_KEY,
|
||||
APP_CJK_FONT_PACKS
|
||||
};
|
||||
|
||||
+66
-17
@@ -2,6 +2,8 @@ import { ref } from 'vue';
|
||||
import { toast } from 'vue-sonner';
|
||||
|
||||
import {
|
||||
APP_CJK_FONT_PACK_CONFIG,
|
||||
APP_CJK_FONT_PACK_DEFAULT_KEY,
|
||||
APP_FONT_CONFIG,
|
||||
APP_FONT_DEFAULT_KEY,
|
||||
THEME_COLORS,
|
||||
@@ -19,6 +21,7 @@ const THEME_MODE_STYLE_ID = 'app-theme-mode-style';
|
||||
const DEFAULT_THEME_COLOR_KEY = 'default';
|
||||
|
||||
const APP_FONT_LINK_ATTR = 'data-app-font';
|
||||
const APP_CJK_FONT_PACK_LINK_ATTR = 'data-app-cjk-font-pack';
|
||||
|
||||
const themeColors = THEME_COLORS.map((theme) => ({
|
||||
...theme,
|
||||
@@ -166,44 +169,89 @@ function resolveAppFontFamily(fontKey) {
|
||||
};
|
||||
}
|
||||
|
||||
function ensureAppFontLinks(fontKey) {
|
||||
function ensureDynamicFontStyle(attrName, styleKey, cssImport) {
|
||||
const head = document.head;
|
||||
if (!head) {
|
||||
return;
|
||||
}
|
||||
|
||||
document
|
||||
.querySelectorAll(`style[${APP_FONT_LINK_ATTR}]`)
|
||||
.forEach((styleEl) => {
|
||||
if (styleEl.getAttribute(APP_FONT_LINK_ATTR) !== fontKey) {
|
||||
styleEl.remove();
|
||||
}
|
||||
});
|
||||
document.querySelectorAll(`style[${attrName}]`).forEach((styleEl) => {
|
||||
if (styleEl.getAttribute(attrName) !== styleKey) {
|
||||
styleEl.remove();
|
||||
}
|
||||
});
|
||||
|
||||
const config = APP_FONT_CONFIG[fontKey];
|
||||
if (!config?.cssImport) {
|
||||
if (!cssImport) {
|
||||
return;
|
||||
}
|
||||
|
||||
const existing = document.querySelector(
|
||||
`style[${APP_FONT_LINK_ATTR}="${fontKey}"]`
|
||||
);
|
||||
const existing = document.querySelector(`style[${attrName}="${styleKey}"]`);
|
||||
if (existing) {
|
||||
return;
|
||||
}
|
||||
|
||||
const styleEl = document.createElement('style');
|
||||
styleEl.setAttribute(APP_FONT_LINK_ATTR, fontKey);
|
||||
styleEl.textContent = config.cssImport;
|
||||
styleEl.setAttribute(attrName, styleKey);
|
||||
styleEl.textContent = cssImport;
|
||||
head.appendChild(styleEl);
|
||||
}
|
||||
|
||||
function applyAppFontFamily(fontKey) {
|
||||
function resolveAppCjkFontPack(packKey) {
|
||||
const normalized = String(packKey || '')
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
if (APP_CJK_FONT_PACK_CONFIG[normalized]) {
|
||||
return { key: normalized, ...APP_CJK_FONT_PACK_CONFIG[normalized] };
|
||||
}
|
||||
return {
|
||||
key: APP_CJK_FONT_PACK_DEFAULT_KEY,
|
||||
...APP_CJK_FONT_PACK_CONFIG[APP_CJK_FONT_PACK_DEFAULT_KEY]
|
||||
};
|
||||
}
|
||||
|
||||
function ensureAppCjkFontPackLinks(packKey) {
|
||||
const config = APP_CJK_FONT_PACK_CONFIG[packKey];
|
||||
ensureDynamicFontStyle(
|
||||
APP_CJK_FONT_PACK_LINK_ATTR,
|
||||
packKey,
|
||||
config?.cssImport
|
||||
);
|
||||
}
|
||||
|
||||
function applyAppFontFamily(fontKey, customCssName) {
|
||||
if (fontKey === 'custom') {
|
||||
const cssName = String(customCssName || '').trim() || 'system-ui';
|
||||
const root = document.documentElement;
|
||||
root.style.setProperty('--font-western-primary', cssName);
|
||||
ensureDynamicFontStyle(APP_FONT_LINK_ATTR, 'custom', null);
|
||||
return {
|
||||
key: 'custom',
|
||||
...APP_FONT_CONFIG.custom,
|
||||
cssName
|
||||
};
|
||||
}
|
||||
|
||||
const resolved = resolveAppFontFamily(fontKey);
|
||||
const root = document.documentElement;
|
||||
root.style.setProperty('--font-western-primary', resolved.cssName);
|
||||
ensureDynamicFontStyle(
|
||||
APP_FONT_LINK_ATTR,
|
||||
resolved.key,
|
||||
resolved.cssImport
|
||||
);
|
||||
|
||||
ensureAppFontLinks(resolved.key);
|
||||
return resolved;
|
||||
}
|
||||
|
||||
function applyAppCjkFontPack(packKey) {
|
||||
const resolved = resolveAppCjkFontPack(packKey);
|
||||
const root = document.documentElement;
|
||||
root.style.setProperty('--font-cjk-jp-primary', resolved.cssName.jp);
|
||||
root.style.setProperty('--font-cjk-sc-primary', resolved.cssName.sc);
|
||||
root.style.setProperty('--font-cjk-kr-primary', resolved.cssName.kr);
|
||||
root.style.setProperty('--font-cjk-tc-primary', resolved.cssName.tc);
|
||||
|
||||
ensureAppCjkFontPackLinks(resolved.key);
|
||||
|
||||
return resolved;
|
||||
}
|
||||
@@ -461,6 +509,7 @@ export {
|
||||
refreshCustomCss,
|
||||
refreshCustomScript,
|
||||
applyAppFontFamily,
|
||||
applyAppCjkFontPack,
|
||||
HueToHex,
|
||||
HSVtoRGB,
|
||||
formatJsonVars,
|
||||
|
||||
Reference in New Issue
Block a user