feat: add ui doc

This commit is contained in:
azhan
2025-01-25 12:39:17 +08:00
parent 91e047b866
commit efed56f2e8
40 changed files with 980 additions and 207 deletions

11
docs/en/UI/_meta.json Normal file
View File

@@ -0,0 +1,11 @@
{
"overall": {
"title": "Overview"
},
"quickStart": {
"title": "QuickStart"
},
"system": {
"title": "Architecture"
}
}

26
docs/en/UI/overall.md Normal file
View File

@@ -0,0 +1,26 @@
---
order: 0
title: Overview
type: UI
label: UI
---
UI is a system used to build user interfaces. It provides a range of tools and components to help developers create interactive interface elements. Here are its key features:
- **Visual Editing**: With the basic nodes and component creation capabilities in the [editor](https://galacean.antgroup.com/editor/projects), combined with the RectTool (shortcut key T), developing interactive interfaces becomes more intuitive and efficient.
- **Rendering and Interactive Components**: Supports rendering components like Image, Text, etc., as well as basic interactive components such as Button.
- **Transferable Opacity and Interactivity Attributes**: Through the UIGroup component, properties such as **opacity** and **interactivity** can be inherited or ignored.
- **Events**: In addition to supporting original Pointer events, UI components also support **event bubbling** for interactions triggered by the UI.
In this section, you will:
- Learn how to quickly develop a UI interface:
- Create a [Root Canvas](/en/docs/UI/quickStart/canvas)
- Familiarize yourself with [UITransform](/en/docs/UI/quickStart/transform)
- Create [Image](/en/docs/UI/quickStart/image)
- Create [Text](/en/docs/UI/quickStart/text)
- Create [Button](/en/docs/UI/quickStart/button)
- Create [UIGroup](/en/docs/UI/quickStart/group)
- Understand the [Overall Architecture and Module Management](/en/docs/UI/system) of UI
- Learn about [UI Rendering Order](/en/docs/UI/quickStart/order)
- Understand the [UI Event Mechanism](/en/docs/UI/quickStart/event)

View File

@@ -0,0 +1,44 @@
---
order: 4
title: Button
type: UI
label: UI
---
`Button` can be used to create interactive buttons within a UICanvas.
## Editor Usage
### Add Button Node
Add a `Button` node in the **[Hierarchy Panel](/docs/interface/hierarchy/)**.
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*Zjn4QbY0B-IAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
> If the parent or ancestor node does not have a Canvas component, a root Canvas node will be automatically added.
### Set Transition
In the editor, you can easily set the button's transition effects for different states.
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*IFiaSLZqIWYAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
## Properties
| Property Name | Description |
| :-------------- | :-------------------------------- |
| `transitions` | All the transition effects of the button |
| `interactive` | Whether the button is interactive |
## Methods
| Method Name | Description |
| :------------------ | :------------------------------------ |
| `addTransition` | Add a transition effect to the button |
| `removeTransition` | Remove a transition effect from the button |
| `addClicked` | Add a click callback function |
| `removeClicked` | Remove a click callback function |
## Script Development
<playground src="ui-Button.ts"></playground>

View File

@@ -0,0 +1,62 @@
---
order: 0
title: Canvas
type: UI
label: UI
---
The root canvas is the foundation of the UI, but not all `UICanvas` nodes are root canvases. Heres how to create a root canvas in your scene.
## Editor Usage
### Add UICanvas Node
Add a Canvas node in the **[Hierarchy Panel](/docs/interface/hierarchy/)**.
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*ZFO6Q7P7NwQAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
### Set Properties
Select the node that has the `Canvas` component and you can set its properties in the **[Inspector Panel](/docs/interface/inspector)**.
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*4nbARKclT8sAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
### Root Canvas
If the parent or ancestor node of the newly added canvas node already contains an active `UICanvas` component, this canvas will not have rendering or interaction functionality.
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*9CxZQ5t6GVEAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
## Properties
| Property Name | Description |
| :------------------------------ | :------------------------------------------------------------ |
| `renderMode` | The rendering mode of the canvas |
| `renderCamera` | The camera used for rendering when the canvas is in `ScreenSpaceCamera` mode |
| `distance` | The distance of the canvas relative to the camera when in `ScreenSpaceCamera` mode |
| `resolutionAdaptationMode` | The adaptation mode of the canvas, such as width adaptation or height adaptation |
| `referenceResolution` | The reference resolution for size adaptation of the canvas |
| `referenceResolutionPerUnit` | The ratio of canvas units to world space units |
| `sortOrder` | The rendering priority of the canvas |
## Script Development
```typescript
// Add camera
const cameraEntity = root.createChild("Camera");
const camera = cameraEntity.addComponent(Camera);
// Add UICanvas
const canvasEntity = root.createChild("canvas");
const canvas = canvasEntity.addComponent(UICanvas);
// Set renderMode to `ScreenSpaceOverlay`
canvas.renderMode = CanvasRenderMode.ScreenSpaceOverlay;
// Set renderMode to `ScreenSpaceCamera`
canvas.renderMode = CanvasRenderMode.ScreenSpaceCamera;
canvas.renderCamera = camera;
// Set Reference Resolution
canvas.referenceResolution.set(750, 1624);
// Set Adaptation Mode
canvas.resolutionAdaptationMode = ResolutionAdaptationMode.WidthAdaptation;
```

View File

@@ -0,0 +1,40 @@
---
order: 3
title: Event
type: UI
label: UI
---
UI events follow the engine's event system, with the additional support for event bubbling in UI components.
## Bubbling
The current version only supports the following bubbling flow:
| Interface | Bubbles |
| :----------------------------------------------------------- | :--------- |
| [onPointerEnter](/apis/core/#Script-onPointerEnter) | Does not bubble |
| [onPointerExit](/apis/core/#Script-onPointerExit) | Does not bubble |
| [onPointerDown](/apis/core/#Script-onPointerDown) | Bubbles |
| [onPointerUp](/apis/core/#Script-onPointerUp) | Bubbles |
| [onPointerClick](/apis/core/#Script-onPointerClick) | Bubbles |
| [onPointerBeginDrag](/apis/core/#Script-onPointerBeginDrag) | Bubbles |
| [onPointerDrag](/apis/core/#Script-onPointerDrag) | Bubbles |
| [onPointerEndDrag](/apis/core/#Script-onPointerEndDrag) | Bubbles |
| [onPointerDrop](/apis/core/#Script-onPointerDrop) | Bubbles |
As shown in the diagram below, if node C triggers the `pointerup` event, the event will bubble along the path C --> B --> A --> RootCanvas.
```mermaid
stateDiagram
RootCanvas --> A
RootCanvas --> F
A --> B
A --> E
B --> C
B --> D
```
## Script Development
<playground src="ui-Event.ts"></playground>

View File

@@ -0,0 +1,28 @@
---
order: 5
title: UIGroup
type: UI
label: UI
---
The `UIGroup` component allows you to inherit or ignore properties such as **opacity** and **interactivity**.
## Editor Usage
Select the node, then in the **[Inspector Panel](/docs/interface/inspector)**, click **Add Component** and choose **UIGroup**. You can control the opacity of multiple UI elements by modifying the settings.
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*PWGYRb7MJs4AAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
## Properties
| Property Name | Description |
| :------------------ | :--------------------------------- |
| `alpha` | Opacity |
| `interactive` | Whether the element is interactive |
| `ignoreParentGroup` | Whether to ignore the settings of the parent group |
> UIGroup resolves the issue where UI element properties cannot be passed from parent to child.
## Script Development
<playground src="xr-ar-simple.ts"></playground>

View File

@@ -0,0 +1,48 @@
---
order: 2
title: Image
type: UI
label: UI
---
The `Image` component is used to display images within a `UICanvas`.
## Editor Usage
### Add Image Node
Add an `Image` node in the **[Hierarchy Panel](/docs/interface/hierarchy/)**.
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*9SCNTZNglo0AAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
> If the parent or ancestor node does not have a Canvas component, a root canvas node will be automatically added.
### Set Sprite
The content displayed by the `Image` depends on the selected [Sprite asset](). Select the node with the `Image` component, and in the **[Inspector Panel](/docs/interface/inspector)**, choose the corresponding sprite asset in the Sprite property to change the displayed content.
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*aztPTKxnkHEAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
### Modify Draw Mode
The `Image` component currently provides three draw modes: Normal, Nine-Patch, and Tiled (the default is Normal). You can visually feel the rendering differences between modes by modifying the width and height in each mode.
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*z6iPRb0U9FUAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
### Adjust Size
For adjusting the size of UI elements, refer to [Quickly Adjust UI Element Size](/docs/UI/quickStart/transform).
## Properties
| Property Name | Description |
| :----------------- | :-------------------------------------------------- |
| `sprite` | The sprite to render |
| `color` | The color of the sprite |
| `drawMode` | The draw mode, supports Normal, Nine-Patch, and Tiled modes |
| `raycastEnabled` | Whether the image can be detected by raycasting |
| `raycastPadding` | Custom padding for raycasting, representing the distance from the edges of the collision area. This is a normalized value, where X, Y, Z, and W represent the distances from the left, bottom, right, and top edges respectively. |
## Script Development
<playground src="ui-Image.ts"></playground>

View File

@@ -0,0 +1,61 @@
---
order: 6
title: Rendering Order
type: UI
label: UI
---
The rendering order of UI components follows two rules:
- Different `UICanvas` instances follow a specific rendering order based on their `RendererMode` type.
- `UIRenderer` components under a `UICanvas` are rendered according to a **depth-first** order, from parent to child, and from left to right.
## UICanvas
Assume the current runtime:
- There is a scene `Scene`
- The scene `Scene` contains two cameras, `Camera1` and `Camera2`
- The scene `Scene` contains three canvases:
- `Canvas1` with `WorldSpace` render mode
- `Canvas2` with `ScreenSpace-Overlay` render mode
- `Canvas3` with `ScreenSpace-Camera` render mode, using `Camera1` as the render camera
```mermaid
journey
title Scene Rendering Cycle
section Camera1.render
Canvas1.render: 5
Canvas3.render: 5
section Camera2.render
Canvas1.render: 5
section Ending
Canvas2.render: 5
```
It's important to note:
- Canvases with `ScreenSpace-Camera` render mode will only render with their corresponding camera, and they follow the general camera clipping rules, just like canvases with `ScreenSpace-Overlay` render mode.
- Canvases with `ScreenSpace-Overlay` render mode can still be rendered without a camera.
- Within the same camera, the rendering order of `UICanvas` follows these rules: canvases in the overlay mode have their rendering order determined only by `sortOrder`.
```mermaid
flowchart TD
A[Sort rendering data] --> B{canvas.sortOrder}
B -->|Not equal| C[Return comparison result]
B -->|Equal| D{Canvas and camera distance}
D -->|Not equal| E[Return comparison result]
D -->|Equal| F[Return comparison result]
```
## UIRenderer Rendering Order
```mermaid
stateDiagram
RootCanvas --> A
RootCanvas --> F
A --> B
A --> E
B --> C
B --> D
```
As shown in the diagram above, the rendering order under the root canvas follows A -> B -> C -> D -> E -> F. It is important to note that setting `UIRenderer.priority` does not change its rendering order.

View File

@@ -0,0 +1,60 @@
---
order: 3
title: Text
type: UI
label: UI
---
The `Text` component is used to display text within a `UICanvas`.
## Editor Usage
### Add Text Node
Add a `Text` node in the **[Hierarchy Panel](/docs/interface/hierarchy/)**.
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*yklkSI-wIq0AAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
> If the parent or ancestor node does not have a Canvas component, a root canvas node will be automatically added.
### Set Text Content
Select the node with the `Text` component, and in the **[Inspector Panel](/docs/interface/inspector)**, modify the `text` property to change the content of the `Text` element.
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*j46eSYWAfVYAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
### Set Font
Select the node with the `Text` component, and in the **[Inspector Panel](/docs/interface/inspector)**, modify the `font` property to change the font type of the `Text` element.
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*vR-rR7eGHZkAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
### Modify Font Size
The `Text` component can modify the rendering size by adjusting the `FontSize`.
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*DcrDR6Y_fKAAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
> Changing the `size` in `UITransform` will not affect the rendering size of `Text`.
## Properties
| Property Name | Description |
| :------------------ | :------------------------------------------------------------------------------------------------ |
| `Text` | The text to be displayed |
| `Color` | The color of the text |
| `FontSize` | The font size of the text |
| `Font` | Custom font for the text |
| `LineSpacing` | The line spacing between text lines |
| `FontStyle` | Font style settings: whether to apply bold or italic styles |
| `HorizontalAlignment` | Horizontal alignment of the text, with options: Left/Center/Right |
| `VerticalAlignment` | Vertical alignment of the text, with options: Top/Center/Bottom |
| `EnableWrapping` | Whether to enable word wrapping; when enabled, text will wrap based on the set width. If width is set to 0, the text will not render |
| `OverflowMode` | How to handle overflow when the text exceeds the set height: options are Overflow/Truncate. Overflow means the text will overflow and display; Truncate means only the content within the set height will be displayed, depending on the vertical alignment of the text. |
| `Mask Interaction` | Mask type for text, specifying whether the text needs masking, and whether the content inside or outside the mask should be shown |
| `Mask Layer` | The mask layer for the text, used for matching with SpriteMask. Default is Everything, meaning it can interact with any SpriteMask |
| `priority` | Rendering priority; the lower the value, the higher the priority, meaning it will be rendered first |
## Script Development
<playground src="ui-Text.ts"></playground>

View File

@@ -0,0 +1,34 @@
---
order: 1
title: UITransform
type: UI
label: UI
---
The `UITransform` component is specifically designed to represent the size and position of UI elements. It inherits from the [Transform](/apis/core/#Transform) component.
## Editor Usage
When a node with a UI component is added, the `UITransform` component will automatically be added (replacing the previous [Transform](/apis/core/#Transform) component). In the editor, you can select the node and use the `RectTool` (shortcut key `T`) to quickly adjust properties, or you can set precise properties in the **[Inspector Panel](/docs/interface/inspector)**.
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*hJ81TKtDKLIAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
> When the main canvas's render mode is `Screen`, the editor will prohibit modifications to its `transform` to avoid screen adaptation issues. Therefore, in scripts, **developers should avoid modifying the `transform` properties of the main canvas in screen space.**
## Properties
| Property Name | Description |
| :------------ | :--------------------------------------------------------------------------- |
| `size` | The size of the UI element. `x` represents width, and `y` represents height. The default is `100` for both. |
| `pivot` | The anchor point of the UI element. It is a normalized 2D vector with the origin at the bottom-left corner, with the default value being the center (0.5, 0.5). |
## Script Usage
```typescript
// Add UICanvas
const canvasEntity = root.createChild("canvas");
const canvas = canvasEntity.addComponent(UICanvas);
const imageEntity = canvasEntity.create("Image");
(<UITransform>imageEntity.transform).size.set(200, 200);
(<UITransform>imageEntity.transform).pivot.set(0, 0);
```

108
docs/en/UI/system.md Normal file
View File

@@ -0,0 +1,108 @@
---
order: 2
title: Architecture
type: UI
label: UI
---
## System Design
```mermaid
---
title: UI System
---
classDiagram
Component <|-- Transform
Script <|-- Component
Transform <|-- UITransform
Component <|-- Renderer
Renderer <|-- UIRenderer
UIRenderer <|-- Image
UIRenderer <|-- Text
UICanvas <|-- Component
UIInteractive <|-- Script
Button <|-- UIInteractive
UIGroup <|-- Component
class Script {
+void onUpdate()
}
class Transform{
+Vector3 position
+Vector3 rotation
+Vector3 scale
...
}
class UITransform{
<<Added>>
+Vector2 size
+Vector2 pivot
}
class Renderer{
+BoundingBox bounds
+Material getMaterial()
+Material setMaterial()
}
class UIRenderer{
<<Added>>
+Color color
+boolean raycastEnabled
+vec4 raycastPadding
}
class Image{
<<Added>>
+Sprite sprite
+SpriteDrawMode drawMode
...
}
class Text{
<<Added>>
+string text
+Font font
...
}
class UICanvas {
<<Added>>
+CanvasRenderMode renderMode
+Camera renderCamera
...
}
class UIInteractive {
<<Added>>
+boolean interactive
+Transition transitions
...
}
class Button {
<<Added>>
+void addClicked()
+void removeClicked()
...
}
class UIGroup {
<<Added>>
+boolean interactive
+number alpha
+boolean ignoreParentGroup
}
```
## Module Management
| Package | Description | Related Documentation |
| :--------------------------------------------------------------------- | :------------- | ----------------------- |
| [@galacean/engine-ui](https://www.npmjs.com/package/@galacean/engine-xr) | Core architecture logic | [API](/apis/galacean) |
> `@galacean/engine-ui` is a dependency that must be included to implement **UI**.
> The [version dependency rules](/docs/basics/version/#version-dependency) must be followed, meaning the version of `@galacean/engine-ui` should match the version of `@galacean/engine`.

View File

@@ -47,6 +47,12 @@
"collapse": true
}
},
"UI": {
"title": "UI",
"theme": {
"collapse": true
}
},
"xr": {
"title": "XR",
"theme": {

View File

@@ -1,11 +1,11 @@
{
"overall": {
"title": "UI 总览"
"title": "总览"
},
"quickStart": {
"title": "快速上手"
},
"system": {
"title": "UI 架构"
"title": "架构"
}
}

View File

@@ -1,13 +1,13 @@
---
order: 0
title: UI 总览
title: 总览
type: UI
label: UI
---
UI 是用于构建用户界面的系统,它提供了一系列工具和组件方便开发者搭建交互界面元素。以下是它的主要能力:
- 可视化编辑:通过[编辑器]()中的基础节点与组件创建能力,搭配 RectTool 工具,让交互界面的开发更加直观高效。
- 可视化编辑:通过[编辑器](https://galacean.antgroup.com/editor/projects)中的基础节点与组件创建能力,搭配 `RectTool` (快捷键 `T` ,让交互界面的开发更加直观高效。
- 渲染与交互组件:支持 `Image``Text` 等渲染组件,以及基础的交互组件,如 `Button`
- 可传递的透明度与交互属性:通过 `UIGroup` 组件,可以继承或忽略**透明度****是否可交互**等属性
- 事件:在兼容原有的 Pointer 事件的基础上UI 组件触发的交互事件还支持**冒泡传递**。
@@ -15,11 +15,12 @@ UI 是用于构建用户界面的系统,它提供了一系列工具和组件
在本章节,您可以:
- 学会如何快速开发 UI 界面:
- 创建根画布
- 创建 Image
- 创建 Text
- 创建 Button
- 创建 UIGroup
- 了解 UI 的整体架构与模块管理
- 了解 UI 中的渲染顺序
- 了解 UI 中的事件
- 创建 [根画布](/docs/UI/quickStart/canvas)
- 熟悉 [UITransform](/docs/UI/quickStart/transform)
- 创建 [Image](/docs/UI/quickStart/image)
- 创建 [Text](/docs/UI/quickStart/text)
- 创建 [Button](/docs/UI/quickStart/button)
- 创建 [UIGroup](/docs/UI/quickStart/group)
- 了解 [UI 的整体架构与模块管理](/docs/UI/system)
- 了解 [UI 的渲染顺序](/docs/UI/quickStart/order)
- 了解 [UI 的事件机制](/docs/UI/quickStart/event)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 513 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 569 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 651 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 718 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 741 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 688 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 563 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 663 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 663 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 582 KiB

View File

@@ -1,33 +1,19 @@
---
order: 3
order: 4
title: 创建按钮
type: UI
label: UI
---
[Button](/apis/core/#SpriteRenderer) 可以在 UICanvas 中构建交互按钮。
`Button` 可以在 UICanvas 中构建交互按钮。
## 属性
| 属性名 | 属性类型 | 描述 |
| :----------------------------------------------------------- | :-------------------------------------------------------- | :------------------------------------------------------------------------------------------------ |
| [sprite](/apis/core/#SpriteRenderer-sprite) | [Sprite](/apis/core/#Sprite) | 使用精灵的引用 |
| [width](/apis/core/#SpriteRenderer-width) | Number | 精灵渲染器的宽,若开发者未自定义渲染器宽度,则默认为精灵宽度 |
| [height](/apis/core/#SpriteRenderer-height) | Number | 精灵渲染器的高,若开发者未自定义渲染器高度,则默认为精灵高度 |
| [color](/apis/core/#SpriteRenderer-color) | [Color](/apis/math/#Color) | 精灵颜色 |
| [flipX](/apis/core/#SpriteRenderer-flipX) | Boolean | 渲染时是否 X 轴翻转 |
| [flipY](/apis/core/#SpriteRenderer-flipY) | Boolean | 渲染时是否 Y 轴翻转 |
| [drawMode](/apis/core/#SpriteRenderer-drawMode) | [SpriteDrawMode](/apis/core/#SpriteDrawMode) | 绘制模式,支持普通,九宫和平铺绘制模式 |
| [maskInteraction](/apis/core/#SpriteRenderer-maskInteraction) | [SpriteMaskInteraction](/apis/core/#SpriteMaskInteraction) | 遮罩类型,用于设置精灵是否需要遮罩,以及需要遮罩的情况下,是显示遮罩内还是遮罩外的内容 |
| [maskLayer](/apis/core/#SpriteRenderer-maskLayer) | [SpriteMaskLayer](/apis/core/#SpriteMaskLayer) | 精灵所属遮罩层,用于和 SpriteMask 进行匹配,默认为 Everything表示可以和任何 SpriteMask 发生遮罩 |
## 编辑器
## 编辑器使用
### 添加 Button 节点
**[层级面板](/docs/interface/hierarchy/)** 添加 Button 节点
**[层级面板](/docs/interface/hierarchy/)** 添加 `Button` 节点
<img src="![alt text](<2025-01-24 18.02.39.gif>)" style="zoom:50%;" />
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*Zjn4QbY0B-IAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
> 若父亲或祖先节点没有画布组件,会自动添加上根画布节点。
@@ -35,8 +21,24 @@ label: UI
在编辑器中可以方便地设置按钮在不同状态下的过渡表现
<img src="![alt text](<2025-01-24 20.24.17.gif>)" style="zoom:50%;" />
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*IFiaSLZqIWYAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
## 属性
| 属性名 | 描述 |
| :------------ | :----------------- |
| `transitions` | 按钮的所有过渡表现 |
| `interactive` | 按钮是否可交互 |
## 方法
| 方法名 | 描述 |
| :----------------- | :------------------- |
| `addTransition` | 添加一个按钮过渡表现 |
| `removeTransition` | 移除某个按钮过渡表现 |
| `addClicked` | 添加一个点击回调函数 |
| `removeClicked` | 移除某个点击回调函数 |
## 脚本开发
<playground src="xr-ar-simple.ts"></playground>
<playground src="ui-Button.ts"></playground>

View File

@@ -1,12 +1,32 @@
---
order: 0
title: 创建根画布
type: XR
label: XR
type: UI
label: UI
---
根画布是 UI 的基础,但不是所有的 `UICanvas` 都是根画布,接下来为大家演示如何在场景中创建根画布。
## 编辑器使用
### 添加 UICanvas 节点
**[层级面板](/docs/interface/hierarchy/)** 添加 Canvas 节点
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*ZFO6Q7P7NwQAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
### 设置属性
选中添加了 `Canvas` 组件的节点,可以在 **[检查器面板](/docs/interface/inspector)** 设置相关的属性
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*4nbARKclT8sAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
### 根画布
如果新添加的画布节点的父亲或祖先节点已经包含激活的 `UICanvas` 组件,那么此画布不包含任何渲染与交互的功能。
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*9CxZQ5t6GVEAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
## 属性
| 属性名 | 描述 |
@@ -19,26 +39,6 @@ label: XR
| `referenceResolutionPerUnit` | 画布中的单位与世界空间中单位的比例关系 |
| `sortOrder` | 画布的渲染排序优先级 |
## 编辑器使用
### 添加 UICanvas 节点
**[层级面板](/docs/interface/hierarchy/)** 添加 Canvas 节点
<img src="![alt text](<2025-01-24 15.50.47.gif>)" style="zoom:50%;" />
### 设置属性
选中添加了 `Canvas` 组件的节点,可以在 **[检查器面板](/docs/interface/inspector)** 设置相关的属性
![alt text](<2025-01-24 23.01.32.gif>)
### 根画布
如果新添加的画布节点的父亲或祖先节点已经包含激活的 `UICanvas` 组件,那么此画布不包含任何渲染与交互的功能。
![alt text](<2025-01-24 23.03.11.gif>)
## 脚本开发
```typescript

View File

@@ -2,8 +2,7 @@
order: 3
title: 事件系统
type: UI
group: quickStart
label: UI/quickStart
label: UI
---
UI 事件遵循引擎的事件系统在此基础之上UI 组件派发的事件还额外支持冒泡机制。
@@ -12,17 +11,17 @@ UI 事件遵循引擎的事件系统在此基础之上UI 组件派发的
当前版本仅支持冒泡流程:
| 接口 | 是否冒泡率 |
| :------------------------------------------------- | :------------------------------------------------------------------------- |
| [onPointerEnter](/apis/core/#Script-onPointerEnter) | 不冒泡 |
| [onPointerExit](/apis/core/#Script-onPointerExit) | 不冒泡 |
| [onPointerDown](/apis/core/#Script-onPointerDown) | 冒泡 |
| [onPointerUp](/apis/core/#Script-onPointerUp) | 冒泡 |
| [onPointerClick](/apis/core/#Script-onPointerClick) | 冒泡 |
| [onPointerBeginDrag](/apis/core/#Script-onPointerBeginDrag) | 冒泡 |
| [onPointerDrag](/apis/core/#Script-onPointerDrag) | 冒泡 |
| [onPointerEndDrag](/apis/core/#Script-onPointerEndDrag) | 冒泡 |
| [onPointerDrop](/apis/core/#Script-onPointerDrop) | 冒泡 |
| 接口 | 是否冒泡率 |
| :---------------------------------------------------------- | :--------- |
| [onPointerEnter](/apis/core/#Script-onPointerEnter) | 不冒泡 |
| [onPointerExit](/apis/core/#Script-onPointerExit) | 不冒泡 |
| [onPointerDown](/apis/core/#Script-onPointerDown) | 冒泡 |
| [onPointerUp](/apis/core/#Script-onPointerUp) | 冒泡 |
| [onPointerClick](/apis/core/#Script-onPointerClick) | 冒泡 |
| [onPointerBeginDrag](/apis/core/#Script-onPointerBeginDrag) | 冒泡 |
| [onPointerDrag](/apis/core/#Script-onPointerDrag) | 冒泡 |
| [onPointerEndDrag](/apis/core/#Script-onPointerEndDrag) | 冒泡 |
| [onPointerDrop](/apis/core/#Script-onPointerDrop) | 冒泡 |
如下图所示,如果 C 节点触发 `pointerup` 事件, 将会沿着 C --> B --> A --> RootCanvas 路径一路派发此事件。
@@ -35,3 +34,7 @@ stateDiagram
B --> C
B --> D
```
## 脚本开发
<playground src="ui-Event.ts"></playground>

View File

@@ -1,11 +1,17 @@
---
order: 1
order: 5
title: UIGroup
type: UI
label: UI
---
通过 [UIGroup] 组件,可以继承或忽略**透明度****是否可交互**等属性。
通过 `UIGroup` 组件,可以继承或忽略**透明度****是否可交互**等属性。
## 编辑器使用
选中节点,在 **[检查器面板](/docs/interface/inspector)** 点击 **添加组件** 并选择 **UIGroup**,即可通过修改设置控制多个 UI 元素的透明度。
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*PWGYRb7MJs4AAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
## 属性
@@ -17,10 +23,6 @@ label: UI
> UIGroup 解决了 UI 元素的属性无法由父传递给子的问题。
## 编辑器
## 脚本开发
<playground src="xr-ar-simple.ts"></playground>

View File

@@ -1,29 +1,19 @@
---
order: 1
order: 2
title: 创建图片
type: UI
label: UI
---
[Image](/apis/core/#SpriteRenderer) 组件用于在 UICanvas 中显示图片。
`Image` 组件用于在 `UICanvas` 中显示图片。
## 属性
| 属性名 | 描述 |
| :--------- | :------------------------------------- |
| `sprite` | 渲染的精灵 |
| `color` | 精灵颜色 |
| `drawMode` | 绘制模式,支持普通,九宫和平铺绘制模式 |
| `raycastEnabled` | 是否可以被射线检测到 |
| `raycastPadding` | 射线检测的自定义边界与他的碰撞区域的距离,它是归一化的值并且 XYZW 分别代表距离左下右上四条边的距离 |
## 编辑器
## 编辑器使用
### 添加 Image 节点
**[层级面板](/docs/interface/hierarchy/)** 添加 Image 节点
**[层级面板](/docs/interface/hierarchy/)** 添加 `Image` 节点
<img src="![alt text](<2025-01-24 16.23.33.gif>)" style="zoom:50%;" />
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*9SCNTZNglo0AAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
> 若父亲或祖先节点没有画布组件,会自动添加上根画布节点。
@@ -31,18 +21,28 @@ label: UI
Image 的显示内容取决于设置的 [Sprite 资产]() ,选中添加了 `Image` 组件的节点,在 **[检查器面板](/docs/interface/inspector)** 的 Sprite 属性选择对应的精灵资产即可替换显示内容。
<img src="![alt text](<2025-01-24 16.23.33.gif>)" style="zoom:50%;" />
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*aztPTKxnkHEAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
### 修改渲染模式
Image 目前提供三种绘制模式,分别是普通绘制,九宫绘制与平铺绘制(默认为普通绘制),在不同的绘制模式下,修改绘制宽高可以直观地感受到各种模式之间的渲染差异。
`Image` 目前提供三种绘制模式,分别是普通绘制,九宫绘制与平铺绘制(默认为普通绘制),在不同的绘制模式下,修改绘制宽高可以直观地感受到各种模式之间的渲染差异。
<img src="![alt text](<2025-01-24 18.31.52.gif>)" style="zoom:50%;" />
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*z6iPRb0U9FUAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
### 调整尺寸
请参照[快速调整 UI 元素的尺寸]()
请参照[快速调整 UI 元素的尺寸](/docs/UI/quickStart/transform)
## 属性
| 属性名 | 描述 |
| :-- | :-- |
| `sprite` | 渲染的精灵 |
| `color` | 精灵颜色 |
| `drawMode` | 绘制模式,支持普通,九宫和平铺绘制模式 |
| `raycastEnabled` | 是否可以被射线检测到 |
| `raycastPadding` | 射线检测的自定义边界与他的碰撞区域的距离,它是归一化的值并且 XYZW 分别代表距离左下右上四条边的距离 |
## 脚本开发
<playground src="xr-ar-simple.ts"></playground>
<playground src="ui-Image.ts"></playground>

View File

@@ -1,9 +1,8 @@
---
order: 2
order: 6
title: 渲染顺序
type: UI
group: quickStart
label: UI/quickStart
label: UI
---
UI 组件的渲染顺序遵从两个规则:

View File

@@ -1,11 +1,41 @@
---
order: 2
order: 3
title: 创建文字
type: UI
label: UI
---
[Text](/apis/core/#SpriteRenderer) 组件用于在 UICanvas 中显示文字。
`Text` 组件用于在 `UICanvas` 中显示文字。
## 编辑器使用
### 添加 Text 节点
**[层级面板](/docs/interface/hierarchy/)** 添加 `Text` 节点
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*yklkSI-wIq0AAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
> 若父亲或祖先节点没有画布组件,会自动添加上根画布节点。
### 设置文本内容
选中添加了 `Text` 组件的节点,在 **[检查器面板](/docs/interface/inspector)** 修改 `text` 属性可以改变 `Text` 元素的显示内容。
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*j46eSYWAfVYAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
### 设置字体
选中添加了 `Text` 组件的节点,在 **[检查器面板](/docs/interface/inspector)** 修改 `font` 属性可以改变 `Text` 元素的字体类型。
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*vR-rR7eGHZkAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
### 修改字体大小
`Text` 组件可以通过调整 `FontSize` 修改渲染尺寸
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*DcrDR6Y_fKAAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
> 修改 `UITransform` 的 `size` 不会改变 `Text` 的渲染尺寸。
## 属性
@@ -25,38 +55,6 @@ label: UI
| `Mask Layer` | 文本所属遮罩层,用于和 SpriteMask 进行匹配,默认为 Everything表示可以和任何 SpriteMask 发生遮罩 |
| `priority` | 渲染优先级,值越小,渲染优先级越高,越优先被渲染 |
## 编辑器
### 添加 Text 节点
**[层级面板](/docs/interface/hierarchy/)** 添加 Text 节点
<img src="![alt text](<2025-01-24 17.58.43.gif>)" style="zoom:50%;" />
> 若父亲或祖先节点没有画布组件,会自动添加上根画布节点。
### 设置文本内容
选中添加了 `Text` 组件的节点,在 **[检查器面板](/docs/interface/inspector)** 修改 `text` 属性可以改变 Text 元素的显示内容。
<img src="![alt text](<2025-01-24 18.52.57-1.gif>)" style="zoom:50%;" />
### 设置字体
选中添加了 `Text` 组件的节点,在 **[检查器面板](/docs/interface/inspector)** 修改 `font` 属性可以改变 Text 元素的字体类型。
<img src="![alt text](<2025-01-24 20.08.26.gif>)" style="zoom:50%;" />
### 修改字体大小
`Text` 组件可以通过调整 FontSize 修改渲染尺寸
<img src="![alt text](<2025-01-24 20.05.54.gif>)" style="zoom:50%;" />
> 修改 `UITransform` 的 `size` 不会改变 `Text` 的渲染尺寸。
其他属性含义详见[Text]()
## 脚本开发
<playground src="xr-ar-simple.ts"></playground>
<playground src="ui-Text.ts"></playground>

View File

@@ -1,24 +1,34 @@
---
order: 2
order: 1
title: UITransform
type: UI
group: quickStart
label: UI/quickStart
label: UI
---
[UITransform](/apis/core/#SpriteRenderer) 组件是专门设计用来表示 UI 元素的尺寸和位置的,继承于 [Transform](/apis/core/#SpriteRenderer)
`UITransform` 组件是专门设计用来表示 UI 元素的尺寸和位置的,继承于 [Transform](/apis/core/#Transform) 。
## 编辑器使用
添加了 UI 组件的节点,会自动添加 `UITransform` 组件(替换原先旧的 [Transform](/apis/core/#Transform) 组件),在编辑器中,可以选中节点可以使用 `RectTool` (快捷键 `T` )快速设置属性,也可以在在 **[检查器面板](/docs/interface/inspector)** 设置精确属性。
<img src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*hJ81TKtDKLIAAAAAAAAAAAAAehuCAQ/original" style="zoom:50%;" />
> 当主画布的渲染模式为 `Screen` 时,编辑器侧会禁止修改它的 `transform` 避免屏幕适配异常,因此在脚本中,**开发者应当自己避免去篡改屏幕空间主画布 `transform` 的属性**。
## 属性
除了 [Transform](/apis/core/#SpriteRenderer)
| 属性名 | 描述 |
| :------ | :----------------------------------------------------------------------------------- |
| `size` | UI 元素的尺寸,`x` 代表宽度,`y` 代表高度,初始化都默认为 `100` |
| `pivot` | UI 元素的锚点,它是一个以左下角为原点的归一化的二元向量,默认值为中心点,即(0.5,0.5) |
| 属性名 | 描述 |
| :------ | :---------------------------------------- |
| `size` | UI 元素的尺寸,`x` 代表宽度,`y` 代表高度 |
| `pivot` | UI 元素的锚点 |
## 脚本使用
## 编辑器
添加了 UI 组件的节点,会自动添加 `UITransform` 组件(替换原先旧的 `Transform` 组件),在编辑器中,可以选中节点可以使用 `RectTool` (快捷键 `T` )快速设置属性,也可以在在 **[检查器面板](/docs/interface/inspector)** 设置精确属性。
![alt text](<2025-01-24 22.17.44.gif>)
```typescript
// Add UICanvas
const canvasEntity = root.createChild("canvas");
const canvas = canvasEntity.addComponent(UICanvas);
const imageEntity = canvasEntity.create("Image");
(<UITransform>imageEntity.transform).size.set(200, 200);
(<UITransform>imageEntity.transform).pivot.set(0, 0);
```

View File

@@ -1,6 +1,6 @@
---
order: 1
title: UI 架构
order: 2
title: 架构
type: UI
label: UI
---
@@ -9,7 +9,7 @@ label: UI
```mermaid
---
title: UI
title: UI System
---
classDiagram
Component <|-- Transform

63
examples/ui-Button.ts Normal file
View File

@@ -0,0 +1,63 @@
/**
* @title UI Button
* @category UI
*/
import { AssetType, FontStyle, Sprite, SpriteDrawMode, Texture2D, WebGLEngine } from "@galacean/engine";
import {
Button,
CanvasRenderMode,
ColorTransition,
Image,
ScaleTransition,
Text,
UICanvas,
UITransform
} from "@galacean/engine-ui";
// Create engine
WebGLEngine.create({ canvas: "canvas" }).then((engine) => {
engine.canvas.resizeByClientSize();
const scene = engine.sceneManager.activeScene;
const rootEntity = scene.createRootEntity();
// Add canvas
const canvasEntity = rootEntity.createChild("canvas");
const canvas = canvasEntity.addComponent(UICanvas);
canvas.renderMode = CanvasRenderMode.ScreenSpaceOverlay;
canvas.referenceResolutionPerUnit = 50;
// Add button
const buttonEntity = canvasEntity.createChild("Image");
const image = buttonEntity.addComponent(Image);
image.drawMode = SpriteDrawMode.Sliced;
(<UITransform>buttonEntity.transform).size.set(200, 70);
const text = buttonEntity.createChild("Text").addComponent(Text);
text.text = "Button";
text.fontStyle |= FontStyle.Bold;
text.color.set(0, 0, 0, 1);
text.fontSize = 60;
const button = buttonEntity.addComponent(Button);
const scaleTransition = new ScaleTransition();
scaleTransition.target = image;
const colorTransition = new ColorTransition();
colorTransition.target = image;
button.addTransition(scaleTransition);
button.addTransition(colorTransition);
button.addClicked(() => {
window.alert("button clicked");
});
engine.resourceManager
.load<Texture2D>({
url: "https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*mFpSS502qUYAAAAAAAAAAAAAehuCAQ/original",
type: AssetType.Texture2D
})
.then((texture) => {
const sprite = new Sprite(engine, texture);
sprite.border.set(0.49, 0.49, 0.49, 0.49);
image.sprite = sprite;
});
engine.run();
});

85
examples/ui-Event.ts Normal file
View File

@@ -0,0 +1,85 @@
/**
* @title UI Event
* @category UI
*/
import { AssetType, PointerEventData, Script, Sprite, Texture2D, WebGLEngine } from "@galacean/engine";
import { CanvasRenderMode, Image, UICanvas, UITransform } from "@galacean/engine-ui";
// Create engine
WebGLEngine.create({ canvas: "canvas" }).then((engine) => {
engine.canvas.resizeByClientSize();
const scene = engine.sceneManager.activeScene;
const rootEntity = scene.createRootEntity();
// Add canvas
const canvasEntity = rootEntity.createChild("canvas");
const canvas = canvasEntity.addComponent(UICanvas);
canvas.renderMode = CanvasRenderMode.ScreenSpaceOverlay;
canvas.referenceResolutionPerUnit = 50;
// Add ImageOne
const imageEntity1 = canvasEntity.createChild("Image1");
const image1 = imageEntity1.addComponent(Image);
image1.color.set(1, 0, 0, 1);
(<UITransform>imageEntity1.transform).size.set(300, 300);
imageEntity1.addComponent(EventScript);
const imageEntity2 = imageEntity1.createChild("Image2");
const image2 = imageEntity2.addComponent(Image);
image2.color.set(0, 1, 0, 1);
(<UITransform>imageEntity2.transform).size.set(200, 200);
imageEntity2.addComponent(EventScript);
const imageEntity3 = imageEntity2.createChild("Image3");
const image3 = imageEntity3.addComponent(Image);
image3.color.set(0, 0, 1, 1);
(<UITransform>imageEntity3.transform).size.set(100, 100);
imageEntity3.addComponent(EventScript);
engine.resourceManager
.load<Texture2D>({
url: "https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*wW-5TYANcJAAAAAAAAAAAAAADhuCAQ/original/Image.png",
type: AssetType.Texture2D
})
.then((texture) => {
const sprite = new Sprite(engine, texture);
image1.sprite = image2.sprite = image3.sprite = sprite;
});
engine.run();
});
class EventScript extends Script {
onPointerEnter(eventData: PointerEventData): void {
console.log(this.entity.name, "onPointerEnter");
}
onPointerDown(eventData: PointerEventData): void {
console.log(this.entity.name, "onPointerDown");
}
onPointerUp(eventData: PointerEventData): void {
console.log(this.entity.name, "onPointerUp");
}
onPointerClick(eventData: PointerEventData): void {
console.log(this.entity.name, "onPointerClick");
}
onPointerExit(eventData: PointerEventData): void {
console.log(this.entity.name, "onPointerExit");
}
onPointerBeginDrag(eventData: PointerEventData): void {
console.log(this.entity.name, "onPointerBeginDrag");
}
onPointerEndDrag(eventData: PointerEventData): void {
console.log(this.entity.name, "onPointerEndDrag");
}
onPointerDrop(eventData: PointerEventData): void {
console.log(this.entity.name, "onPointerDrop");
}
}

View File

@@ -4,76 +4,70 @@
* @thumbnail https://mdn.alipayobjects.com/merchant_appfe/afts/img/A*t4cXTbFa6kkAAAAAAAAAAAAADiR2AQ/original
*/
import {
AmbientLight,
AssetType,
Camera,
DirectLight,
MeshRenderer,
PBRMaterial,
PrimitiveMesh,
Sprite,
Vector3,
WebGLEngine,
} from "@galacean/engine";
import {
UICanvas,
Image,
CanvasRenderMode,
SpriteDrawMode,
} from "@galacean/engine-ui";
import { AssetType, Sprite, SpriteDrawMode, Texture2D, WebGLEngine } from "@galacean/engine";
import { CanvasRenderMode, Image, Text, UICanvas, UITransform } from "@galacean/engine-ui";
// Create engine
WebGLEngine.create({ canvas: "canvas" }).then((engine) => {
engine.canvas.resizeByClientSize();
const rootEntity = engine.sceneManager.scenes[0].createRootEntity();
const scene = engine.sceneManager.activeScene;
const rootEntity = scene.createRootEntity();
// Create camera
const cameraEntity = rootEntity.createChild("Camera");
cameraEntity.transform.position = new Vector3(0, 0, 10);
const camera = cameraEntity.addComponent(Camera);
camera.fieldOfView = 60;
camera.farClipPlane = 200;
camera.nearClipPlane = 0.3;
camera.isOrthographic = true;
// 添加 canvas
// Add canvas
const canvasEntity = rootEntity.createChild("canvas");
const canvas = canvasEntity.addComponent(UICanvas);
canvas.renderMode = CanvasRenderMode.ScreenSpaceOverlay;
canvas.referenceResolutionPerUnit = 50;
// 添加按钮
const buttonEntity = canvasEntity.createChild("Image");
const image = buttonEntity.addComponent(Image);
image.drawMode = SpriteDrawMode.Sliced;
// Add Image
const simpleImageEntity = canvasEntity.createChild("Image");
const simpleImage = simpleImageEntity.addComponent(Image);
simpleImage.drawMode = SpriteDrawMode.Simple;
const simpleImageTransform = <UITransform>simpleImageEntity.transform;
simpleImageTransform.position.set(-300, 0, 0);
simpleImageTransform.size.set(200, 70);
const simpleTextEntity = canvasEntity.createChild("Text");
simpleTextEntity.transform.setPosition(-300, 70, 0);
const simpleText = simpleTextEntity.addComponent(Text);
simpleText.text = "Simple Image";
const slicedImageEntity = canvasEntity.createChild("Image");
const slicedImage = slicedImageEntity.addComponent(Image);
slicedImage.drawMode = SpriteDrawMode.Sliced;
const slicedImageTransform = <UITransform>slicedImageEntity.transform;
slicedImageTransform.size.set(200, 70);
const slicedTextEntity = canvasEntity.createChild("Text");
slicedTextEntity.transform.setPosition(0, 70, 0);
const slicedText = slicedTextEntity.addComponent(Text);
slicedText.text = "Sliced Image";
const tiledImageEntity = canvasEntity.createChild("Image");
const tiledImage = tiledImageEntity.addComponent(Image);
tiledImage.drawMode = SpriteDrawMode.Tiled;
const tiledImageTransform = <UITransform>tiledImageEntity.transform;
tiledImageTransform.position.set(300, 0, 0);
tiledImageTransform.size.set(200, 70);
const tiledTextEntity = canvasEntity.createChild("Text");
tiledTextEntity.transform.setPosition(300, 70, 0);
const tiledText = tiledTextEntity.addComponent(Text);
tiledText.text = "Tiled Image";
engine.resourceManager
// @ts-ignore
.load<[Texture2D, Texture2D, Texture2D]>([
{
url: "https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*mgwORIDzEGUAAAAAAAAAAAAADhuCAQ/original",
type: AssetType.Texture2D,
},
{
url: "https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*bH8HRYxI0pEAAAAAAAAAAAAADhuCAQ/original",
type: AssetType.Texture2D,
},
{
url: "https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*ehlWSJN0y6gAAAAAAAAAAAAADhuCAQ/original",
type: AssetType.Texture2D,
},
])
.then(([normalTexture, pressedTexture, disableTexture]) => {
const normalSprite = new Sprite(engine, normalTexture);
const pressedSprite = new Sprite(engine, pressedTexture);
const disableSprite = new Sprite(engine, disableTexture);
normalSprite.border.set(0.3, 0.3, 0.3, 0.3);
pressedSprite.border.set(0.3, 0.3, 0.3, 0.3);
disableSprite.border.set(0.3, 0.3, 0.3, 0.3);
image.sprite = normalSprite;
.load<Texture2D>({
url: "https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*mFpSS502qUYAAAAAAAAAAAAAehuCAQ/original",
type: AssetType.Texture2D
})
.then((texture) => {
const simpleSprite = new Sprite(engine, texture);
const slicedSprite = new Sprite(engine, texture);
slicedSprite.border.set(0.49, 0.49, 0.49, 0.49);
const tiledSprite = new Sprite(engine, texture);
simpleImage.sprite = simpleSprite;
slicedImage.sprite = slicedSprite;
tiledImage.sprite = tiledSprite;
});
engine.run();

88
examples/ui-Text.ts Normal file
View File

@@ -0,0 +1,88 @@
/**
* @title UI Text
* @category UI
* @thumbnail https://mdn.alipayobjects.com/merchant_appfe/afts/img/A*t4cXTbFa6kkAAAAAAAAAAAAADiR2AQ/original
*/
import { Color, Entity, Font, FontStyle, Vector3, WebGLEngine } from "@galacean/engine";
import { CanvasRenderMode, Text, UICanvas } from "@galacean/engine-ui";
// Create engine
WebGLEngine.create({ canvas: "canvas" }).then((engine) => {
engine.canvas.resizeByClientSize();
const rootEntity = engine.sceneManager.scenes[0].createRootEntity();
// Add canvas
const canvasEntity = rootEntity.createChild("canvas");
const canvas = canvasEntity.addComponent(UICanvas);
canvas.renderMode = CanvasRenderMode.ScreenSpaceOverlay;
// The position of text
const pos = new Vector3();
// The color of text
const color = new Color();
// Create text with default params
pos.set(0, 125, 0);
color.set(1, 1, 1, 1);
createText();
// Create text with cursive font family
pos.set(0, 75, 0);
color.set(1, 1, 1, 1);
const entity = createText("cursive");
for (let i = 0; i < 10; i++) {
entity.clone();
}
// Create text with font size 36
pos.set(0, 25, 0);
color.set(1, 0.5, 0.5, 1);
createText("Arial", 36);
// Create text with bold
pos.set(0, -25, 0);
color.set(1, 1, 1, 1);
createText("Arial", 26, true);
// Create text with italic
pos.set(0, -75, 0);
color.set(1, 1, 1, 1);
createText("Arial", 26, false, true);
// Create text with bold and italic
pos.set(0, -125, 0);
color.set(1, 1, 1, 1);
createText("Arial", 26, true, true);
engine.run();
/**
* Create text to display by params.
* @param fontFamily - The font family
* @param fontSize - The size of font
* @param bold - The text whether bold
* @param italic - The text whether italic
*/
function createText(
fontFamily: string = "Arial",
fontSize: number = 26,
bold: boolean = false,
italic: boolean = false
): Entity {
// Create text entity
const entity = canvasEntity.createChild("text");
entity.transform.position = pos;
// Add text renderer for text entity
const text = entity.addComponent(Text);
// Set text color
text.color = color;
// Set text to render
text.text = "The quick brown fox jumps over the lazy dog";
// Set font with font family
text.font = Font.createFromOS(entity.engine, fontFamily);
// Set font size
text.fontSize = fontSize;
// Set font whether bold
bold && (text.fontStyle |= FontStyle.Bold);
// Set font whether italic
italic && (text.fontStyle |= FontStyle.Italic);
return entity;
}
});