实现小程序 uniApp 输入框展示自定义表情包

前言

无需任何在线工具,一条命令生成 .ttf;前端只用 <input>,就能实时显示高清彩色表情。把 PNG 表情包变成 Web 字体:_input __也能展示丰富的自定义表情。


一、为什么要"把图变成字"

在我遇到的问题背景下,核心是因为 input 不支持 UI 切出来的的表情图片,尤其是在 uniApp 或者小程序使用富文本编辑器较为复杂的背景下,侧面的一个实现方案。

二、整体流程

复制代码
PNG 文件夹 → 映射表 → nanoemoji → TTF → CDN → @font-face → <input> 里打字出 Emoji

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

1. 安装依赖(一次性)

bash 复制代码
# mac / Linux / WSL 均可
# 创建并进入 Python 隔离环境,避免包污染系统
python -m venv venv && source venv/bin/activate
# 升级安装 nanoemoji 工具:把 PNG/SVG 打包成彩色字体
pip install -U nanoemoji

2. 准备素材

复制代码
emojis/
 ├─ grin.png
 ├─ cool.png
 └─ ...

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

3. 生成映射表(自动)

bash 复制代码
cd emojis/
# 把当前目录下所有 png 文件列出来,自动生成"文件名→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

码位用私有区 U+C000 ~ U+CFFF,不与系统 Emoji 冲突。

4. 一键打包

bash 复制代码
nanoemoji \
  --config config.csv \
  --output_file emojifont.ttf \
  --color_format sbix        # 彩色位图,兼容主流浏览器

得到:

  • emojifont.ttf (彩色)
  • emojifont.woff2 (自动压缩,更小)

5. 上传 CDN

bash 复制代码
# 上传至阿里云 OSS(提前安装并配置 ossutil)
ossutil cp emojifont.ttf oss://yourbucket/font/

外链示例:

复制代码
https://cdn.yourdomain.com/font/emojifont.ttf

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

1. 引入字体

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

2. 输入框样式

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

3. HTML 结构

html 复制代码
<!-- 表情按钮 -->
<button class="emoji-btn" data-code="\uC001">😀</button>
<button class="emoji-btn" data-code="\uC002">😎</button>

<!-- 核心:普通 input,却能实时显示彩色 Emoji -->
<input
  id="msgInput"
  class="emoji-input"
  maxlength="100"
  placeholder="点表情 / 直接打字"
/>

<button id="sendBtn">发送</button>

4. 插入逻辑

js 复制代码
<!-- 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="点表情 / 直接打字"
  />

  <!-- 发送 -->
  <button @click="send">发送</button>
</template>

<script setup>
import { ref } from 'vue'

/* 数据 */
const msg = ref('')
const inputRef = ref(null)
const emojiList = [
  { icon: '😀', code: '\uC001' },
  { icon: '😎', 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

  // 恢复光标位置
  nextTick(() => {
    el.setSelectionRange(start + code.length, start + code.length)
    el.focus()
  })
}

function send() {
  console.log('发送内容:', msg.value) // 含 \uC001 等
  alert(`已发送:${msg.value}`)
  msg.value = ''
}
</script>

5. 效果

  • 用户点 😀 → input 立即出现彩色 grin 表情
  • 继续敲普通字母无缝混合
  • 全程只用 <input>,没有额外 <div><img>

五、常见坑 & 速查表

问题 解决方式
字体跨域 403 CDN 加 Access-Control-Allow-Origin:*
码位冲突 坚持私有区 U+C000 ~ U+CFFF
小程序 web-view 白名单 + base64 内嵌(<30 KB)

六、一条命令总结

bash 复制代码
# ① 安装
pip install -U nanoemoji

# ② 进目录
cd emojis/

# ③ 自动生成映射表
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服务

七、示例效果

相关文档:

相关推荐
云云只是个程序马喽5 小时前
AI漫剧创作系统开发定制指南
人工智能·小程序·php
专科3年的修炼1 天前
uni-app移动应用开发第四章
开发语言·javascript·uni-app
cosinmz2 天前
图片太多太乱怎么整理?分享一个我最近常用的图片转 PDF方法
经验分享·小程序·pdf
q5507071772 天前
uniapp/uniappx实现原生图片编辑涂鸦、贴图、滤镜、旋转、裁剪等
uni-app
科技互联.2 天前
2026年小程序定制市场:个性化需求激增,技术深度成竞争关键
人工智能·小程序
小羊Yveesss2 天前
2026年小程序商城的现状和发展趋势
小程序
智慧景区与市集主理人2 天前
五一市集分账混乱?巨有科技智慧市集小程序实现统一收款、自动分账
大数据·科技·小程序
程序鉴定师2 天前
深圳小程序制作哪家好?2026深度市场分析与选择指南?
大数据·小程序
河北清兮网络科技2 天前
广告联盟全解析:从开发接入到运营优化,多视角拆解流量变现逻辑
小程序·app
计算机学姐2 天前
基于微信小程序的校园失物招领管理系统【uniapp+springboot+vue】
java·vue.js·spring boot·mysql·信息可视化·微信小程序·uni-app