分享一种富文本打字机效果和代码实现

效果如图, 算法中用到了一个特殊字符做替换,所以确保你要显示的文字里不会出现那个特殊字符, 没有经过太多测试,抛砖引玉

const str = "<u>hello</u><color=#ff0000>Red Text,</color><br/>"+
                    "<size=60>enlarge me,</size>"+
                    "<br/><outline color=red width=4>A label with <i>outline,</i></outline>"+
                    "<br/><b>This text will be rendered as bold,</b>"+
                    "<br/><i>This text will be rendered as italic。</i>";
private richText(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");
            }
        }
        const lastStrArr: string[] = []; // 转换后富文本数组
        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);
            }
        }
        let lastStrIndex = 0;
        const func = () => {
            if (lastStrIndex >= lastStrArr.length) {
                return;
            }
            this.richtext.string = lastStrArr[lastStrIndex];
            lastStrIndex += 1;
            setTimeout(() => {
                func();
            }, 50);
        };
        setTimeout(() => {
            func();
        }, 1000);
    }
19赞

说下思路吧,creator 富文本标签里没有文字是不会显示的, 所以把标签里的文本都筛选出来,文本的位置用字符替换, 然后得到一个串, 再一个一个字替换回去,保存到数组里,感兴趣的可以一起交流

2赞

mark, 厉害了。

mark,厉害~

mark

mark

mark

mark

楼主,能不能把完整代码整理出来,共享一下哈。

mare a a

Mark

已经很完整了,我就不放工程了,稍微弄一下就能跑的

我发现这个在做切换的时候如果不等文字出来就切换就会出错,系统就崩了

mark

学习一下

我就是举个简单的例子, 你把settimeout换一下,或者在切换时停掉,就好了

1赞

mark ,厉害了学习学习。

mark

感觉富文本打字机效果的性能消耗好高,尤其是打印速度更快文字更多的话,如果是只修改一次富文本的文本,然后计算文本长度,添加遮罩来显示,会不会性能好一些。但是好像也不太知道该怎么做。

目前已经解决了,