diff --git a/docs/en/UI/_meta.json b/docs/en/UI/_meta.json new file mode 100644 index 000000000..963d63d40 --- /dev/null +++ b/docs/en/UI/_meta.json @@ -0,0 +1,11 @@ +{ + "overall": { + "title": "Overview" + }, + "quickStart": { + "title": "QuickStart" + }, + "system": { + "title": "Architecture" + } +} diff --git a/docs/en/UI/overall.md b/docs/en/UI/overall.md new file mode 100644 index 000000000..1dc8f574d --- /dev/null +++ b/docs/en/UI/overall.md @@ -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) diff --git a/docs/en/UI/quickStart/button.md b/docs/en/UI/quickStart/button.md new file mode 100644 index 000000000..20cb75310 --- /dev/null +++ b/docs/en/UI/quickStart/button.md @@ -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/)**. + + + +> 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. + + + +## 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 + + \ No newline at end of file diff --git a/docs/en/UI/quickStart/canvas.md b/docs/en/UI/quickStart/canvas.md new file mode 100644 index 000000000..7bb4b12c1 --- /dev/null +++ b/docs/en/UI/quickStart/canvas.md @@ -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. Here’s 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/)**. + + + +### Set Properties + +Select the node that has the `Canvas` component and you can set its properties in the **[Inspector Panel](/docs/interface/inspector)**. + + + +### 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. + + + +## 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; +``` \ No newline at end of file diff --git a/docs/en/UI/quickStart/event.md b/docs/en/UI/quickStart/event.md new file mode 100644 index 000000000..0d6db4145 --- /dev/null +++ b/docs/en/UI/quickStart/event.md @@ -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 + + \ No newline at end of file diff --git a/docs/en/UI/quickStart/group.md b/docs/en/UI/quickStart/group.md new file mode 100644 index 000000000..8ec0cae9b --- /dev/null +++ b/docs/en/UI/quickStart/group.md @@ -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. + + + +## 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 + + \ No newline at end of file diff --git a/docs/en/UI/quickStart/image.md b/docs/en/UI/quickStart/image.md new file mode 100644 index 000000000..f4851aed6 --- /dev/null +++ b/docs/en/UI/quickStart/image.md @@ -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/)**. + + + +> 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. + + + +### 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. + + + +### 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 + + \ No newline at end of file diff --git a/docs/en/UI/quickStart/order.md b/docs/en/UI/quickStart/order.md new file mode 100644 index 000000000..803b97bc1 --- /dev/null +++ b/docs/en/UI/quickStart/order.md @@ -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. \ No newline at end of file diff --git a/docs/en/UI/quickStart/text.md b/docs/en/UI/quickStart/text.md new file mode 100644 index 000000000..8a30a56a3 --- /dev/null +++ b/docs/en/UI/quickStart/text.md @@ -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/)**. + + + +> 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. + + + +### 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. + + + +### Modify Font Size + +The `Text` component can modify the rendering size by adjusting the `FontSize`. + + + +> 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 + + \ No newline at end of file diff --git a/docs/en/UI/quickStart/transform.md b/docs/en/UI/quickStart/transform.md new file mode 100644 index 000000000..95c05f739 --- /dev/null +++ b/docs/en/UI/quickStart/transform.md @@ -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)**. + + + +> 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"); +(imageEntity.transform).size.set(200, 200); +(imageEntity.transform).pivot.set(0, 0); +``` \ No newline at end of file diff --git a/docs/en/UI/system.md b/docs/en/UI/system.md new file mode 100644 index 000000000..f6fe6df87 --- /dev/null +++ b/docs/en/UI/system.md @@ -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{ + <> + +Vector2 size + +Vector2 pivot + } + + class Renderer{ + +BoundingBox bounds + +Material getMaterial() + +Material setMaterial() + } + + class UIRenderer{ + <> + +Color color + +boolean raycastEnabled + +vec4 raycastPadding + } + + class Image{ + <> + +Sprite sprite + +SpriteDrawMode drawMode + ... + } + + class Text{ + <> + +string text + +Font font + ... + } + + class UICanvas { + <> + +CanvasRenderMode renderMode + +Camera renderCamera + ... + } + + class UIInteractive { + <> + +boolean interactive + +Transition transitions + ... + } + + class Button { + <> + +void addClicked() + +void removeClicked() + ... + } + + class UIGroup { + <> + +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`. \ No newline at end of file diff --git a/docs/en/_meta.json b/docs/en/_meta.json index c4284d4e7..670683210 100644 --- a/docs/en/_meta.json +++ b/docs/en/_meta.json @@ -47,6 +47,12 @@ "collapse": true } }, + "UI": { + "title": "UI", + "theme": { + "collapse": true + } + }, "xr": { "title": "XR", "theme": { diff --git a/docs/zh/UI/_meta.json b/docs/zh/UI/_meta.json index a56d32629..522ed42a5 100644 --- a/docs/zh/UI/_meta.json +++ b/docs/zh/UI/_meta.json @@ -1,11 +1,11 @@ { "overall": { - "title": "UI 总览" + "title": "总览" }, "quickStart": { "title": "快速上手" }, "system": { - "title": "UI 架构" + "title": "架构" } } diff --git a/docs/zh/UI/overall.md b/docs/zh/UI/overall.md index e122e5c9c..763bf8ab8 100644 --- a/docs/zh/UI/overall.md +++ b/docs/zh/UI/overall.md @@ -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) diff --git a/docs/zh/UI/quickStart/2025-01-24 15.50.47.gif b/docs/zh/UI/quickStart/2025-01-24 15.50.47.gif deleted file mode 100644 index 235ed1d38..000000000 Binary files a/docs/zh/UI/quickStart/2025-01-24 15.50.47.gif and /dev/null differ diff --git a/docs/zh/UI/quickStart/2025-01-24 16.19.45.gif b/docs/zh/UI/quickStart/2025-01-24 16.19.45.gif deleted file mode 100644 index 6b2c1df75..000000000 Binary files a/docs/zh/UI/quickStart/2025-01-24 16.19.45.gif and /dev/null differ diff --git a/docs/zh/UI/quickStart/2025-01-24 16.23.33.gif b/docs/zh/UI/quickStart/2025-01-24 16.23.33.gif deleted file mode 100644 index 137b164b3..000000000 Binary files a/docs/zh/UI/quickStart/2025-01-24 16.23.33.gif and /dev/null differ diff --git a/docs/zh/UI/quickStart/2025-01-24 17.58.43.gif b/docs/zh/UI/quickStart/2025-01-24 17.58.43.gif deleted file mode 100644 index 0de80e304..000000000 Binary files a/docs/zh/UI/quickStart/2025-01-24 17.58.43.gif and /dev/null differ diff --git a/docs/zh/UI/quickStart/2025-01-24 18.02.39.gif b/docs/zh/UI/quickStart/2025-01-24 18.02.39.gif deleted file mode 100644 index 5248081ac..000000000 Binary files a/docs/zh/UI/quickStart/2025-01-24 18.02.39.gif and /dev/null differ diff --git a/docs/zh/UI/quickStart/2025-01-24 18.31.52.gif b/docs/zh/UI/quickStart/2025-01-24 18.31.52.gif deleted file mode 100644 index 561ac4f08..000000000 Binary files a/docs/zh/UI/quickStart/2025-01-24 18.31.52.gif and /dev/null differ diff --git a/docs/zh/UI/quickStart/2025-01-24 20.05.54.gif b/docs/zh/UI/quickStart/2025-01-24 20.05.54.gif deleted file mode 100644 index 32b12be25..000000000 Binary files a/docs/zh/UI/quickStart/2025-01-24 20.05.54.gif and /dev/null differ diff --git a/docs/zh/UI/quickStart/2025-01-24 20.08.26.gif b/docs/zh/UI/quickStart/2025-01-24 20.08.26.gif deleted file mode 100644 index 6799061d1..000000000 Binary files a/docs/zh/UI/quickStart/2025-01-24 20.08.26.gif and /dev/null differ diff --git a/docs/zh/UI/quickStart/2025-01-24 20.24.17.gif b/docs/zh/UI/quickStart/2025-01-24 20.24.17.gif deleted file mode 100644 index de0a05c4c..000000000 Binary files a/docs/zh/UI/quickStart/2025-01-24 20.24.17.gif and /dev/null differ diff --git a/docs/zh/UI/quickStart/2025-01-24 22.17.44.gif b/docs/zh/UI/quickStart/2025-01-24 22.17.44.gif deleted file mode 100644 index 1486716a3..000000000 Binary files a/docs/zh/UI/quickStart/2025-01-24 22.17.44.gif and /dev/null differ diff --git a/docs/zh/UI/quickStart/2025-01-24 23.01.32-1.gif b/docs/zh/UI/quickStart/2025-01-24 23.01.32-1.gif deleted file mode 100644 index e237f9512..000000000 Binary files a/docs/zh/UI/quickStart/2025-01-24 23.01.32-1.gif and /dev/null differ diff --git a/docs/zh/UI/quickStart/2025-01-24 23.01.32.gif b/docs/zh/UI/quickStart/2025-01-24 23.01.32.gif deleted file mode 100644 index e237f9512..000000000 Binary files a/docs/zh/UI/quickStart/2025-01-24 23.01.32.gif and /dev/null differ diff --git a/docs/zh/UI/quickStart/2025-01-24 23.03.11.gif b/docs/zh/UI/quickStart/2025-01-24 23.03.11.gif deleted file mode 100644 index 735e49742..000000000 Binary files a/docs/zh/UI/quickStart/2025-01-24 23.03.11.gif and /dev/null differ diff --git a/docs/zh/UI/quickStart/button.md b/docs/zh/UI/quickStart/button.md index 9075eaa59..50444dbe5 100644 --- a/docs/zh/UI/quickStart/button.md +++ b/docs/zh/UI/quickStart/button.md @@ -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` 节点 - + > 若父亲或祖先节点没有画布组件,会自动添加上根画布节点。 @@ -35,8 +21,24 @@ label: UI 在编辑器中可以方便地设置按钮在不同状态下的过渡表现 - + + +## 属性 + +| 属性名 | 描述 | +| :------------ | :----------------- | +| `transitions` | 按钮的所有过渡表现 | +| `interactive` | 按钮是否可交互 | + +## 方法 + +| 方法名 | 描述 | +| :----------------- | :------------------- | +| `addTransition` | 添加一个按钮过渡表现 | +| `removeTransition` | 移除某个按钮过渡表现 | +| `addClicked` | 添加一个点击回调函数 | +| `removeClicked` | 移除某个点击回调函数 | ## 脚本开发 - + diff --git a/docs/zh/UI/quickStart/canvas.md b/docs/zh/UI/quickStart/canvas.md index e0297bb6b..0172440f7 100644 --- a/docs/zh/UI/quickStart/canvas.md +++ b/docs/zh/UI/quickStart/canvas.md @@ -1,12 +1,32 @@ --- order: 0 title: 创建根画布 -type: XR -label: XR +type: UI +label: UI --- 根画布是 UI 的基础,但不是所有的 `UICanvas` 都是根画布,接下来为大家演示如何在场景中创建根画布。 +## 编辑器使用 + +### 添加 UICanvas 节点 + +在 **[层级面板](/docs/interface/hierarchy/)** 添加 Canvas 节点 + + + +### 设置属性 + +选中添加了 `Canvas` 组件的节点,可以在 **[检查器面板](/docs/interface/inspector)** 设置相关的属性 + + + +### 根画布 + +如果新添加的画布节点的父亲或祖先节点已经包含激活的 `UICanvas` 组件,那么此画布不包含任何渲染与交互的功能。 + + + ## 属性 | 属性名 | 描述 | @@ -19,26 +39,6 @@ label: XR | `referenceResolutionPerUnit` | 画布中的单位与世界空间中单位的比例关系 | | `sortOrder` | 画布的渲染排序优先级 | -## 编辑器使用 - -### 添加 UICanvas 节点 - -在 **[层级面板](/docs/interface/hierarchy/)** 添加 Canvas 节点 - - - -### 设置属性 - -选中添加了 `Canvas` 组件的节点,可以在 **[检查器面板](/docs/interface/inspector)** 设置相关的属性 - -![alt text](<2025-01-24 23.01.32.gif>) - -### 根画布 - -如果新添加的画布节点的父亲或祖先节点已经包含激活的 `UICanvas` 组件,那么此画布不包含任何渲染与交互的功能。 - -![alt text](<2025-01-24 23.03.11.gif>) - ## 脚本开发 ```typescript diff --git a/docs/zh/UI/quickStart/event.md b/docs/zh/UI/quickStart/event.md index 16241d4cb..fd3ab2324 100644 --- a/docs/zh/UI/quickStart/event.md +++ b/docs/zh/UI/quickStart/event.md @@ -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 ``` + +## 脚本开发 + + diff --git a/docs/zh/UI/quickStart/group.md b/docs/zh/UI/quickStart/group.md index a9166425e..08a51af70 100644 --- a/docs/zh/UI/quickStart/group.md +++ b/docs/zh/UI/quickStart/group.md @@ -1,11 +1,17 @@ --- -order: 1 +order: 5 title: UIGroup type: UI label: UI --- -通过 [UIGroup] 组件,可以继承或忽略**透明度**,**是否可交互**等属性。 +通过 `UIGroup` 组件,可以继承或忽略**透明度**,**是否可交互**等属性。 + +## 编辑器使用 + +选中节点,在 **[检查器面板](/docs/interface/inspector)** 点击 **添加组件** 并选择 **UIGroup**,即可通过修改设置控制多个 UI 元素的透明度。 + + ## 属性 @@ -17,10 +23,6 @@ label: UI > UIGroup 解决了 UI 元素的属性无法由父传递给子的问题。 -## 编辑器 - - - ## 脚本开发 diff --git a/docs/zh/UI/quickStart/image.md b/docs/zh/UI/quickStart/image.md index 4fefd0743..18528a6fc 100644 --- a/docs/zh/UI/quickStart/image.md +++ b/docs/zh/UI/quickStart/image.md @@ -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` | 射线检测的自定义边界与他的碰撞区域的距离,它是归一化的值并且 X,Y,Z,W 分别代表距离左下右上四条边的距离 | - -## 编辑器 +## 编辑器使用 ### 添加 Image 节点 -在 **[层级面板](/docs/interface/hierarchy/)** 添加 Image 节点 +在 **[层级面板](/docs/interface/hierarchy/)** 添加 `Image` 节点 - + > 若父亲或祖先节点没有画布组件,会自动添加上根画布节点。 @@ -31,18 +21,28 @@ label: UI Image 的显示内容取决于设置的 [Sprite 资产]() ,选中添加了 `Image` 组件的节点,在 **[检查器面板](/docs/interface/inspector)** 的 Sprite 属性选择对应的精灵资产即可替换显示内容。 - + ### 修改渲染模式 -Image 目前提供三种绘制模式,分别是普通绘制,九宫绘制与平铺绘制(默认为普通绘制),在不同的绘制模式下,修改绘制宽高可以直观地感受到各种模式之间的渲染差异。 +`Image` 目前提供三种绘制模式,分别是普通绘制,九宫绘制与平铺绘制(默认为普通绘制),在不同的绘制模式下,修改绘制宽高可以直观地感受到各种模式之间的渲染差异。 - + ### 调整尺寸 -请参照[快速调整 UI 元素的尺寸]() +请参照[快速调整 UI 元素的尺寸](/docs/UI/quickStart/transform) + +## 属性 + +| 属性名 | 描述 | +| :-- | :-- | +| `sprite` | 渲染的精灵 | +| `color` | 精灵颜色 | +| `drawMode` | 绘制模式,支持普通,九宫和平铺绘制模式 | +| `raycastEnabled` | 是否可以被射线检测到 | +| `raycastPadding` | 射线检测的自定义边界与他的碰撞区域的距离,它是归一化的值并且 X,Y,Z,W 分别代表距离左下右上四条边的距离 | ## 脚本开发 - + diff --git a/docs/zh/UI/quickStart/order.md b/docs/zh/UI/quickStart/order.md index 7d3097a86..2e22e6a59 100644 --- a/docs/zh/UI/quickStart/order.md +++ b/docs/zh/UI/quickStart/order.md @@ -1,9 +1,8 @@ --- -order: 2 +order: 6 title: 渲染顺序 type: UI -group: quickStart -label: UI/quickStart +label: UI --- UI 组件的渲染顺序遵从两个规则: diff --git a/docs/zh/UI/quickStart/text.md b/docs/zh/UI/quickStart/text.md index b8b38db5c..5f102c35f 100644 --- a/docs/zh/UI/quickStart/text.md +++ b/docs/zh/UI/quickStart/text.md @@ -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` 节点 + + + +> 若父亲或祖先节点没有画布组件,会自动添加上根画布节点。 + +### 设置文本内容 + +选中添加了 `Text` 组件的节点,在 **[检查器面板](/docs/interface/inspector)** 修改 `text` 属性可以改变 `Text` 元素的显示内容。 + + + +### 设置字体 + +选中添加了 `Text` 组件的节点,在 **[检查器面板](/docs/interface/inspector)** 修改 `font` 属性可以改变 `Text` 元素的字体类型。 + + + +### 修改字体大小 + +`Text` 组件可以通过调整 `FontSize` 修改渲染尺寸 + + + +> 修改 `UITransform` 的 `size` 不会改变 `Text` 的渲染尺寸。 ## 属性 @@ -25,38 +55,6 @@ label: UI | `Mask Layer` | 文本所属遮罩层,用于和 SpriteMask 进行匹配,默认为 Everything,表示可以和任何 SpriteMask 发生遮罩 | | `priority` | 渲染优先级,值越小,渲染优先级越高,越优先被渲染 | -## 编辑器 - -### 添加 Text 节点 - -在 **[层级面板](/docs/interface/hierarchy/)** 添加 Text 节点 - - - -> 若父亲或祖先节点没有画布组件,会自动添加上根画布节点。 - -### 设置文本内容 - -选中添加了 `Text` 组件的节点,在 **[检查器面板](/docs/interface/inspector)** 修改 `text` 属性可以改变 Text 元素的显示内容。 - - - -### 设置字体 - -选中添加了 `Text` 组件的节点,在 **[检查器面板](/docs/interface/inspector)** 修改 `font` 属性可以改变 Text 元素的字体类型。 - - - -### 修改字体大小 - -`Text` 组件可以通过调整 FontSize 修改渲染尺寸 - - - -> 修改 `UITransform` 的 `size` 不会改变 `Text` 的渲染尺寸。 - -其他属性含义详见[Text]() - ## 脚本开发 - + diff --git a/docs/zh/UI/quickStart/transform.md b/docs/zh/UI/quickStart/transform.md index 1fe4a9d79..37622e28b 100644 --- a/docs/zh/UI/quickStart/transform.md +++ b/docs/zh/UI/quickStart/transform.md @@ -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)** 设置精确属性。 + + + +> 当主画布的渲染模式为 `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>) \ No newline at end of file +```typescript +// Add UICanvas +const canvasEntity = root.createChild("canvas"); +const canvas = canvasEntity.addComponent(UICanvas); +const imageEntity = canvasEntity.create("Image"); +(imageEntity.transform).size.set(200, 200); +(imageEntity.transform).pivot.set(0, 0); +``` diff --git a/docs/zh/UI/system.md b/docs/zh/UI/system.md index 80edeaf04..357f559a1 100644 --- a/docs/zh/UI/system.md +++ b/docs/zh/UI/system.md @@ -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 diff --git a/examples/ui-Button.ts b/examples/ui-Button.ts new file mode 100644 index 000000000..3d2ab95f6 --- /dev/null +++ b/examples/ui-Button.ts @@ -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; + (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({ + 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(); +}); diff --git a/examples/ui-Event.ts b/examples/ui-Event.ts new file mode 100644 index 000000000..27d15c91c --- /dev/null +++ b/examples/ui-Event.ts @@ -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); + (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); + (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); + (imageEntity3.transform).size.set(100, 100); + imageEntity3.addComponent(EventScript); + + engine.resourceManager + .load({ + 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"); + } +} diff --git a/examples/ui-Image.ts b/examples/ui-Image.ts index e426cda90..a43bb9a2c 100644 --- a/examples/ui-Image.ts +++ b/examples/ui-Image.ts @@ -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 = 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 = 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 = 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({ + 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(); diff --git a/examples/ui-Text.ts b/examples/ui-Text.ts new file mode 100644 index 000000000..fadafb416 --- /dev/null +++ b/examples/ui-Text.ts @@ -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; + } +});