| ---
|
| import { siteConfig } from "@/config";
|
|
|
| const { font: fontConfig } = siteConfig;
|
|
|
|
|
| const getSelectedFonts = () => {
|
| if (!fontConfig.enable || !fontConfig.selected) return [];
|
|
|
| const selectedIds = Array.isArray(fontConfig.selected)
|
| ? fontConfig.selected
|
| : [fontConfig.selected];
|
|
|
| return selectedIds
|
| .map((id) => fontConfig.fonts[id])
|
| .filter((font) => font?.src);
|
| };
|
|
|
| const selectedFonts = getSelectedFonts();
|
|
|
|
|
| const generateFontClasses = () => {
|
| if (!fontConfig.enable) return [];
|
|
|
| const selectedIds = Array.isArray(fontConfig.selected)
|
| ? fontConfig.selected
|
| : [fontConfig.selected];
|
|
|
| return selectedIds.map((id) => `font-${id}-enabled`);
|
| };
|
|
|
| const fontClasses = generateFontClasses();
|
|
|
|
|
| const generateFontFamilyStyle = () => {
|
| if (!fontConfig.enable || !fontConfig.selected) return "";
|
|
|
| const selectedIds = Array.isArray(fontConfig.selected)
|
| ? fontConfig.selected
|
| : [fontConfig.selected];
|
|
|
| const selectedFontFamilies = selectedIds
|
| .map((id) => fontConfig.fonts[id])
|
| .filter((font) => font)
|
| .map((font) => `"${font.family}"`);
|
|
|
| if (selectedFontFamilies.length === 0) return "";
|
|
|
| const fallbacks = fontConfig.fallback || [];
|
| const allFonts = [...selectedFontFamilies, ...fallbacks];
|
|
|
| return `font-family: ${allFonts.join(", ")};`;
|
| };
|
|
|
| const fontFamilyStyle = generateFontFamilyStyle();
|
| ---
|
|
|
| <!-- 字体样式表链接 -->{
|
| selectedFonts.map((font) => {
|
|
|
| const isExternalUrl =
|
| font.src.startsWith("http://") ||
|
| font.src.startsWith("https://") ||
|
| font.src.startsWith("//");
|
|
|
| if (isExternalUrl) {
|
|
|
| return <link rel="stylesheet" href={font.src} />;
|
| } else {
|
|
|
| return (
|
| <style
|
| set:html={`
|
| @font-face {
|
| font-family: "${font.family}";
|
| src: url("${font.src}") ${font.format ? `format("${font.format}")` : ""};
|
| ${font.weight ? `font-weight: ${font.weight};` : ""}
|
| ${font.style ? `font-style: ${font.style};` : ""}
|
| ${font.display ? `font-display: ${font.display};` : ""}
|
| ${font.unicodeRange ? `unicode-range: ${font.unicodeRange};` : ""}
|
| }
|
| `}
|
| />
|
| );
|
| }
|
| })
|
| }
|
|
|
| <!-- 字体预加载链接 -->
|
| {
|
| fontConfig.enable &&
|
| fontConfig.preload &&
|
| selectedFonts
|
| .filter((font) => !font.src.startsWith("http"))
|
| .map((font) => (
|
| <link
|
| rel="preload"
|
| href={font.src}
|
| as="font"
|
| type={`font/${font.format || "woff2"}`}
|
| crossorigin
|
| />
|
| ))
|
| }
|
|
|
| <!-- 全局字体样式 -->
|
| {
|
| fontConfig.enable && fontFamilyStyle && (
|
| <style
|
| set:html={`
|
| :root {
|
| --font-family-custom: ${selectedFonts.map((font) => `"${font.family}"`).join(", ")};
|
| --font-family-fallback: ${(fontConfig.fallback || []).join(", ")};
|
| }
|
|
|
| /* 应用自定义字体到body */
|
| body {
|
| ${fontFamilyStyle}
|
| }
|
|
|
| /* 为每个选中的字体生成对应的CSS类 */
|
| ${selectedFonts
|
| .map((font) => {
|
| return `
|
| .font-${font.id},
|
| .font-${font.id} * {
|
| font-family: "${font.family}", var(--font-family-fallback) !important;
|
| }
|
| `;
|
| })
|
| .join("\n")}
|
|
|
| /* 为整体启用字体的body添加类名 */
|
| ${fontClasses.map((className) => `.${className}`).join(",\n")} {
|
| /* 字体相关的全局样式可以在这里添加 */
|
| }
|
| `}
|
| />
|
| )
|
| }
|
|
|
| <script>
|
|
|
| if (document.fonts && typeof document.fonts.ready !== "undefined") {
|
| document.fonts.ready
|
| .then(() => {
|
| console.log("All fonts have been loaded");
|
|
|
|
|
| document.dispatchEvent(new CustomEvent("fontsLoaded"));
|
| })
|
| .catch((error: Error) => {
|
| console.warn("Font loading failed:", error);
|
| });
|
| }
|
|
|
|
|
| if (typeof PerformanceObserver !== "undefined") {
|
| const observer = new PerformanceObserver((list) => {
|
| list.getEntries().forEach((entry) => {
|
| if (entry.entryType === "resource") {
|
|
|
| }
|
| });
|
| });
|
|
|
| try {
|
| observer.observe({ entryTypes: ["resource"] });
|
| } catch (e) {
|
|
|
| }
|
| }
|
| </script>
|
|
|