【cocos creator】【TS】Label,RichText一键互相转换


/**https://blog.csdn.net/K86338236/article/details/131699371
 * 将Label,RichText互相转换,使用方法:挂载到需要转换的节点上,如果有子节点,会遍历子节点进行转换
*/
const { ccclass, property, menu } = cc._decorator;

@ccclass
@menu("扩展/Label_RichText_Change")
export default class Label_RichText_Change extends cc.Component {

    //第一次挂载到节点上运行
    resetInEditor() {
        this.FontChange();
    }

    /**
     * 遍历子节点执行函数
     * @param parent 父节点
     * @param callBack 回调函数,传入遍历的节点,是否是最后一个节点
     */
    forEachNode(parent, callBack) {
        parent = parent || cc.director.getScene().parent;
        let list = [];
        list.push(parent)
        while (list.length > 0) {
            let node = list.shift();
            for (let i = 0; node.children && i < node.childrenCount; i++) {
                list.push(node.children[i]);
            }
            delete list[node];
            callBack(node, list.length == 0);
        }
    }

    /**
     * 遍历子节点修改
     */
    FontChange() {
        this.forEachNode(this.node, (node, isLast) => {
            this.changeFont(node, isLast, () => {
                this.node.removeComponent(this);
            });
        });
    }

    /**
     * 修改字体
     * @param node 要修改的节点
     * @param isLast 是否是最后一个节点
     * @param callBack 最后一个节点执行的回调函数
     * @returns 
     */
    changeFont(node: cc.Node, isLast: boolean = false, callBack?) {
        if (node.getComponent(cc.Label)) {
            this.changeToRichText(node);
            if (isLast && callBack) callBack();
            return;
        }
        if (node.getComponent(cc.RichText)) {
            this.changeToLabel(node);
            if (isLast && callBack) callBack();
            return;
        }
    }

    /**将富文本转为label */
    changeToLabel(node: cc.Node) {
        let _richText: cc.RichText = node.getComponent(cc.RichText);
        if (!_richText) {
            Editor.log("挂载节点无RichText脚本")
            return
        }
        let fontSize = _richText.fontSize;
        let lineHeight = _richText.lineHeight;
        let align = cc.Label.HorizontalAlign.LEFT;
        let font = _richText.font;
        let str = _richText.string;
        let anchorX = _richText.node.anchorX;
        let anchorY = _richText.node.anchorY;

        if (_richText.horizontalAlign == cc.macro.TextAlignment.LEFT) {
            align = cc.Label.HorizontalAlign.LEFT;
        }
        else if (_richText.horizontalAlign == cc.macro.TextAlignment.CENTER) {
            align = cc.Label.HorizontalAlign.CENTER;
        }
        else if (_richText.horizontalAlign == cc.macro.TextAlignment.RIGHT) {
            align = cc.Label.HorizontalAlign.RIGHT;
        }

        node.removeComponent(cc.RichText);
        _richText = null;
        node.addComponent(cc.Label);

        let _label = node.getComponent(cc.Label);
        _label.string = this.formatString(str);
        _label.fontSize = fontSize;
        _label.lineHeight = lineHeight;
        _label.horizontalAlign = align;
        _label.font = font;
        _label.node.anchorX = anchorX;
        _label.node.anchorY = anchorY;
        _label.verticalAlign = cc.Label.VerticalAlign.CENTER;

        //外描边
        if (str && str[0] == "<" && str[str.length - 1] == ">" && str.indexOf("</outline>") != -1 && str.split("</outline>").length == 2) {
            let string = str.split("</outline>")[0].split(">")[1];
            _label.string = this.formatString(string);
            let width: any = "", color = "", widthStatus = 0, colorStatus = 0;
            for (let i = 0; i < str.length; i++) {
                const element = str[i];
                if (!widthStatus && element == "h") {
                    widthStatus = 1
                }
                else if ((element == " " || element == ">") && widthStatus == 1 && width) {
                    width = Number(width)
                    widthStatus = 2;
                }
                else if (widthStatus == 1 && element != "=") {
                    width += element
                    Editor.log(width, element == " ", element == ">", widthStatus)
                }

                if (!colorStatus && element == "r") {
                    colorStatus = 1
                }
                else if ((element == " " || element == ">") && colorStatus == 1 && color) {
                    Editor.log(color)
                    colorStatus = 2;
                }
                else if (colorStatus == 1 && element != "=") {
                    color += element
                }
            }
            if (!color) return;
            let _LabelOutline = node.addComponent(cc.LabelOutline);
            _LabelOutline.color = new cc.Color().fromHEX(color)
            _LabelOutline.width = width || 2;
        }
    }
    /**changeToRichText */
    changeToRichText(node: cc.Node) {
        let _text: cc.Label = node.getComponent(cc.Label);
        if (!_text) {
            Editor.log("挂载节点无Label脚本")
            return
        }
        let fontSize = _text.fontSize;
        let lineHeight = _text.lineHeight;
        let align = cc.macro.TextAlignment.CENTER;
        let font = _text.font;
        let str = _text.string;
        let anchorX = _text.node.anchorX;
        let anchorY = _text.node.anchorY;

        if (_text.horizontalAlign == cc.Label.HorizontalAlign.LEFT) {
            align = cc.macro.TextAlignment.LEFT;
        }
        else if (_text.horizontalAlign == cc.Label.HorizontalAlign.CENTER) {
            align = cc.macro.TextAlignment.CENTER;
        }
        else if (_text.horizontalAlign == cc.Label.HorizontalAlign.RIGHT) {
            align = cc.macro.TextAlignment.RIGHT;
        }

        let _outLine: cc.LabelOutline = node.getComponent(cc.LabelOutline);
        let outLineData = {}
        if (_outLine) {
            outLineData["color"] = "#" + _outLine.color.toHEX();
            outLineData["width"] = _outLine.width;
            node.removeComponent(cc.LabelOutline);
        }
        if (node.getComponent(cc.LabelShadow)) node.removeComponent(cc.LabelShadow);

        node.removeComponent(cc.Label);
        _text = null;
        node.addComponent(cc.RichText);
        let _RichText = node.getComponent(cc.RichText);
        _RichText.fontSize = fontSize;
        _RichText.font = font;
        _RichText.horizontalAlign = align;
        _RichText.lineHeight = lineHeight;
        _RichText.handleTouchEvent = false;
        _RichText.node.anchorX = anchorX;
        _RichText.node.anchorY = anchorY;
        _RichText.string = this.formatString(str);
        if (_outLine) {
            _RichText.string = this.formatString(`<outline color=${outLineData["color"]} width=${outLineData["width"]}>${str}</outline>`);
            node.removeComponent(cc.LabelOutline);
        }
    }
    /** 
     * 编辑器里加载资源
     * @param {*} url 路径,编辑器assets下的目录结构,带后缀名
     * @param {*} callback 回调
     */
    loadRes(url, callback) {
        //@ts-ignore
        let uuid = Editor.assetdb.remote.urlToUuid("db://assets/" + url);
        if (uuid) {
            //@ts-ignore
            cc.AssetLibrary.loadAsset(uuid, function (err, asset) {
                if (!err) {
                    if (callback) callback(asset);
                } else {
                    cc.error(err);
                }
            });
        } else {
            cc.error(url + " not found");
        }
    }

    /**去掉RichText加粗*/
    formatString(str) {
        str = str.replace("<b>", "");
        str = str.replace("</b>", "");
        return str;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

烧仙草奶茶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值