Skip to content

UIImageGroup

UIImageGroup 组件提供多图片的显示,该组件允许你在一个组件下,同时控制多个 Quad 渲染。相较于 UIImage 组件,其主要区别如下:

  1. UIImageGroup 多个 Quad 绑定在一个 Object3D 对象,在批量渲染同类型 Sprite 类型时,UIImageGroup 可以获得更加高效的渲染性能;
  2. UIImageGroup 中每个 Quad 使用自身的尺寸数据,节点所对应的UITransform 的缩放不会对每个 Quad 产生影响;
  3. UIImageGroup 需要指定下标 index 才能找到对应的 Quad 对象,设置 Quad 属性需要通过调用对应的 set API 进行设置。

初始化图片组:

ts
...
// 创建图片组节点
let groupObj = new Object3D();
panelRoot.addChild(groupObj);

// ImageGroup 组件需要设置内置多少个 Quad,默认为 1 个 Quad 节点
this.imageGroup = groupObj.addComponent(UIImageGroup, (count: 2));

设置贴图

和单个 UIImage一样,我们首先需要通过 Engine3D.res.loadAtlas 来加载精灵图集,然后通过 setSprite 赋予图片组中指定 indexquad 贴图内容:

ts
// 加载 Atlas 图集素材
await Engine3D.res.loadAtlas('atlas/UI_atlas.json');
// 设置 0 位精灵贴图 
imageGroup.setSprite(0, Engine3D.res.getGUISprite('logo'));

修改图片颜色

同样,通过 setColor 更改对应 indexquad 颜色,如果组件有设置贴图,会乘法叠加贴图像素颜色:

ts
imageGroup.setColor(0, new Color(1.0, 0.0, 0.0, 1.0));

修改图片大小

通过 setSize 更改对应 indexquad 大小:

ts
imageGroup.setSize(0, 100, 100);

组件 visible(可见/隐藏)

图片组中,可以设置 visible 属性统一修改所有 quad 显示或隐藏:

ts
imageGroup.visible = false;//or true

销毁图片组

ts
imageGroup.destroy();

修改指定下标精灵的拉伸/平铺类型

精灵图类型:参考 ImageType,设置精灵的渲染类型;

  • Simple:默认类型,精灵图被拉伸平铺到指定区域
  • Sliced:按照九宫格的方式进行拉伸渲染
  • Tiled:未支持
  • Filled:未支持
ts
imageGroup.setImageType(0, ImageType.Simple);

下面示例展示如何在 UIImageGroup 中设置单个 Quad 的位置和大小:

WebGPU is not supported in your browser
Please upgrade to latest Chrome/Edge

<
ts
import { AtmosphericComponent, BitmapTexture2D, Camera3D, Engine3D, HoverCameraController, Object3D, Scene3D, Texture, UIImageGroup, View3D, ViewPanel, makeAloneSprite } from '@orillusion/core'
import * as dat from 'dat.gui'

class Sample_UIImageGroup {
    scene: Scene3D
    imageGroup: UIImageGroup

    async run() {
        Engine3D.setting.shadow.autoUpdate = true
        // initializa engine
        await Engine3D.init()
        // create new scene as root node
        let scene3D: Scene3D = new Scene3D()
        scene3D.addComponent(AtmosphericComponent)
        // create camera
        let cameraObj: Object3D = new Object3D()
        let camera = cameraObj.addComponent(Camera3D)
        // adjust camera view
        camera.perspective(60, Engine3D.aspect, 1, 5000.0)
        // set camera controller
        let controller = cameraObj.addComponent(HoverCameraController)
        controller.setCamera(0, -20, 30)
        // add camera node
        scene3D.addChild(cameraObj)

        let view = new View3D()
        view.scene = scene3D
        view.camera = camera
        Engine3D.startRenderView(view)

        this.scene = scene3D

        await this.createImageGroup()
    }

    async createImageGroup() {
        // enable ui canvas
        let canvas = this.scene.view.enableUICanvas()
        //create UI root
        let panelRoot: Object3D = new Object3D()
        //create panel
        let panel = panelRoot.addComponent(ViewPanel)
        canvas.addChild(panel.object3D)

        let bitmapTexture2D = new BitmapTexture2D()
        bitmapTexture2D.flipY = true
        await bitmapTexture2D.load('https://cdn.orillusion.com/images/webgpu.png')

        let uiNode = new Object3D()
        panelRoot.addChild(uiNode)
        //create sprite sheet list
        this.imageGroup = this.createSpriteSheets(uiNode, bitmapTexture2D)
        this.createGUI()
    }

    private halfSize = 0
    createGUI() {
        let GUIHelp = new dat.GUI()
        let quat = this.imageGroup.getQuad(1)
        let f = GUIHelp.addFolder('Position')
        let pos = { x: quat.x, y: quat.y }
        let action = () => this.imageGroup.setXY(1, pos.x, pos.y)
        f.add(pos, 'x', -Engine3D.width/2, Engine3D.width/2, 1).onChange(action)
        f.add(pos, 'y', -Engine3D.height/2, Engine3D.height/2, 1).onChange(action)
        f.open()

        f = GUIHelp.addFolder('Size')
        let size = { width: quat.width, height: quat.height }
        let action2 = () => this.imageGroup.setSize(1, size.width, size.height)
        f.add(size, 'width', 0, 256, 1).onChange(action2)
        f.add(size, 'height', 0, 256, 1).onChange(action2)
        f.open()
    }

    private createSpriteSheets(root: Object3D, texture: Texture): UIImageGroup {
        let sprite = makeAloneSprite('logo', texture)
        let imgGroup = root.addComponent(UIImageGroup, { count: 2 })
        let size = 128
        this.halfSize = size * 0.5
        for (let i = 0; i < 2; i++) {
            imgGroup.setSprite(i, sprite)
            imgGroup.setSize(i, size, size)
            if (i == 1) {
                imgGroup.setXY(1, -this.halfSize, this.halfSize)
            } else {
                imgGroup.setXY(0, -this.halfSize, -this.halfSize)
            }
        }
        return imgGroup
    }
}

new Sample_UIImageGroup().run()