表情emoji

判断是否输入emoji

  // 判断是否输入emoji
    function isEmojiCharacter(substring) {
    for ( var i = 0; i < substring.length; i++) {
        var hs = substring.charCodeAt(i);
        if (0xd800 <= hs && hs <= 0xdbff) {
            if (substring.length > 1) {
                var ls = substring.charCodeAt(i + 1);
                var uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                if (0x1d000 <= uc && uc <= 0x1f77f) {
                    return true;
                }
            }
        } else if (substring.length > 1) {
            var ls = substring.charCodeAt(i + 1);
            if (ls == 0x20e3) {
                return true;
            }
        } else {
            if (0x2100 <= hs && hs <= 0x27ff) {
                return true;
            } else if (0x2B05 <= hs && hs <= 0x2b07) {
                return true;
            } else if (0x2934 <= hs && hs <= 0x2935) {
                return true;
            } else if (0x3297 <= hs && hs <= 0x3299) {
                return true;
            } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030
                    || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b
                    || hs == 0x2b50) {
                return true;
            }
        }
    }
}

根据emoji.unified显示emoji表情

 /* 利用findSurrogatePair结合String.fromCharCode()来对unicode编码进行处理 */
    function findSurrogatePair(point: any): any {
      // assumes point > 0xffff
      const offset = point - 0x10000,
        lead = 0xd800 + (offset >> 10),
        trail = 0xdc00 + (offset & 0x3ff);
      return [lead.toString(16), trail.toString(16)];
    }
    let afterEmoji: any;
    if (emoji.unified.length === 4) {
      afterEmoji = String.fromCharCode(+'0x' + emoji.unified);
      alert(afterEmoji);
    } else {
      const beforeEmoji = findSurrogatePair('0x' + emoji.unified);
      afterEmoji = beforeEmoji.map(function (item: any, index: any): any {
        const str = new String('0x' + item.trim());
        return str;
      });
      afterEmoji = String.fromCharCode(afterEmoji[0], afterEmoji[1]);
      alert(afterEmoji);
    }
    const expressionContent: any = afterEmoji;

emoji.unified哪些范围的可以在安卓机上显示(只测了部分)

<1f920只测了一部分
在安卓机上可以显示
1f920
1f930~1f93e
1f940~1f94b
1f950~1f95e
1f980~1f991
1f9c0
在安卓机上可以显示
>=20000时在pc端显示汉字等字,但是在安卓机上也没有显示出来,还是带叉的矩形框(只测了部分)
2049-fe0f这个也可以,对应的是一个感叹号加一个问号
四位数的也只测了几个,但是这几个也可以: 2753对应的是一个红色的问号 2754对应的是一个白色的问号,建议最好使用时再测一下,以防有所改动。

上面提到了charCodeAtfromCharCode
charCodeAt() 是普通字符串的方法,返回字符串指定位置的Unicode码点(十进制)表示。

var str=“abc”; console.log(str.charCodeAt(0);
97

fromCharCode() 它是String对象提供的静态方法(即定义在对象实例的方法),该方法的参数是一个或者多个值,代表unicode码点,返回值是这些码点组成的字符串。

String.fromCharCode(104,101,108,108,111);
hello
String.fromCharCode(97);
a

emoji的使用

import {emojiIndex, Emoji} from 'emoji-mart'
const emINDEX: any = emojiIndex; //用于遍历表情数组,进行高级查询
1、存放表情在对应的图片中的位置posArray
2、表情集合emojiPoformaceArray
3、表情对应名字集合emojiNameArray

发送信息模块
首先得有一个用于高级查询的表情数组(如果明确要哪几个表情,没必要使用这种,可以直接使用,具体参照github对应的文章就可以。如果没有明确要哪个表情,就可以使用这种方式。
public constructor(props: IPropsSendAndShow){
/* 关于表情的部分为了防止初加载时没有显示出来对应的图片位置,对其设置了内容(即表情),后来加载出来后,需要清空之前的内容,显示图片就行 */
    const timer = setInterval(function (): void {
      if ($('#emoticonPackage .EmotionList-con button span')) {
        if ($('#emoticonPackage .EmotionList-con button span').css('background-position')) {
          $('#emoticonPackage .EmotionList-con button span').html('');
          clearInterval(timer);
        }
      }
    }, 1000);
this.state={arrayExpressSearch ['question','high five','hand','bell','+1','smile','good','congra','sad','hug','face_with_thermometer','presnt','book','paper',....]}
const aExprssion: any = this.state.arrayExpressSearch;
aExprssion.map((item: any,index: any): any=>{
const result1=emINDEX.search(item).map((o:any,Index: any): any=>{
//因为有些表情部分安卓手机显示不出来,所以做了处理
  if ((o.unified <= '1f920' || o.unified >= '1f930' && o.unified <= '1f93e' || o.unified >= '1f940' && o.unified <= '1f94b' || o.unified >= '1f950' && o.unified <= '1f95e' || o.unified >= '1f980' && o.unified <= '1f991' || o.unified === '1f9c0') && o.unified < '20000' && o.unified !== "1f91f" && o.unified !== "1f481-200d-2642-fe0f" && o.unified !== "1f64b-200d-2642-fe0f" && o.unified !== "1f481-200d-2640-fe0f" && o.unified !== "1f64b-200d-2640-fe0f" || o.unified.length === 4) {
          emojiPoformaceArray.push(o.native);
          emojiNameArray.push(o.name);
 /*  const emojiProperty: any = { id: o['id'], skin: 6 };
           return (
             <em className="EmotionList-item" key={o['id']}>
               <Emoji emoji={emojiProperty} size={30} tooltip={true} set={'emojione' ? 'emojione' : 'apple' ? 'apple' : 'facebook' ? 'facebook' : 'google' ? 'google' : 'messenger' ? 'messenger' : 'twitter'}
                 backgroundImageFn={((set, sheetSize) => require('./images/appleExpress.png'))} onClick={(emoji, event) => that.expressionHandle(emoji)} />
             </em>
           ); */
        }
      });
    //  resultexpression.push(result1); // 用于获取所有展示出的表情在图片中的位置集合posArray
    });

public componentDidMount(): void{
    const oSpan = $('.EmotionList-con span');
    const oTSpan = Array.prototype.slice.call(oSpan);
    const arr: any = [];
    oTSpan.map((item: any, index: any) => {
      arr.push($(item).css('background-position'));
    });
    console.log(arr);//获取到要展示的表情对应的位置,就可以直接写死了posArray(其值就是arr)
}
       生成的表情块
        <aside id="emoticonPackage">
          <div className="emoticonPackagecontainer">
            <div className="EmotionList">
              <div className="EmotionList-con" style={{ top: '0px' }}>
                {emojiPoformaceArray.map((item: any, index: any) => {
                  return (
                    <button title={emojiNameArray[index]} className="emoji-mart-emoji" type="button" key={index} onClick={() => that.expressionHandle(item)}>
                      <span style={{ backgroundPosition: posArray[index] }}>{item}</span>
                    </button>
                  );
                })}
              </div>
	/*  最初使用下边的dom,是为了在componnetDidMount中获取所有展示出的表情在图片中的位置集合posArray,然后就可以使用上边的了 */
              {/*   <div className="EmotionList-con" style={{ top: '0px' }}>{resultexpression}</div> */} 
            </div>
          </div>
        </aside>
展示消息模块
 searchSubStr查找一个字符串中的某个字串的位置
 posLenIndex信息中的表情的在信息中对应的位置、表情的长度、表情集合中对应的索引位(用作查找到图片位置数组对应的数据)
 三种情况:发的信息中有表情存在、送花、信息中没有表情
 
  public render(): React.ReactNode {
    return (
      <div className="center" id="dialogue">
        {this.state.message.map((item, index) => {
          let content = JSON.parse(item)["content"][0];
          let contentCopy: any = '';
          /**
           *查找一个字符串中的所有子串的位置
           * * */
          function searchSubStr(str: any, subStr: any, positions: any): void {
            let pos = str.indexOf(subStr);
            while (pos > -1) {
              positions.push(pos);
              pos = str.indexOf(subStr, subStr.length + pos);
            }
          }
          const posLenIndex: any = []; // 信息中包含的所有表情对应的在信息中的位置、表情的长度、对应的表情数组的索引位(用作查找到图片位置数组对应的数据)
          emojiPoformaceArray.map((item: any, index: any) => {
            const xh = content.indexOf(item);
            if (xh !== -1) {
              const positions = new Array();
              searchSubStr(content, item, positions);
              posLenIndex.push({
                posArr: positions,
                len: item.length,
                emoitionIndex: index,
              });
            }
          });
          if (posLenIndex.length > 0) { // 发的信息中有表情存在
            posLenIndex.map((a: any, b: any) => {
              const sen = `<span style="background-position:${posArray[a.emoitionIndex]}"></span>`;
              a.posArr.map((c: any, d: any) => { // 遍历是因为在上面emojiPoformaceArray的遍历中用g也不能全部替换,所以就在生成的posLenIndex数组中遍历
                const newItem = new RegExp(emojiPoformaceArray[a.emoitionIndex], 'g'); // 带上g谁知也没有全部替换,所以就在每次变化后重新赋给content
                contentCopy = content.replace(newItem, sen);
                content = contentCopy;
              });
            });
          } else if (content === '?') { // 送花
            contentCopy = `<span class='special' style='background-size: 30px 30px;width: 30px; height: 30px;'></span>`;
          } else { // 没有表情信息
            contentCopy = content;
          }
          return (
            <figure key={index}>
              <img src={JSON.parse(item).user.avatar} alt="头像" onError={(e: any) => { e.currentTarget.src = require("./images/rentou.jpg"); }} /> 
              <figcaption>
                <div className="left">
                  <p dangerouslySetInnerHTML={{ __html: contentCopy }}></p>
                </div>
              </figcaption>
            </figure>
          );
        })}
      </div>
    );
  }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值