Egret圖文混排組件

/**
     * 圖文混排組件
     */
    class TextImage extends eui.Group {
        public templet: egret.TextField
        constructor(protected _TextImageData: Array<any> = []) {
            super();
            this.init()
        }
        set TextImageData(val: Array<any>) { this._TextImageData = val; this.init(); }
        get TextImageData() { return this._TextImageData }
        _size = 36
        /**設置文字字體大小 */
        set size(val: number) {
            this._size = val
        }
        get size(): number {
            return this._size
        }
        private _width: number;
        /**設置寬度 */
        set width(val) { this._width = val; this.invalidate(); }
        get width() { return this._width };


        private _verticalAlign = egret.VerticalAlign.MIDDLE;
        /**設置vercatical */
        set verticalAlign(val) { this._verticalAlign = val; this.invalidate(); }
        get verticalAlign() { return this._verticalAlign };

        _maxWidth: number
        /**設置組件的最大寬度 */
        set maxWidth(val: number) {
            this._maxWidth = val
            if (this.templet.width > val) {
                this.width = val
                this.invalidate()
            }
        }
        get maxWidth(): number {
            return this._maxWidth
        }
        private _lineSpacing = 0
        /**設置組件的行間距 */
        set lineSpacing(val: number) {
            if (this._lineSpacing === val) return
            this._lineSpacing = val
            this.invalidate()
        }
        get lineSpacing(): number {
            return this._lineSpacing
        }
        /**立即計算佈局 */
        validateNow() {
            this.init()
            this.invalidate_Flag = false
        }
        /**組件的每行高度 */
        lineHeightArray: Array<number> = []
        components: any[] = []
        protected init() {
            this.removeChildren()
            if (this._TextImageData.length == 0) {
                this.width = this.height = 0
                return
            }
            // 保存組件,清除事件綁定
            this.components = []
            this._TextImageData.forEach(component => {
                if (typeof component == 'object') {
                    this.components.push(component)
                    if (!component['watch']) {
                        egret.is(component, 'eui.Image') && component.once(egret.Event.COMPLETE, this.invalidate, this)
                        eui.Watcher.watch(component, ['width'], this.invalidate, this)
                        eui.Watcher.watch(component, ['height'], this.invalidate, this)
                        component['watch'] = true
                    }
                }
            })
            let textFlow = this._TextImageData.map(text =>
                typeof text === "string" || egret.is(text, 'eui.Label')
                    ? { text: egret.is(text, 'eui.Label') ? text.text : text }
                    : { text: '樂', style: { size: text.width } }
            )
            let TextField: egret.TextField = this.templet = new egret.TextField();
            TextField.size = this.size;
            TextField.lineSpacing = 0;
            TextField.width = this.width
            TextField.textFlow = textFlow
            TextField.height = TextField.height

            this.height = 0
            this.lineHeightArray = []

            let componentTestIndex = 0 //測量高度的組件序號
            let componentIndex = 0 //佈局的組件序號
            TextField['linesArr'].forEach((item,lines) => {
                console.log('item=>', item)
                //獲取最大高度
                let maxheight = this.size
                //組件序號
                item.elements.forEach((element) => {
                    if (element.text == '樂') {
                        let c = this.components[componentTestIndex++]
                        maxheight = Math.max(maxheight, c.height)
                    }
                })
                maxheight = this._lineSpacing + maxheight
                this.lineHeightArray.push(maxheight)

                //開始佈局
                let x = 0
                item.elements.forEach(element => {
                    let component
                    if (element.text !== '樂') {
                        component = new egret.TextField()
                        component.x = x
                        component.size = this.size
                        component.text = element.text
                        component.width = element.width
                        component.textColor = this._textColor
                        component.height = maxheight
                        component.y = this.height
                        component.verticalAlign = this._verticalAlign;
                    } else {
                        component = this.components[componentIndex++]
                        component.x = x
                        component.y = this.height + (maxheight - component.height) / 2
                    }
                    x += component.width
                    this.addChild(component)
                })
                this.height += maxheight
            })
            this._width = this.templet.width

        }
        _textColor: number = 0x000000
        set textColor(val) {
            this._textColor = val
            this.invalidate()
        }
        get textColor() {
            return this._textColor
        }



        /**失效驗證 */
        private invalidate_Flag: boolean = false
        private invalidate(e?: egret.Event): void {
            if (this.invalidate_Flag) {
                return
            }
            this.invalidate_Flag = true
            this.once(egret.Event.ENTER_FRAME, () => {
                this.init()
                this.invalidate_Flag = false
            }, this);
        }
    }

使用方式

function create(width=60,height=40):eui.Rect{
            let bg = new eui.Rect()
            bg.width = width
            bg.height = width
            bg.alpha = 0.6
            return bg
        }
let textData = [馬克思主義是馬克思,create(),主克,create(),思主義理論體系包,create(),含兩個組]
let textImage  = new TextImage(textData )
this.addChild(textImage) 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章