UNPKG

kinetic-slider

Version:

A WebGL-powered kinetic slider component using PIXI.js

186 lines (183 loc) 5.29 kB
import { Assets } from 'pixi.js'; const SYSTEM_FONTS = [ // Sans-serif fonts "Arial", "Helvetica", "Helvetica Neue", "Verdana", "Tahoma", "Trebuchet MS", "Segoe UI", "Roboto", "Open Sans", "Liberation Sans", "Noto Sans", "Ubuntu", // Serif fonts "Times", "Times New Roman", "Georgia", "Palatino", "Garamond", "Bookman", "Cambria", "Constantia", "Liberation Serif", "Noto Serif", // Monospace fonts "Courier", "Courier New", "Monaco", "Consolas", "Liberation Mono", "Menlo", // Generic families "sans-serif", "serif", "monospace", "cursive", "fantasy", "system-ui" ]; const FONT_EXTENSIONS = [".woff2", ".woff", ".ttf", ".otf"]; function parseFontStack(fontStack) { if (!fontStack) return []; return fontStack.split(",").map((font) => { return font.replace(/^["'\s]+|["'\s]+$/g, "").trim(); }).filter(Boolean); } function identifyCustomFonts(parsedFonts) { return parsedFonts.filter( (font) => ( // Not in our system fonts list and not a generic family !SYSTEM_FONTS.some( (systemFont) => systemFont.toLowerCase() === font.toLowerCase() ) ) ); } async function findFontFile(fontName, extensions = FONT_EXTENSIONS) { const fontPaths = []; for (const ext of extensions) { fontPaths.push(`/fonts/${fontName}${ext}`); fontPaths.push(`/fonts/${fontName.toLowerCase()}${ext}`); } const additionalPaths = []; for (const ext of extensions) { additionalPaths.push(`/public/fonts/${fontName}${ext}`); additionalPaths.push(`/public/fonts/${fontName.toLowerCase()}${ext}`); } const allPaths = [...fontPaths, ...additionalPaths]; for (const path of allPaths) { try { const response = await fetch(path, { method: "HEAD" }); if (response.ok) { console.log(`Found font file at: ${path}`); return path; } } catch (error) { } } console.warn(`No font file found for: ${fontName}`); return null; } async function loadCustomFonts(fontStack) { if (!fontStack) return []; const parsedFonts = parseFontStack(fontStack); const customFonts = identifyCustomFonts(parsedFonts); if (!customFonts.length) { console.log("No custom fonts identified in font stack:", fontStack); return []; } console.log("Identified custom fonts:", customFonts); const loadedFonts = []; for (const fontName of customFonts) { try { const cleanFontName = fontName.replace(/['"]/g, ""); const fontPath = await findFontFile(cleanFontName); if (fontPath) { console.log(`Loading font: ${cleanFontName} from ${fontPath}`); try { await Assets.load({ src: fontPath, data: { // Add font-specific metadata if needed family: cleanFontName } }); loadedFonts.push(fontPath); console.log(`Successfully loaded font: ${cleanFontName}`); } catch (loadError) { console.warn(`Failed to load font ${cleanFontName}:`, loadError); } } } catch (error) { console.warn(`Error processing font ${fontName}:`, error); } } return loadedFonts; } function createFontFaceCSS(fontPaths) { return fontPaths.map((path) => { const fontName = path.split("/").pop()?.split(".")[0] || ""; const fontFormat = path.split(".").pop(); let format; switch (fontFormat) { case "woff2": format = "woff2"; break; case "woff": format = "woff"; break; case "ttf": format = "truetype"; break; case "otf": format = "opentype"; break; default: format = "truetype"; } return ` @font-face { font-family: '${fontName}'; src: url('${path}') format('${format}'); font-weight: normal; font-style: normal; font-display: swap; } `; }).join("\n"); } function injectFontFaceCSS(css) { if (typeof document === "undefined" || !css) return; const style = document.createElement("style"); style.textContent = css; style.setAttribute("data-kinetic-slider-fonts", "true"); document.head.appendChild(style); } async function setupCustomFonts(titleFontStack, subtitleFontStack) { if (typeof window === "undefined") return; console.log("Setting up custom fonts:", { titleFontStack, subtitleFontStack }); const loadedFontPaths = []; if (titleFontStack) { const titleFontPaths = await loadCustomFonts(titleFontStack); loadedFontPaths.push(...titleFontPaths); } if (subtitleFontStack) { const subtitleFontPaths = await loadCustomFonts(subtitleFontStack); const newPaths = subtitleFontPaths.filter((path) => !loadedFontPaths.includes(path)); loadedFontPaths.push(...newPaths); } if (loadedFontPaths.length > 0) { const fontFaceCSS = createFontFaceCSS(loadedFontPaths); injectFontFaceCSS(fontFaceCSS); console.log("Injected font-face CSS for:", loadedFontPaths); return new Promise((resolve) => { setTimeout(resolve, 100); }); } return Promise.resolve(); } export { createFontFaceCSS, findFontFile, identifyCustomFonts, injectFontFaceCSS, loadCustomFonts, parseFontStack, setupCustomFonts }; //# sourceMappingURL=fontUtils.js.map