前言

無(wú)需任何在線工具,一條命令生成 .ttf;前端只用 <input>,就能實(shí)時(shí)顯示高清彩色表情。把 PNG 表情包變成 Web 字體:_input __也能展示豐富的自定義表情。


一、為什么要“把圖變成字”

在我遇到的問(wèn)題背景下,核心是因?yàn)?input 不支持 UI 切出來(lái)的的表情圖片,尤其是在 uniApp 或者小程序使用富文本編輯器較為復(fù)雜的背景下,側(cè)面的一個(gè)實(shí)現(xiàn)方案。

二、整體流程

PNG 文件夾 → 映射表 → nanoemoji → TTF → CDN → @font-face → <input> 里打字出 Emoji

三、本地打包:png → ttf(30 秒)

1. 安裝依賴(lài)(一次性)

# mac / Linux / WSL 均可
# 創(chuàng)建并進(jìn)入 Python 隔離環(huán)境,避免包污染系統(tǒng)
python -m venv venv && source venv/bin/activate
# 升級(jí)安裝 nanoemoji 工具:把 PNG/SVG 打包成彩色字體
pip install -U nanoemoji

2. 準(zhǔn)備素材

emojis/
 ├─ grin.png
 ├─ cool.png
 └─ …

透明 PNG,建議 64×64 或 128×128。

3. 生成映射表(自動(dòng))

cd emojis/
# 把當(dāng)前目錄下所有 png 文件列出來(lái),自動(dòng)生成“文件名→Unicode私有碼位”映射表,保存為 config.csv
ls *.png | awk '{printf "%s,U+C%04X\n",$0,NR+0xC000}' > config.csv


示例輸出

grin.png,U+C001
cool.png,U+C002

碼位用私有區(qū) U+C000 ~ U+CFFF,不與系統(tǒng) Emoji 沖突。

4. 一鍵打包

nanoemoji \
  --config config.csv \
  --output_file emojifont.ttf \
  --color_format sbix        # 彩色位圖,兼容主流瀏覽器

得到:

  • emojifont.ttf (彩色)

  • emojifont.woff2 (自動(dòng)壓縮,更小)

5. 上傳 CDN

# 上傳至阿里云 OSS(提前安裝并配置 ossutil)
ossutil cp emojifont.ttf oss://yourbucket/font/


外鏈?zhǔn)纠?/p>

https://cdn.yourdomain.com/font/emojifont.ttf

四、前端:只在 <input> 里渲染 Emoji

1. 引入字體

@font-face {
  font-family: "iconfont";
  src: url("https://cdn.yourdomain.com/font/emojifont.ttf") format("truetype");
}


2. 輸入框樣式

.emoji-input {
  font-family: iconfont, system-ui, sans-serif;
  font-size: 24px;
  line-height: 1.2;
  width: 100%;
  padding: 8px;}

3. HTML 結(jié)構(gòu)

<!-- 表情按鈕 -->
<button class="emoji-btn" data-code="\uC001"></biaoingbutton>
<button class="emoji-btn" data-code="\uC002">biaoqing</button>

<!-- 核心:普通 input,卻能實(shí)時(shí)顯示彩色 Emoji -->
<input
  id="msgInput"
  class="emoji-input"
  maxlength="100"
  placeholder="點(diǎn)表情 / 直接打字"
/>

<button id="sendBtn">發(fā)送</button>

4. 插入邏輯

<!-- Vue3 Composition API 示例 --><template>
  <!-- 表情按鈕 -->
  <button
    v-for="({ icon, code }, idx) in emojiList"
    :key="idx"
    @click="insertEmoji(code)"
  >
    {{ icon }}
  </button>

  <!-- 輸入框 -->
  <input
    ref="inputRef"
    v-model="msg"
    maxlength="100"
    placeholder="點(diǎn)表情 / 直接打字"
  />

  <!-- 發(fā)送 -->
  <button @click="send">發(fā)送</button></template><script setup>import { ref } from 'vue'/* 數(shù)據(jù) */const msg = ref('')const inputRef = ref(null)const emojiList = [
  { icon: 'biaoqing', code: '\uC001' },
  { icon: 'biaoqing', code: '\uC002' }]/* 方法 */function insertEmoji(code) {
  const el = inputRef.value  if (!el) return
  const [start, end] = [el.selectionStart, el.selectionEnd]
  const newValue =
    msg.value.slice(0, start) + code + msg.value.slice(end)
  msg.value = newValue  // 恢復(fù)光標(biāo)位置
  nextTick(() => {
    el.setSelectionRange(start + code.length, start + code.length)
    el.focus()
  })}function send() {
  console.log('發(fā)送內(nèi)容:', msg.value) // 含 \uC001 等
  alert(`已發(fā)送:${msg.value}`)
  msg.value = ''}</script>

5. 效果

  • 用戶(hù)點(diǎn) (biaoqing) → input 立即出現(xiàn)彩色 grin 表情

  • 繼續(xù)敲普通字母無(wú)縫混合

  • 全程只用 <input>,沒(méi)有額外 <div> 或 <img>


五、常見(jiàn)坑 & 速查表

問(wèn)題解決方式
字體跨域 403CDN 加 Access-Control-Allow-Origin:*
碼位沖突堅(jiān)持私有區(qū) U+C000 ~ U+CFFF
小程序 web-view白名單 + base64 內(nèi)嵌(<30 KB)

六、一條命令總結(jié)

# ① 安裝
pip install -U nanoemoji

# ② 進(jìn)目錄
cd emojis/

# ③ 自動(dòng)生成映射表
ls *.png | awk '{printf "%s,U+C%04X\n",$0,NR+0xC000}' > config.csv

# ④ 打包
nanoemoji --config config.csv -o emojifont.ttf --color_format sbix

# ⑤ 上傳
上傳至你的CDN服務(wù)


七、示例效果

在這里插入圖片描述

相關(guān)文檔: