Laya富文本工具类(支持多色文字|字体设置|指定文本点击响应)

背景

使用官方提供的 Laya.HTMLDivElement, 设置字体不生效, 下划线不生效

思路

查看 Laya 引擎源码与断点 HTMLDivElement 对象后发现2点:

  1. 点击 HTMLDivElement 后, 当 href 不为空时, 会派发 Laya.Event.LINK 事件;
  2. 赋值 innerHtml 时, 每一个 span 都会生成一个 HTMLElement 对象, 可以用来设置 href 值.

用处

  1. 多色自定义字体文本显示
  2. 新手引导, 一段文本不同内容点击响应不同操作

效果

在这里插入图片描述

实现

// 使用  this.lab_content 编辑器排版好的 Label, 直接作为父物体了
private showText() {
    let font = 'ResourceHanRoundedCN-Bold';
    let size = this.lab_content.fontSize;
    let str = `F:${font}&S:${size}&C:#648ABE&T:花费` + '||' +
        `F:${font}&S:${size}&C:#FC335A&E:coin&T:500金币` + '||' +
        `F:${font}&S:${size}&C:#648ABE&T:可获得` + '||' +            
        `F:${font}&S:${size}&C:#FC335A&E:times&T:1000次`;
    let htmlDivEle = RichTextMaker.parse(str);        
    htmlDivEle.style.width = this.lab_content.width;
    htmlDivEle.style.height = this.lab_content.height;
    htmlDivEle.style.wordWrap = true;
    htmlDivEle.style.leading = 26;
    htmlDivEle.style.align = 'center';
    htmlDivEle.style.valign = 'middle';     
    if(htmlDivEle['_element']) {
        // align: center
        htmlDivEle.x = (this.lab_content.width - htmlDivEle['_element'].contextWidth) / 2;
        // valign: middle
        htmlDivEle.y = (this.lab_content.height - htmlDivEle['_element'].contextHeight) / 2;
    }
    htmlDivEle.on(Laya.Event.LINK, this, (e) => {
        switch (e) {
            case 'coin':
                console.log('点击了金币');
                break;
            case 'times':
                console.log('点击了次数');
                break;
        }
    })
    this.lab_content.removeChildren();
    this.lab_content.addChild(htmlDivEle);
}

export class RichTextMaker {

    /** 颜色 */
    private static COLOR: string = "C";
    /** 字体大小 */
    private static SIZE: string = "S";
    /** 使用的字体 */
    private static FAMILY: string = "F";    
    private static UNDERLINE: string = "U";         // 设置未生效    
    private static WEIGHT: string = "W";
    private static STYLE: string = "S";
    private static TEXT_DECORATION: string = "D";   // 设置未生效
    private static EVENT: string = "E";             // 自带下划线

    /** 解析
    	|| 分割成一个个模块
		单个模块样式: [样式1&样式2]&T:[文本内容]
    	例:
    		`F:${font}&S:${size}&C:#648ABE&T:花费||F:${font}&S:${size}&C:#648ABE&T:100`
	*/
    public static parse(str: string): Laya.HTMLDivElement {
        let divElement = new Laya.HTMLDivElement();
        divElement.innerHTML = this.generate(str);
        this.checkLinkEvent(divElement, str);
        return divElement;
    }

    /** 生成 */
    private static generate(sourceText: string): string {
        let result = '';
        let textArr = sourceText.split("||");
        for (let i = 0, len = textArr.length; i < len; i++) {
            result += this.handleSingleStr(textArr[i]);
        }
        return result;
    }

    private static handleSingleStr(text: string): string {
        let arrText = text.split("&T:", 2);
        if (arrText.length == 2) {
            let str: string = '<span style="';
            let textArr = arrText[0].split("&");
            let tempArr: string[];
            for (let i = 0, len = textArr.length; i < len; i++) {
                tempArr = textArr[i].split(":");
                switch (tempArr[0]) {
                    case this.COLOR:
                        str += `color:${tempArr[1]};`;
                        break;
                    case this.SIZE:
                        str += `font-size:${tempArr[1]};`;
                        break;
                    case this.FAMILY:
                        str += `font-family:${tempArr[1]};`;
                        break;
                    case this.UNDERLINE:
                        str += 'text-decoration:underline;';
                        break;
                    case this.WEIGHT:
                        str += `font-weight:${tempArr[1]};`;
                        break;
                    case this.STYLE:
                        str += `font-style:${tempArr[1]};`;
                        break;
                    case this.TEXT_DECORATION:
                        str += `text-decoration:${tempArr[1]};`;
                        break;
                }
            }
            str += `">${arrText[1]}</span>`;
            return str;
        } else {
            return '<span>' + text + '</span>';
        }
    }

    /** 检测是否有点击事件 */
    private static checkLinkEvent(divElement: Laya.HTMLDivElement, sourceText: string) {
        let childrenElements: Laya.HTMLElement[];
        if (divElement && divElement['_element'] && divElement['_element']['_children']) {
            childrenElements = divElement['_element']['_children'];
        } else {
            console.error('divElement 没有children');
            return;
        }
        let textArr = sourceText.split("||");
        for (let i = 0, len = textArr.length; i < len; i++) {
            let text = textArr[i];
            let arrText = text.split("&T:", 2);
            if (arrText.length == 2) {
                let textArr = arrText[0].split("&");
                let tempArr: string[];
                for (let i = 0, len = textArr.length; i < len; i++) {
                    tempArr = textArr[i].split(":");
                    switch (tempArr[0]) {
                        case this.EVENT:
                            for (let j = 0; j < childrenElements.length; j++) {
                                if (childrenElements[j].innerTEXT == arrText[1]) {
                                    childrenElements[j].href = tempArr[1];
                                    break;
                                }
                            }
                            break;
                    }
                }
            }
        }
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值