实现含富文本的打字机效果

public richText(textLabel:mo.EUI.Label,str: string = "") {
            const regex = /\[.+?\/?\]/g; // 匹配中括号标签
            const matchArr = str.match(regex);
            const specialChar = "│";
            const replaceStr = str.replace(regex, specialChar); // 标签数组
            const textArr: string[] = replaceStr.split(specialChar); // 文字数组
            const strArr: string[] = []; // 存放处理过的文字数组
            let paraNum = 0; // 待替换参数个数
            for (let text of textArr) {
                // 非空字符替换成类似 $[0-n] 参数
                if (text !== "") {
                    text = `$[${paraNum}]`;
                    paraNum += 1;
                }
                strArr.push(text);
            }
            let templetStr: string = strArr.join(specialChar); // 数组转成待替换字符串
            for (let index = 0; index < textArr.length; index++) {
                // 转换代替换字符串之后, 删除文字数组多余空字符
                if (textArr[index] === "") {
                    textArr.splice(index, 1);
                    index = index - 1;
                }
            }
            while (templetStr.search(specialChar) !== -1) {
                // 数组转成的字符串原本 '特殊字符' 位置都是富文本标签的位置, 替换回标签
                if (matchArr[0]) {
                    templetStr = templetStr.replace(specialChar, matchArr[0].toString());
                    matchArr.splice(0, 1);
                } else {
                    templetStr = templetStr.replace(specialChar,             "");// 空字符串替换,防止死循环
                    console.warn("matchArr not enough");
                }
            }
            console.log("xxxxxx:", templetStr)
            const lastStrArr: string[] = []; // 转换后富文本数组
            ///
            const arrayParm:string[] = [];
            for (let i = 0; i < paraNum; i++) {
                arrayParm.push("");
            }//同const arrayParm: string[] = new Array(paraNum).fill("");
            
            for (let i = 0; i < textArr.length; i++) {
                for (const text of textArr[i]) {
                    arrayParm[i] = arrayParm[i] + text;
                    let replaceStr1 = templetStr;
                    for (let index = 0; index < paraNum; index++) {
                        replaceStr1 = replaceStr1.replace(`$[${index}]`, arrayParm[index]);
                    }
                    lastStrArr.push(replaceStr1);
                }
            }
            console.log("bbbbb:"+lastStrArr);
            let lastStrIndex = 0;
            const func = () => {
                if (lastStrIndex >= lastStrArr.length) {
                    return;
                }
                textLabel.text = lastStrArr[lastStrIndex];
                lastStrIndex += 1;
                setTimeout(() => {
                    func();
                }, 100);
            };
            setTimeout(() => {
                func();
            }, 100);
        }

实现打字机效果。支持[ubb color=0xff0000][/ubb]格式
如果要配置
<color=0xff0000></color>
const regex = /\[.+?\/?\]/g;
替换为const regex = /<.+?\/?>/g;

//这是把字拆成一个一个单字的方式,然后连接起来
_timerTaskId_chatOpen = 0; //对白开启定时器
        _strList:any[];
        _textLabel:any;
        _labelStr:string;
        _currentStr:string;
        _speed:number = 60; //速度

        public constructor(speed:number =60) {
            let self = this;
            self._speed = speed;
        }

        //开始动画
        public startAni(textLabel:mo.EUI.Label, str:string){
            if(!textLabel||!str){
                return;
            }
            let self = this;

           self._currentStr = "";
            let spaceReg:RegExp = /\[ubb/g;
            let result = str.search(spaceReg);
            if(result==-1){
                textLabel.text = str;
                self._labelStr = textLabel.text;
                textLabel.text = "";
                self._textLabel = textLabel;

                //self._labelStr = str;
                self._strList = [];
                for(let i=0;i<mo.STR.getLength(self._labelStr);i++){
                    let st = self._labelStr.substring(i,i+1);
                    if(st!=""){
                        self._strList.push(st);
                    }
                }
            }else{
                textLabel.text = "";
                self._textLabel = textLabel;
                self._labelStr = str;
                self._strList = [];
                let list1 = str.split("[/br]");
                for(let v1 of list1){
                    let list2 = v1.split("[ubb");
                    for(let v2 of list2){
                        if(v2==""){
                            continue;
                        }
                        let spaceReg1:RegExp = /ubb\]/g;
                        let result1 = v2.search(spaceReg1);
                        if(result1!=-1){
                            let list3 = v2.split("[/ubb]");
                            mo.ARR.rm(list3,"");
                            let color = list3[0];
                            let str1 = list3[1];
                            let colorType = "[ubb";
                            let colorStr = "";
                            let count = 0;
                            for(let i1=0;i1<mo.STR.getLength(color);i1++){
                                let st = color.substring(i1,i1+1);
                                if(st!=""){
                                    if(count==0){
                                        colorType = colorType+st;
                                    }else{
                                        colorStr = colorStr+st;
                                    }
                                    if(st=="]"){
                                        count = count+1;
                                    }
                                }
                            }
                            for(let i2=0;i2<mo.STR.getLength(colorStr);i2++){
                                let st = colorStr.substring(i2,i2+1);
                                if(st!=""){
                                    self._strList.push(colorType+st+"[/ubb]");
                                }
                            }
                            if(str1&&str1!=""){
                                for(let i3=0;i3<mo.STR.getLength(str1);i3++){
                                    let st = str1.substring(i3,i3+1);
                                    if(st!=""){
                                        self._strList.push(st);
                                    }
                                }
                            }
                        }else{
                            for(let i4=0;i4<mo.STR.getLength(v2);i4++){
                                let st = v2.substring(i4,i4+1);
                                if(st!=""){
                                    self._strList.push(st);
                                }
                            }
                        }
                    }
                    self._strList.push("[/br]");
                }
            }



            self.dialogAni();
        }
        private dialogAni():void{
            let self = this;
            if(self._strList && self._strList.length<=0){
                self.stopAni();
                return;
            }
            self._timerTaskId_chatOpen = mo.setTimeout(function () {
                if(self._strList && self._strList.length>0){
                    self._currentStr += self._strList.shift();
                    self._textLabel.text = self._currentStr;
                    self.dialogAni();
                }
            }, self, self._speed);
        }
        //停止动画
        public stopAni(cb?:any){
            let self = this;
            if(self._timerTaskId_chatOpen!=0){
                mo.clearTimeout(self._timerTaskId_chatOpen);
                self._timerTaskId_chatOpen = 0;
                if(self._textLabel) self._textLabel.text = self._labelStr;
                self.onExit();
            }else{
                if(cb) cb();
            }
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pilihou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值