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();