For the complete documentation index, see llms.txt. This page is also available as Markdown.

UI 定位

设置 UI 实体的位置、缩放、内边距和其他属性。

对于各种 UI 内容,请使用 uiTransform 组件来设置实体的大小、位置以及与对齐相关的其他属性。

该 uiTransform 组件在屏幕的 2D 空间中工作,很像 Transform 组件在场景的 3D 空间中工作。

ui.tsx 文件:

import { UiEntity, ReactEcs } from '@dcl/sdk/react-ecs'
import { Color4 } from '@dcl/sdk/math'

export const uiMenu = () => (
	<UiEntity
		uiTransform={{
			width: '200px',
			height: '100px',
			justifyContent: 'center',
			alignItems: 'center',
		}}
		uiBackground={{ color: Color4.Green() }}
	/>
)

index.ts 文件:

import { ReactEcsRenderer } from '@dcl/sdk/react-ecs'
import { uiMenu } from './ui'

export function main() {
    ReactEcsRenderer.setUiRenderer(uiMenu)
}

定位属性

UI 实体的对齐基于 Flexbox 对齐模型。这是一个非常强大的模型,可用于在大小可能不同的模态窗口中动态组织嵌套实体。

💡 提示:Decentraland 的 UI 实现基于 Yoga。请阅读 本文 ,以获得对 Flexbox 中可用属性的非常易懂且深入的介绍。

实体大小

使用 width 和 height 来设置实体的大小。支持以下几种值:

  • auto:大小会自适应以适合内部内容。这对于长度可能变化的文本非常方便。将值写为“auto”。

  • 百分比:作为父级测量值的百分比。将值写成以“%”结尾的字符串,例如 10 %.

  • 像素:将值写成数字。

  • 屏幕宽度或高度:可使用 vw(视口宽度)和 vh(视口高度)来表示运行 Decentraland 的窗口总尺寸的一部分。例如 10vw 表示窗口宽度的 10%, 25vh 表示窗口高度的 25%。

请注意,这些属性会影响 default 该项的大小,即在执行任何 flex grow 和 flex shrink 计算之前该项的大小。最终大小可能会根据父实体的大小以及所设置的 Flexbox 属性而以不同方式解释。

还可以使用以下其他属性以更高级的方式调整大小:

  • maxWidth 和 maxHeight: 数值 或字符串(如 height 和 width)。实体可具有的最大尺寸。

  • minWidth 和 minHeight: 数值 或字符串(如 height 和 width)。实体可具有的最小尺寸。如果父级太小,无法容纳实体的最小尺寸,它们会溢出父级。

  • flexBasis:这是一种与轴无关的方式,用于提供沿主轴方向的项目默认大小。设置子项的 flex basis 类似于:如果其父级是 flex direction: row 的容器,则设置该子项的 width;如果其父级是 flex direction: column 的容器,则类似于设置子项的 height。

排列子实体

默认情况下,子实体相对于其父级的左上角定位。你可以使用 justifyContent 和 alignItems 等属性来改变这种行为。

💡 提示:任何引用 内容 的属性都指向主轴上的实体(由 flexDirection决定)。任何引用

  • flexDirection:Flex direction 控制节点子项的布局方向。这也称为主轴。主轴是子项布局的方向。交叉轴是与主轴垂直的轴,或者说是换行排列所沿用的轴。它的值来自 FlexDirectionType 类型。可用选项如下:

    • row (默认)

    • row-reverse

    • column

    • column-reverse

  • justifyContent:此属性描述了如何在容器的主轴上对齐子项。例如,你可以使用此属性将子项在 flexDirection 设为 row 的容器中水平居中,或在 flexDirection 设为 column 的容器中垂直居中。此属性的值必须来自 JustifyType 类型。可能的值有:

    • flex-start (默认):将容器的子项对齐到容器主轴的起点。

    • flex-end:将容器的子项对齐到容器主轴的终点。

    • center:将容器的子项居中对齐到容器主轴。

    • space-between:在容器主轴上均匀分布子项,并将剩余空间分配在子项之间。

    • space-around:在容器主轴上均匀分布子项,并在子项周围分配剩余空间。与 space-between 相比,使用 space-around 会将空间分配到第一个子项的开头和最后一个子项的结尾。

    • space-evenly:在容器主轴上均匀分布子项,并分配剩余空间,使子项之间以及子项与容器边缘之间的间隙都相等。

  • alignItems:描述如何沿容器的交叉轴对齐子项。align items 与 justify content 非常相似,但它不是应用于主轴,而是应用于交叉轴。此属性需要来自 AlignType 类型。可用选项如下:

    • 拉伸: (默认)拉伸容器的子项以匹配容器交叉轴的高度。

    • flex-start:将容器的子项对齐到容器交叉轴的起点。

    • flex-end:将容器的子项对齐到容器交叉轴的终点。

    • center:将容器的子项居中对齐到容器交叉轴。

    • baseline:沿共同基线对齐容器的子项。单个子项可以设置为其父级的参考基线。

  • alignSelf:align self 具有与 alignItems 相同的选项和效果,但不是影响容器中的子项,而是可以将此属性应用于单个子项,以改变其在父级中的对齐方式。align self 会覆盖父级通过 align items 设置的任何选项。它的值来自 AlignType以无代码方式触发声音播放,参见 alignItems 。有关这些选项的详细信息,请参见上文。

  • alignContent:align content 定义了沿交叉轴的行分布。只有在使用 flexWrap将项目换行到多行时,这才会生效。它的值来自 AlignType 类型。可用选项如下:

    • flex-start: (默认)将换行对齐到容器交叉轴的起点。

    • flex-end:将换行对齐到容器交叉轴的终点。

    • 拉伸:拉伸换行以匹配容器交叉轴的高度。

    • center:将换行居中对齐到容器交叉轴。

    • space-between:在容器主轴上均匀分布换行,并将剩余空间分配在各行之间。

    • space-around:在容器主轴上均匀分布换行,并在各行周围分配剩余空间。与 space-between 相比,使用 space-around 会将空间分配到第一行的开头和最后一行的结尾。

  • flexGrow:这描述了容器内的任何空间应如何沿主轴分配给其子项。在布局完子项后,容器会根据子项指定的 flex grow 值分配任何剩余空间。Flex grow 接受任何大于等于 0 的浮点值,0 为默认值。容器会按照子项的 flex grow 值加权分配剩余空间。

  • flexShrink:描述当子项总大小在主轴上超过容器大小时,如何沿主轴缩小子项。flex shrink 与 flex grow 非常相似,如果把任何溢出的大小视为负的剩余空间,也可以用同样的方式理解。这两个属性也可以很好地协同工作,允许子项按需增长和收缩。Flex shrink 接受任何大于等于 0 的浮点值,1 为默认值。容器会按照子项的 flex shrink 值加权缩小子项。

  • overflow:决定当实体的子项大小超过其父级时会发生什么。它使用来自 OverflowType 类型。

    • hidden:溢出的实体会变得不可见。

    • visible:溢出的实体会超出父级的边界。

    • scroll:该区域会变为可滚动,允许玩家滚动查看溢出的内容。请参见 可滚动容器 了解详情。

  • flexWrap:flex wrap 属性设置在容器上,用于控制当子项在主轴方向上超过容器大小时会发生什么。默认情况下,如有需要,子项会沿主轴换行成多行。如果使用 nowrap禁用换行,子项会被强制放入单行(这可能会缩小实体)。wrap reverse 的行为与 wrap 相同,但行顺序相反。此属性的值来自 FlexWrapType 类型。

    • wrap

    • nowrap

    • wrap-reverse

外边距和内边距

  • margin:此属性影响节点外侧的间距。带有 margin 的节点会将自身相对于父级边界偏移,同时也会影响任何兄弟节点的位置。若父级采用自动大小,节点的 margin 会计入父级的总大小。用于设置实体与其父级边距之间的空间。预期值是一个包含以下属性的对象: 顶部, 左侧, 底部、以及 右侧.

  • padding:此属性影响其所应用节点的大小。在 Yoga 中,padding 的行为就像设置了 box-sizing: border-box;。也就是说,如果实体已显式设置大小,padding 不会增加实体总大小。对于自动大小的节点,padding 会增加节点大小并偏移任何子项的位置。预期值是一个包含以下属性的对象: 顶部, 左侧, 底部、以及 右侧.

精细调整位置

在 Flexbox 中,实体的位置主要由其父子关系以及父级和子级上设置的排列属性决定。你通常不需要完全设置 位置 属性。但如果你确实想微调它,或完全覆盖 Flexbox 的正常流并设置绝对位置,以下是相关属性:

  • positionType:定义实体如何定位。它使用来自 PositionType 枚举。

    • relative: (默认)默认情况下,实体是相对定位的。这意味着实体会按照布局的正常流进行定位,然后根据 顶部, 右侧, 底部、以及 左侧的值相对于该位置进行偏移。该偏移不会影响任何兄弟实体或父实体的位置。

    • absolute:当绝对定位时,实体不参与正常的布局流。它会独立于其兄弟节点进行布局。其位置由 顶部, 右侧, 底部、以及 左侧 值列表。

  • 位置:位置值 顶部, 右侧, 底部、以及 左侧 的行为会因 positionType而不同。对于相对实体,它们会在指定方向上偏移实体的位置。对于绝对实体,这些属性则指定实体某一侧与父级相同一侧之间的偏移。预期值是一个包含以下属性的对象: 顶部, 左侧, 底部、以及 右侧.

可见性

  • 显示:确定实体是否可见。若要使实体不可见,请设置 显示 为 none.

Z Index

该 zIndex 属性用于 UiEntity 确定实体的渲染顺序。具有更高 zIndex 的实体会渲染在较低 zIndex的实体之上。默认 zIndex 是 0。

可滚动容器

当某个 UI 实体的内容超过其分配大小时,你可以通过设置 overflow 为 scroll 在实体的 uiTransform中将该区域设为可滚动。然后玩家就可以通过拖动或使用鼠标滚轮来滚动内容。

要创建可滚动容器,父实体必须具有固定大小(使用 width 和 height),并且子项必须超过该大小。

这对于构建长列表、库存、聊天记录、排行榜,或任何内容可能增长到超出屏幕显示范围的面板都很有用。

你也可以在其他 UI 布局中嵌套可滚动容器。例如,一个带有固定头部和可滚动主体的对话模态框:

💡 提示:使用 flexGrow: 1 将其设置在可滚动实体上,使其填满父级剩余空间,这样当其他兄弟元素(如头部或底部)大小变化时,它也会随之适配。

响应式 UI 大小

不同屏幕大小的玩家可能会以不同方式看到你的 UI 布局。像素值会相对于 虚拟屏幕 为你进行缩放,因此同一个 UI 会在不同分辨率下保持其比例—— 你不需要自己计算缩放因子,否则会导致缩放执行两次。

UiCanvasInformation,它默认添加到场景的根实体中,仍然是处理缩放无法表达的布局决策的正确工具——例如在窄屏上使用不同的对话布局,从 devicePixelRatio中选择纹理分辨率,或者自行读取内边距区域。它不是用于大小设定的正确工具。

该 UiCanvasInformation 组件保存以下信息:

  • height:画布高度(像素)

  • width:画布宽度(像素)

  • devicePixelRatio:设备物理像素分辨率与画布像素之间的比例。可作为显示密度提示,例如在 1x、2x 或 3x 纹理版本之间进行选择。

  • interactableArea:一个 BorderRect 对象,详细说明场景 UI 元素所分配的区域。该对象包含以下值: 顶部, 底部, 左侧 和 右侧,其中每一项都是屏幕该边缘上被浏览器 UI 占用的像素数。

  • screenInsetArea:一个 BorderRect 对象,详细说明设备或平台 UI 预留的屏幕内边距区域(安全边距),例如移动端的刘海、状态栏、主页指示器或圆角。该对象包含以下值: 顶部, 底部, 左侧 和 右侧,其中每一项都是该屏幕边缘上预留的像素数。在桌面端这通常是 0 四周都如此。

关于 UI 大小的其他最佳实践:

  • 如果任何 UI 元素的宽度或高度是动态的,也最好使用 maxWidth, minWidth, maxHeight、以及 minHeight 参数来确保它们保持在合理范围内。

  • 数字字体大小是一个虚拟像素值,会像其他值一样按比例缩放。如果你希望改为以画布为基准来度量,从而不受虚拟屏幕影响,请传入 vw/vh 字符串——请参见 响应式文本大小

💡 提示:有关 UI 大小设置的工作示例,请参见 81,-2-ui-screen-inset-area 测试场景,它会同时运行全部三个 screenInset 模式('none', 'device', 'interactable')作为三个并存的渲染器,并输出实时 screenInsetArea 和 interactableArea 值,以及 76,-10-UiCanvasInformation,它会在每一帧读取 UiCanvasInformation 以自适应地设置 UI 大小。

最后更新于