前言
一、為什么要“把圖變成字”
二、整體流程
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 └─ …
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
4. 一鍵打包
nanoemoji \ --config config.csv \ --output_file emojifont.ttf \ --color_format sbix # 彩色位圖,兼容主流瀏覽器
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. 效果
五、常見(jiàn)坑 & 速查表
| 問(wèn)題 | 解決方式 |
|---|---|
| 字體跨域 403 | CDN 加 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ù)


