vue表情包渲染,trie算法实现,表情包资源分享

表情包图片资源

https://yuan-1252477692.cos.ap-guangzhou.myqcloud.com/blog/files/emoticon.zip

data.json

    {
    "[微笑]": "enjoy1",
    "[撇嘴]": "enjoy2",
    "[色]": "enjoy3",
    "[发呆]": "enjoy4",
    "[得意]": "enjoy5",
    "[流泪]": "enjoy6",
    "[害羞]": "enjoy7",
    "[闭嘴]": "enjoy8",
    "[睡]": "enjoy9",
    "[大哭]": "enjoy10",
    "[尴尬]": "enjoy11",
    "[发怒]": "enjoy12",
    "[调皮]": "enjoy13",
    "[呲牙]": "enjoy14",
    "[惊讶]": "enjoy15",
    "[难过]": "enjoy16",
    "[囧]": "enjoy17",
    "[抓狂]": "enjoy18",
    "[吐]": "enjoy19",
    "[偷笑]": "enjoy20",
    "[愉快]": "enjoy21",
    "[白眼]": "enjoy22",
    "[傲慢]": "enjoy23",
    "[困]": "enjoy24",
    "[惊恐]": "enjoy25",
    "[流汗]": "enjoy26",
    "[憨笑]": "enjoy27",
    "[悠闲]": "enjoy28",
    "[奋斗]": "enjoy29",
    "[咒骂]": "enjoy30",
    "[疑问]": "enjoy31",
    "[嘘]": "enjoy32",
    "[晕]": "enjoy33",
    "[衰]": "enjoy34",
    "[骷髅]": "enjoy35",
    "[敲打]": "enjoy36",
    "[再见]": "enjoy37",
    "[擦汗]": "enjoy38",
    "[抠鼻]": "enjoy39",
    "[鼓掌]": "enjoy40",
    "[坏笑]": "enjoy41",
    "[左哼哼]": "enjoy42",
    "[右哼哼]": "enjoy43",
    "[哈欠]": "enjoy44",
    "[鄙视]": "enjoy45",
    "[委屈]": "enjoy46",
    "[快哭了]": "enjoy47",
    "[阴险]": "enjoy48",
    "[亲亲]": "enjoy49",
    "[可怜]": "enjoy50",
    "[菜刀]": "enjoy51",
    "[西瓜]": "enjoy52",
    "[啤酒]": "enjoy53",
    "[篮球]": "enjoy54",
    "[乒乓]": "enjoy55",
    "[咖啡]": "enjoy56",
    "[饭]": "enjoy57",
    "[猪头]": "enjoy58",
    "[玫瑰]": "enjoy59",
    "[凋谢]": "enjoy60",
    "[嘴唇]": "enjoy61",
    "[爱心]": "enjoy62",
    "[心碎]": "enjoy63",
    "[蛋糕]": "enjoy64",
    "[闪电]": "enjoy65",
    "[炸弹]": "enjoy66",
    "[刀]": "enjoy67",
    "[足球]": "enjoy68",
    "[瓢虫]": "enjoy69",
    "[便便]": "enjoy70",
    "[月亮]": "enjoy71",
    "[太阳]": "enjoy72",
    "[礼物]": "enjoy73",
    "[拥抱]": "enjoy74",
    "[强]": "enjoy75",
    "[弱]": "enjoy76",
    "[握手]": "enjoy77",
    "[胜利]": "enjoy78",
    "[抱拳]": "enjoy79",
    "[勾引]": "enjoy80",
    "[拳头]": "enjoy81",
    "[差劲]": "enjoy82",
    "[NO]": "enjoy84",
    "[OK]": "enjoy85",
    "[爱情]": "enjoy86",
    "[飞吻]": "enjoy87",
    "[跳跳]": "enjoy88",
    "[发抖]": "enjoy89",
    "[怄火]": "enjoy90",
    "[转圈]": "enjoy91",
    "[磕头]": "enjoy92",
    "[回头]": "enjoy93",
    "[嘿哈]": "enjoy94",
    "[奸笑]": "enjoy95",
    "[捂脸]": "enjoy96",
    "[机智]": "enjoy97"
    }

trie.js 核心算法

function Trie(){
  this.words = 0;
  this.empty = 1;
  this.index = 0;
  this.children = {};
}
Trie.prototype = {
  insert: function(str, pos = 0, idx){
    if(str.length === 0) {
      return;
    }
    let k;
    let child;
    if(pos === str.length) {
      this.index = idx;
      return;
    }
    k = str[pos];
    if(this.children[k] === undefined){
      this.children[k] = new Trie();
      this.empty = 0;
      this.children[k].words = this.words + 1;
    }
    child = this.children[k];
    child.insert(str, pos + 1, idx);
  },
  build: function(arr){
    let len = arr.length;
    for(let i = 0; i < len; i++){
      this.insert(arr[i], 0, i);
    }
  },
  searchOne: function(str, pos = 0){
    let result = {};
    if(str.length === 0) {
      return result;
    }
    let child;
    let k;
    result.arr = [];
    k = str[pos];
    child = this.children[k];
    if(child !== undefined && pos < str.length){
      return child.searchOne(str,  pos + 1);
    }
    if(child === undefined && this.empty === 0){
      return result;
    }
    if(this.empty === 1){
      result.arr[0] = pos - this.words;
      result.arr[1] = this.index;
      result.words = this.words;
      return result;
    }
    return result;
  },
  search: function(str){
    if(this.empty === 1) {
      return [];
    }
    let len = str.length;
    let searchResult = [];
    let tmp;
    for(let i = 0; i < len - 1; i++){
      tmp = this.searchOne(str, i);
      if(typeof tmp.arr !== 'undefined' && tmp.arr.length > 0){
        searchResult.push(tmp.arr);
        i = i + tmp.words - 1;
      }
    }
    return searchResult;
  }
};
if(typeof module !== 'undefined'){
  module.exports = Trie;
}else if(typeof window !== 'undefined'){
  window._qqWechatEmotionParser.Trie = Trie;
}

index.js 操作

let emotionMap, trie, emotionList, Trie;
function keys(map){
  let list = [];
  for (let k in map) {
    if (map.hasOwnProperty(k)) {
      list.push(k);
    }
  }
  return list;
}
function build(){
  emotionList = keys(emotionMap);
  trie = new Trie();
  trie.build(emotionList);
}
function splice(str, index, count, add) {
  return str.slice(0, index) + add + str.slice(index + count);
}
function qqWechatEmotionParser(s) {
  let str = s
  let indices = trie.search(str);
  indices.reverse().map(function(idx) {
    let pos = idx[0],
      emotion = emotionList[idx[1]],
      img = '<img src="' + require('../../assets/images/emoticon/' + emotionMap[emotion] + '.png') + '" alt="' + emotion + '" style="width: 1.5em;">';
    str = splice(str, pos, emotion.length, img);
  });
  return str;
}
if(typeof module !== 'undefined'){
  emotionMap = require('./data.json');
  Trie = require('./trie');
  build();
  module.exports = qqWechatEmotionParser;
} else if(window !== 'undefined'){
  emotionMap = window._qqWechatEmotionParser.emotion_map;
  Trie = window._qqWechatEmotionParser.Trie;
  build();
  window.qqWechatEmotionParser = qqWechatEmotionParser;
}

测试

import qqWechatEmotionParser from './utils/enjoyAnalysis/index'
let content = qqWechatEmotionParser('[害羞]亲亲您好[玫瑰][玫瑰]')

tip: 如直接对接到微信,消息发送至微信客户端,则无需转换成图片,直接以[玫瑰][笑哭]的形式发送,微信会自动解析
测试结果

<img src="https://img-blog.csdnimg.cn/2022010702185025392.png" alt="[害羞]" style="width: 1.5em;">亲亲您好<img src="https://img-blog.csdnimg.cn/2022010702185025917.png" alt="[玫瑰]" style="width: 1.5em;">

亲亲您好

vue页面显示所有表情包供选择

<template>
  <div class="enjoy_panel">
    <div class="enjoy_list">
      <div v-for="(item,index) in enjoyData" :key="index" @click="onChoiceEnjoy(index)">
        <img style="width: 25px;height: 25px" v-lazy="require('./../../../assets/images/emoticon/' + item + '.png')" alt=""/>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'index',
  data () {
    return {
      enjoyData: require('../../../utils/enjoyAnalysis/data.json')
    }
  },
  methods:{
    onChoiceEnjoy(index){
      this.$emit('onChoiceEnjoy', index)
    }
  }
}
</script>

<style scoped lang="less">
  .enjoy_panel{
    width:100%;
    height: 100%;
    overflow-x: hidden;
    overflow-y: auto;
    &>.enjoy_list{
      display: grid;
      grid-template-columns: repeat(8,12.5%);
      justify-items: center;
      &>div{
        padding: 2px 0;
        &:active{
          opacity: 0.8;
        }
      }
    }
  }
</style>

最终结果不宜直接放入v-html,因为不会过滤标签,如需过滤自信写正则去除标签

其实还可以用文件名代替表情名称

以上思路来自qq-wechat-emotion-parser插件,改版实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值