TinyMCE自定义表情包
loyalty
原创
category
前端
date_range
发表于2022-10-27
remove_red_eye
1316
source
0
favorite
0
tag富文本
记录一次接手别人代码的经历 - TinyMCE自定义表情包
“那个xxx没做过表情功能,你在xxx项目做过,这个功能你来完成吧。” 一句简短的话语,开启了改造表情之路。
简单了解一下项目,使用的是vue结合TinyMCE富文本,开始造吧。
一、效果图
整体效果图如下:
二、准备工作
- 表情包
既然是自定义表情包,必然得自备一些表情图片(文末免费领取QQ表情包——gif格式)。
三、使用tinymce-vue
1. 安装
- Vue3.x
npm install --save "@tinymce/tinymce-vue@^4"
- Vue2.x
npm install --save "@tinymce/tinymce-vue@^3"
2. 使用
引入富文本,在工具栏配置自带的表情包。
<template>
<div>
<editor v-model="content" ref="tinymce" id="tinymce-vue" :init="init" />
</div>
</template>
<script>
import Editor from '@tinymce/tinymce-vue'
export default {
name: 'Editor',
components: {
'editor': Editor
},
data () {
return {
content: '',
init: {
selector: '#tinymce-vue',
plugins: 'emoticons', // tinymce自带表情
toolbar: 'emoticons',
}
}
}
}
</script>
3. 自定义表情包
在init中新增自定义表情配置,并新增表情列表弹框(见末尾完整代码)
setup: editor => {
// 自定义表情
editor.ui.registry.addButton('emoji', {
text: '<svg t="1666853449306" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3854" width="18" height="18"><path d="M512 959.1c-114.6 0-229.1-43.6-316.3-130.9-174.3-174.4-174.2-458.1 0.2-632.4C298.7 93 445.6 46.6 589 71.5c14.3 2.5 23.9 16.1 21.4 30.4-2.5 14.3-16.1 23.9-30.4 21.4-126.5-22-256.2 19-347 109.7-153.9 153.8-154 404.2-0.2 558.1 153.8 153.9 404.2 154 558.1 0.2s154-404.2 0.2-558.2c-15.4-15.4-32-29.5-49.6-42.1-11.8-8.5-14.5-24.9-6-36.7 8.5-11.8 24.9-14.5 36.7-6 19.8 14.2 38.7 30.3 56.1 47.7 174.3 174.4 174.2 458.1-0.2 632.5-87.1 87-201.6 130.6-316.1 130.6z" p-id="3855"></path><path d="M312.8 410.7m-42.8 0a42.8 42.8 0 1 0 85.6 0 42.8 42.8 0 1 0-85.6 0Z" p-id="3856"></path><path d="M715.6 410.9m-42.5 0a42.5 42.5 0 1 0 85 0 42.5 42.5 0 1 0-85 0Z" p-id="3857"></path><path d="M281.1 553.2v0.4c0 127.5 103.3 231 230.9 231s231-103.3 231-230.9v-0.4l-461.9-0.1z" fill="#FFA786" p-id="3858"></path><path d="M512 810.9s-0.1 0 0 0c-141.9 0-257.3-115.5-257.2-257.3 0-7.9 3.2-26.2 32.7-26.3h82.4c67.1 0 160.4 0 236.9 0.1l133.6 0.1c28.6 0.1 28.9 26 28.9 26.3-0.1 141.7-115.5 257.1-257.3 257.1zM309 579.8c12.9 100.5 99 178.5 202.9 178.5h0.1c103.9 0 190-77.9 203-178.4-82.1 0-324-0.1-406-0.1z" p-id="3859"></path><path d="M673.4 124.4m-26.3 0a26.3 26.3 0 1 0 52.6 0 26.3 26.3 0 1 0-52.6 0Z" fill="#FFA786" p-id="3860"></path></svg>',
tooltip: '添加一段文字',
onAction: () => {
// 打开表情弹框
this.dialogVisible = true
}
});
}
4. 插入表情
为表情新增点击事件,点击后插入到富文本中。将光标移动到插入的表情后并聚焦。
// 选择表情
choose (item) {
// 获取当前富文本
let ed = this.$refs.tinymce.editor
// 获取插入对象
let range = ed.selection.getRng()
// 创建img
let imgNode = ed.getDoc().createElement('img')
imgNode.src = `/qq/old/${item}.gif`
// 插入表情
range.insertNode(imgNode)
// 关闭弹框
this.dialogVisible = false
// 光标聚焦并移动至插入的表情后
ed.execCommand('seleceAll')
ed.selection.getRng().collapse()
ed.focus()
}
5. 完整代码
<template>
<div>
<editor v-model="content" ref="tinymce" id="tinymce-vue" :init="init" />
<el-dialog title="自定义表情包" :visible.sync="dialogVisible" width="600px">
<div class="emoji">
<div class="emoji-item" v-for="item in 132" :key="item">
<img :src="`/qq/old/${item}.gif`" alt="error" @click="choose(item)">
</div>
</div>
</el-dialog>
</div>
</template>
<script>
// 引入tinymce-vue
import Editor from '@tinymce/tinymce-vue'
export default {
name: 'Editor',
components: {
'editor': Editor
},
data () {
return {
dialogVisible: false,
content: '',
init: {
selector: '#tinymce-vue',
plugins: 'emoticons', // tinymce自带表情
toolbar: 'emoticons emoji oneButton',
setup: editor => {
// 自定义表情
editor.ui.registry.addButton('emoji', {
// 使用svg表情图标
text: '<svg t="1666853449306" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3854" width="18" height="18"><path d="M512 959.1c-114.6 0-229.1-43.6-316.3-130.9-174.3-174.4-174.2-458.1 0.2-632.4C298.7 93 445.6 46.6 589 71.5c14.3 2.5 23.9 16.1 21.4 30.4-2.5 14.3-16.1 23.9-30.4 21.4-126.5-22-256.2 19-347 109.7-153.9 153.8-154 404.2-0.2 558.1 153.8 153.9 404.2 154 558.1 0.2s154-404.2 0.2-558.2c-15.4-15.4-32-29.5-49.6-42.1-11.8-8.5-14.5-24.9-6-36.7 8.5-11.8 24.9-14.5 36.7-6 19.8 14.2 38.7 30.3 56.1 47.7 174.3 174.4 174.2 458.1-0.2 632.5-87.1 87-201.6 130.6-316.1 130.6z" p-id="3855"></path><path d="M312.8 410.7m-42.8 0a42.8 42.8 0 1 0 85.6 0 42.8 42.8 0 1 0-85.6 0Z" p-id="3856"></path><path d="M715.6 410.9m-42.5 0a42.5 42.5 0 1 0 85 0 42.5 42.5 0 1 0-85 0Z" p-id="3857"></path><path d="M281.1 553.2v0.4c0 127.5 103.3 231 230.9 231s231-103.3 231-230.9v-0.4l-461.9-0.1z" fill="#FFA786" p-id="3858"></path><path d="M512 810.9s-0.1 0 0 0c-141.9 0-257.3-115.5-257.2-257.3 0-7.9 3.2-26.2 32.7-26.3h82.4c67.1 0 160.4 0 236.9 0.1l133.6 0.1c28.6 0.1 28.9 26 28.9 26.3-0.1 141.7-115.5 257.1-257.3 257.1zM309 579.8c12.9 100.5 99 178.5 202.9 178.5h0.1c103.9 0 190-77.9 203-178.4-82.1 0-324-0.1-406-0.1z" p-id="3859"></path><path d="M673.4 124.4m-26.3 0a26.3 26.3 0 1 0 52.6 0 26.3 26.3 0 1 0-52.6 0Z" fill="#FFA786" p-id="3860"></path></svg>',
tooltip: '自定义表情包',
onAction: () => {
// 打开表情列表弹框
this.dialogVisible = true
}
});
// 自定义其他工具栏选项
editor.ui.registry.addButton('oneButton', {
text: 'Insert Hello',
tooltip: '添加一段文字',
onAction: () => {
editor.insertContent('Hello');
}
});
}
}
}
},
methods: {
// 选择表情
choose (item) {
// 获取当前富文本
let ed = this.$refs.tinymce.editor
ed.focus() // 默认聚焦一次,防止初始化后直接插入表情光标bug(在表情前方)
// 获取插入对象
let range = ed.selection.getRng()
// 创建img
let imgNode = ed.getDoc().createElement('img')
imgNode.src = `/qq/old/${item}.gif`
// 插入表情
range.insertNode(imgNode)
// 关闭弹框
this.dialogVisible = false
// 光标聚焦并移动至插入的表情后
ed.execCommand('seleceAll')
ed.selection.getRng().collapse()
ed.fire('change') // 触发change事件,解决v-model不生效bug
ed.focus()
}
}
}
</script>
<style scoped>
.emoji {
display: flex;
flex-wrap: wrap;
}
.emoji .emoji-item {
display: flex;
justify-content: center;
align-items: center;
margin-left: 10px;
margin-bottom: 8px;
}
img {
width: 24px;
height: 24px;
cursor: pointer;
}
</style>
四、总结
自定义表情包,本质上就是把图片插入到富文本中。
QQ表情包,私聊我免费领取。地址:qq动态表情包gif格式_新版&旧版&搞笑版,拿来即用的emoji
评论

暂无评论