dvc890 commited on
Commit
b56ea18
·
verified ·
1 Parent(s): d3d03bf

Upload 45 files

Browse files
Files changed (1) hide show
  1. components/Emoji.tsx +38 -3
components/Emoji.tsx CHANGED
@@ -7,6 +7,14 @@ interface EmojiProps {
7
  size?: number | string;
8
  }
9
 
 
 
 
 
 
 
 
 
10
  // 将 Unicode 转换为 Twemoji 兼容的 Hex 文件名
11
  const getEmojiHex = (emoji: string) => {
12
  try {
@@ -19,13 +27,37 @@ const getEmojiHex = (emoji: string) => {
19
  };
20
 
21
  export const Emoji: React.FC<EmojiProps> = memo(({ symbol, className = '', size }) => {
22
- // 如果不是 Emoji (比如纯数字或字母),直接渲染文本
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  const isEmoji = /\p{Emoji}/u.test(symbol);
24
-
25
  if (!isEmoji) {
26
  return <span className={className} style={{ fontSize: size }}>{symbol}</span>;
27
  }
28
 
 
29
  const hex = getEmojiHex(symbol);
30
 
31
  // 备用方案:如果转换失败,回退到原生显示
@@ -43,7 +75,7 @@ export const Emoji: React.FC<EmojiProps> = memo(({ symbol, className = '', size
43
  style={{
44
  width: size || '1em',
45
  height: size || '1em',
46
- verticalAlign: '-0.1em' // 微调对齐
47
  }}
48
  onError={(e) => {
49
  // 加载失败时隐藏图片,显示原生字符
@@ -51,6 +83,9 @@ export const Emoji: React.FC<EmojiProps> = memo(({ symbol, className = '', size
51
  const span = document.createElement('span');
52
  span.innerText = symbol;
53
  span.className = className || '';
 
 
 
54
  e.currentTarget.parentElement?.insertBefore(span, e.currentTarget);
55
  }}
56
  />
 
7
  size?: number | string;
8
  }
9
 
10
+ // 智能检测:是否为旧版 Windows 系统 (Windows 7, Vista, XP)
11
+ // Windows NT 6.1 = Windows 7
12
+ // Windows NT 6.0 = Vista
13
+ // Windows NT 5.x = XP
14
+ // Windows 8 (6.2) 及以上系统原生支持彩色 Emoji,无需替换
15
+ const isLegacyWindows = typeof navigator !== 'undefined' &&
16
+ /Windows NT (5\.|6\.[0-1])/.test(navigator.userAgent);
17
+
18
  // 将 Unicode 转换为 Twemoji 兼容的 Hex 文件名
19
  const getEmojiHex = (emoji: string) => {
20
  try {
 
27
  };
28
 
29
  export const Emoji: React.FC<EmojiProps> = memo(({ symbol, className = '', size }) => {
30
+ // 【性能优化】如果是现代系统,直接使用原生字体渲染
31
+ // 优点:无网络请求、加载快、与文字对齐更完美
32
+ if (!isLegacyWindows) {
33
+ return (
34
+ <span
35
+ className={className}
36
+ style={{
37
+ fontSize: size,
38
+ // 强制指定 Emoji 字体栈,确保在各平台优先调用彩色字体
39
+ fontFamily: '"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji", "Android Emoji", sans-serif',
40
+ lineHeight: '1em',
41
+ verticalAlign: 'middle',
42
+ display: 'inline-block'
43
+ }}
44
+ role="img"
45
+ aria-label={symbol}
46
+ >
47
+ {symbol}
48
+ </span>
49
+ );
50
+ }
51
+
52
+ // --- 以下逻辑仅在 Windows 7 等旧系统执行 ---
53
+
54
+ // 1. 简单正则判断是否包含 Emoji 字符 (避免对纯文本进行昂贵的 Hex 转换)
55
  const isEmoji = /\p{Emoji}/u.test(symbol);
 
56
  if (!isEmoji) {
57
  return <span className={className} style={{ fontSize: size }}>{symbol}</span>;
58
  }
59
 
60
+ // 2. 转换为图片链接
61
  const hex = getEmojiHex(symbol);
62
 
63
  // 备用方案:如果转换失败,回退到原生显示
 
75
  style={{
76
  width: size || '1em',
77
  height: size || '1em',
78
+ verticalAlign: '-0.1em' // 微调对齐,尽量模拟文字基线
79
  }}
80
  onError={(e) => {
81
  // 加载失败时隐藏图片,显示原生字符
 
83
  const span = document.createElement('span');
84
  span.innerText = symbol;
85
  span.className = className || '';
86
+ span.style.fontSize = typeof size === 'number' ? `${size}px` : (size as string) || '';
87
+ // 继承字体设置以防万一
88
+ span.style.fontFamily = '"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif';
89
  e.currentTarget.parentElement?.insertBefore(span, e.currentTarget);
90
  }}
91
  />