diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-03-25 16:47:22 +0100 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-03-29 15:48:22 +0200 |
| commit | 8db3bead13441a5882d8689dfc6a9f09c82375d9 (patch) | |
| tree | e9d0cafa93904ffcbec3188c37961bcc16c6422d /apps/web/src/lib/fonts | |
| parent | 39ea298a9ccba3104c549c0ca079c231981811f5 (diff) | |
| download | opencut-8db3bead13441a5882d8689dfc6a9f09c82375d9.tar.gz | |
feat: masks, properties refactor, shaders, storage migrations, and more
Diffstat (limited to 'apps/web/src/lib/fonts')
| -rw-r--r-- | apps/web/src/lib/fonts/google-fonts.ts | 26 | ||||
| -rw-r--r-- | apps/web/src/lib/fonts/types.ts | 24 |
2 files changed, 36 insertions, 14 deletions
diff --git a/apps/web/src/lib/fonts/google-fonts.ts b/apps/web/src/lib/fonts/google-fonts.ts index 7e55dffd..580ce406 100644 --- a/apps/web/src/lib/fonts/google-fonts.ts +++ b/apps/web/src/lib/fonts/google-fonts.ts @@ -1,14 +1,16 @@ -import type { FontAtlas } from "@/types/fonts"; +import type { FontAtlas } from "@/lib/fonts/types"; import { SYSTEM_FONTS } from "@/constants/font-constants"; const GOOGLE_FONTS_CSS = "https://fonts.googleapis.com/css2"; +const FONT_ATLAS_PATH = "/fonts/font-atlas.json"; +const FONT_CHUNK_PATH_PREFIX = "/fonts/font-chunk-"; const fullLoaded = new Set<string>(); let cachedAtlas: FontAtlas | null = null; let atlasFetchPromise: Promise<FontAtlas | null> | null = null; -function encodeFamily(family: string): string { +function encodeGoogleFontsFamily(family: string): string { return family.replace(/ /g, "+"); } @@ -19,17 +21,19 @@ export function getCachedFontAtlas(): FontAtlas | null { export function clearFontAtlasCache(): void { cachedAtlas = null; atlasFetchPromise = null; + fullLoaded.clear(); } -async function fetchAtlas(): Promise<FontAtlas | null> { - if (cachedAtlas) return cachedAtlas; +export function loadFontAtlas(): Promise<FontAtlas | null> { + if (cachedAtlas) return Promise.resolve(cachedAtlas); if (atlasFetchPromise) return atlasFetchPromise; - atlasFetchPromise = fetch("/fonts/font-atlas.json") + atlasFetchPromise = fetch(FONT_ATLAS_PATH) .then(async (response) => { if (!response.ok) return null; const data: FontAtlas = await response.json(); cachedAtlas = data; + preloadChunkImages({ atlas: data }); return data; }) .catch(() => null); @@ -42,18 +46,12 @@ function preloadChunkImages({ atlas }: { atlas: FontAtlas }): void { ...Object.values(atlas.fonts).map((entry) => entry.ch), ); for (let i = 0; i <= maxChunk; i++) { + // hint browser to preload chunk images without blocking const img = new Image(); - img.src = `/fonts/font-chunk-${i}.avif`; + img.src = `${FONT_CHUNK_PATH_PREFIX}${i}.avif`; } } -export function prefetchFontAtlas(): Promise<FontAtlas | null> { - return fetchAtlas().then((atlas) => { - if (atlas) preloadChunkImages({ atlas }); - return atlas; - }); -} - export async function loadFullFont({ family, weights = [400, 700], @@ -63,7 +61,7 @@ export async function loadFullFont({ }): Promise<void> { if (fullLoaded.has(family)) return; - const url = `${GOOGLE_FONTS_CSS}?family=${encodeFamily(family)}:wght@${weights.join(";")}&display=swap`; + const url = `${GOOGLE_FONTS_CSS}?family=${encodeGoogleFontsFamily(family)}:wght@${weights.join(";")}&display=swap`; const link = document.createElement("link"); link.rel = "stylesheet"; link.href = url; diff --git a/apps/web/src/lib/fonts/types.ts b/apps/web/src/lib/fonts/types.ts new file mode 100644 index 00000000..a2db6f91 --- /dev/null +++ b/apps/web/src/lib/fonts/types.ts @@ -0,0 +1,24 @@ +export interface FontOption { + value: string; + label: string; + category: "system" | "google" | "custom"; + weights?: number[]; + hasClassName?: boolean; +} + +export interface GoogleFontMeta { + family: string; + category: string; +} + +export interface FontAtlasEntry { + x: number; + y: number; + w: number; + ch: number; + s: string[]; +} + +export interface FontAtlas { + fonts: Record<string, FontAtlasEntry>; +} |
