react js 查看字体效果
起因, 目的:
想查看某个字体,对中英文的支持情况。
效果图:
完整项目见这里, 需要积分下载,不然的话,显得太水了。
过程:
- AI 对话, 生成代码。
- 我检查运行, 来回修改。
- 写个博客,记录过程。
核心代码 App.js
import React, { useState, useEffect, useCallback } from 'react';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import './App.css';
import Header from './components/Header';
import FontSelector from './components/FontSelector';
import TextDisplay from './components/TextDisplay';const fonts = [{ name: 'Arial' },{ name: 'Noto Sans' },{ name: 'SimSun' },{ name: 'Roboto' },{ name: 'Times New Roman' },{ name: 'Microsoft YaHei' },{ name: 'Consolas' },{ name: 'Open Sans' },{ name: 'Noto Sans SC' },{ name: 'Lora' },
];const defaultFont = 'Arial';function App() {const [selectedFont, setSelectedFont] = useState(defaultFont);const [englishFont, setEnglishFont] = useState(defaultFont);const [chineseFont, setChineseFont] = useState(defaultFont);const [searchTerm, setSearchTerm] = useState('');const checkFontSupport = async (fontName, text) => {try {const normalizedFontName = fontName.trim();if (['Arial', 'Microsoft YaHei', 'SimSun', 'Consolas', 'Times New Roman'].includes(normalizedFontName)) {if (normalizedFontName === 'Arial' || normalizedFontName === 'Consolas' || normalizedFontName === 'Times New Roman') {return text === 'A';}if (normalizedFontName === 'Microsoft YaHei') {return true;}if (normalizedFontName === 'SimSun') {return text === '中';}}await document.fonts.load(`20px "${normalizedFontName}"`);const isFontAvailable = document.fonts.check(`20px "${normalizedFontName}"`);if (!isFontAvailable) {console.log(`字体 ${normalizedFontName} 不可用`);return false;}return true;} catch (error) {console.error(`检测字体 ${fontName} 失败:`, error);return false;}};const handleFontChange = useCallback((fontName) => {const timer = setTimeout(async () => {setSelectedFont(fontName);const supportsEnglish = await checkFontSupport(fontName, 'A');const supportsChinese = await checkFontSupport(fontName, '中');const warnings = [];if (!supportsEnglish) {warnings.push('英文');setEnglishFont(defaultFont);} else {setEnglishFont(fontName);}if (!supportsChinese) {warnings.push('中文');setChineseFont(defaultFont);} else {setChineseFont(fontName);}if (warnings.length > 0) {toast.warn(`字体 ${fontName} 不支持${warnings.join('和')},将使用默认字体 ${defaultFont}`);}}, 100);return () => clearTimeout(timer);}, []);useEffect(() => {const link = document.createElement('link');link.href ='https://fonts.font.im/css2?family=Noto+Sans&family=Roboto&family=Open+Sans&family=Noto+Sans+SC&family=Lora&display=swap';link.rel = 'stylesheet';document.head.appendChild(link);return () => document.head.removeChild(link);}, []);const filteredFonts = fonts.filter((font) =>font.name.toLowerCase().includes(searchTerm.toLowerCase()));return (<div className="App"><Header /><FontSelectorfonts={filteredFonts}selectedFont={selectedFont}onFontChange={handleFontChange}searchTerm={searchTerm}onSearchChange={setSearchTerm}/><TextDisplay englishFont={englishFont} chineseFont={chineseFont} /><ToastContainer /></div>);
}export default App;
过程简述
初始:4 种字体,静态检测,单行文本。
扩展:10 种字体,动态检测(checkFontSupport),添加搜索框、Google Fonts 链接、中英文各 3 行。
问题:
- 字体检测失败:改进 checkFontSupport,本地字体特殊处理。
- Google Fonts 加载:切换到 fonts.font.im。
- 重复警告:合并为单一警告。
运行:
npm install react-toastify
npm start
然后访问:http://localhost:3001
结论 + todo
- 大体效果还可以。
- 搜索框,还是有点问题。