Babylon-gui

如何使用babylonGUI

Babylon.js GUI库是您可以用来生成交互式用户界面的扩展。它建立在DynamicTexture之上。

可以在这里找到最新版本:[https](https://github.com/BabylonJS/Babylon.js/tree/master/dist/preview release/gui) : [//github.com/BabylonJS/Babylon.js/tree/master/dist/preview%20release/gui](https://github.com/BabylonJS/Babylon.js/tree/master/dist/preview release/gui)。

源代码可在主要的Babylon.js存储库上找到:https : //github.com/BabylonJS/Babylon.js/tree/master/gui

您可以在这里找到完整的演示:https : //www.babylonjs.com/demos/gui/

请注意,从Babylon.js v3.3开始,还提供3D版本

介绍

Babylon.GUI使用DynamicTexture生成功能齐全且灵活且GPU加速的用户界面。

一 高级动态纹理

首先从Babylon.GUI开始,您需要一个AdvancedDynamicTexture对象。

Babylon.GUI有两种模式:

1.全屏模式

  • 在此模式下,Babylon.GUI将覆盖整个屏幕并重新缩放以始终适应您的渲染分辨率。它还将拦截点击(包括触摸)。要以全屏模式创建AdvancedDynamicTexture,只需运行以下代码:参数为自定义的名称
var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("myUI");

下面是一个简单的全屏模式GUI的例子:https://www.babylonjs-playground.com/#XCPP9Y#1 -

默认情况下,渲染分辨率和纹理大小之间的比率为1。但是您可以使用将其强制为不同的值advancedTexture.renderScale。例如,如果您想要更清晰的文本,这可能会很有用。

前景和背景:全屏模式可以在场景的前景或背景中渲染。可以这样设置:

// true == foreground (default)
// false == background
var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("myUI", foreground? : Boolean );
// it can also be changed on the go:
    advancedTexture.isForeground = false;

请注意,每个场景仅允许一个全屏模式GUI

全屏模式不适用于WebVR,因为它是纯2D渲染。对于WebVR场景,您将必须使用下面的纹理模式。

2.纹理模式

  • 在此模式下,BABYLON.GUI将用作给定网格的纹理。您将必须定义纹理的分辨率。要在纹理模式下创建AdvancedDynamicTexture,只需运行以下代码:
  • 参数一:自定义名称
  • 参数二:宽度
  • 参数三:高度
  • 参数四:是否关闭支持指针移动事件的功能(true,false)
var advancedTexture2 = BABYLON.GUI.AdvancedDynamicTexture.CreateForMesh(
  myPlane,
  1024,
  1024
);

下面是一个简单的纹理模式的GUI的一个示例:https://www.babylonjs-playground.com/#ZI9AK7#1 -

请注意,在复杂的网格物体上处理指针移动事件可能会花费很多,因此您可以使用第四个参数关闭支持指针移动事件的功能:

var advancedTexture2 = BABYLON.GUI.AdvancedDynamicTexture.CreateForMesh(
  myPlane,
  1024,
  1024,
  false
);

一旦有了AdvancedDynamicTexture对象,就可以开始添加控件。

二 调试

从Babylon.js v4.0开始,新的检查器可以通过显示边界信息并让您动态更改属性来帮助调试GUI:https : //doc.babylonjs.com/features/playground_debuglayer#gui-control-actions

三 . 标签

标签事件

请注意,控件必须control.isPointerBlocker = true正确处理所有指针事件。默认情况下,此属性是在显而易见的控件(例如按钮)上设置的,但是,如果要在图像等控件上使用此属性,则必须将其打开。

所有控件都有以下可观察到的内容:

事件注释
onPointerMoveObservable当光标移到控件上方时引发。仅在全屏模式下可用
onPointerEnterObservable当光标进入控件时引发。仅在全屏模式下可用
onPointerOutObservable当光标离开控件时引发。仅在全屏模式下可用
onPointerDownObservable当指针在控件上向下时引发。
onPointerUpObservable当指针在控件上时引发。
onPointerClickObservable单击控件时引发。
onClipboardObservable触发剪贴板事件时引发。

要使用剪贴板事件,他们首先需要通过调用启用registerClipboardEvents的AdvancedDynamicTexture实例,它会注册cutcopypaste事件到画布上。一旦启用,就可以通过ctrl/cmd + c复制,ctrl/cmd + v粘贴和ctrl/cmd + x剪切触发它们,并且它们将始终在画布上收听。如果您有任何其他操作具有相同的键绑定,则可以通过调用来防止默认触发这些事件,这些事件unRegisterClipboardEvents将从画布中注销它们。

这是有关如何使用剪贴板可观察对象的示例:

  • 要创建新的网格:https://playground.babylonjs.com/#S0IW99#1 -
  • 若要从剪贴板中的数据创建新的TextBlocks:https://playground.babylonjs.com/#AY28VL#4 -

您还可以定义控件对事件不可见(例如,您可以单击它)。为此,只需致电control.isHitTestVisible

请注意onPointerMoveObservableonPointerDownObservableonPointerUpObservableonPointerClickObservable会收到一个Vector2参数包含指针坐标。如果要在本地控制空间中获取指针坐标,则必须调用control.getLocalCoordinates(coordinates)

下面是如何使用观测的例子:https://www.babylonjs-playground.com/#XCPP9Y#121 -

下面是如何使用onPointerClickObservable一个例子:https://www.babylonjs-playground.com/#7RH606 -

标签对齐方式

您可以使用以下属性定义控件使用的路线:

属性默认注释
horizontalAlignment2可以设置为left,right或center。
verticalAlignment2可以设置为top, bottom和center。

可以从BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_*BABYLON.GUI.Control.VERTICAL_ALIGNMENT_*上获取值

下面是如何使用路线的例子:https://www.babylonjs-playground.com/#XCPP9Y#13 -

位置和大小

您可以使用以下属性设置控件的位置:

属性类型默认默认单位
leftvalueAndUnit0px
topvalueAndUnit0px

大小可以设置:

属性类型默认默认单位
widthvalueAndUnit100%百分比 使用px加上"10px"
heightvalueAndUnit100%百分比

Padding 可以设置为:

属性类型默认默认单位
paddingTopvalueAndUnit0像素px
paddingBottomvalueAndUnit0像素px
paddingLeftvalueAndUnit0pxpx
paddingRightvalueAndUnit0pxpx

padding 是控件与其父控件或同级控件之间(外部)周围的空间(例如,将box-sizing设置为border-box时的CSS边距)。这意味着usableWidth = width-paddingLeft-paddingRight。与usableHeight = height-paddingTop-paddingBottom相同。

可以使用像素或百分比为单位定义所有这些属性。要将值设置为像素,请使用以下结构:control.left = "50px" 要将值设置为百分比,请使用以下结构:control.left = "50%"

您也无法定义单位(在这种情况下,将使用默认单位):(control.width = 0.5等效于control.width = "50%"

从Babylonjs v4.2开始,您可以使用该fixedRatio属性基于另一个尺寸来计算宽度或高度尺寸。第二维的计算为first dimension x fixedRatio。第一维被确定为您最后设置的维。

myCtrl.width = "40px";
myCtrl.height = "0.2";

第一维是height并且width将按照上面的说明进行计算(因此40px将不使用)。默认情况下,fixedRatio = 0因此未启用。

下面是如何使用的位置和大小的例子:https://www.babylonjs-playground.com/#XCPP9Y#14 -

追踪位置

可以将所有控件移动到跟踪网格的位置。为此,只需调用control.linkWithMesh(mesh)。然后可以使用control.linkOffsetX和偏移位置control.linkOffsetY

下面是一个可跟踪标签的例子:https://www.babylonjs-playground.com/#XCPP9Y#16 -

请注意,要跟踪网格位置的控件必须位于根级别(位于AdvancedDynamicTexture级别)。

您还可以使用将控件移至场景中的特定坐标control.moveToVector3(position)。请注意,如果以后更改矢量,控件将不会停留在该矢量上。

对于线控制,还可以使用将第二点附加到控件line.connectedControl = control。在这种情况下,x2and y2属性用于从连接的控件偏移第二点。

随着这两个选项,你可以创建一个完整的可跟踪标签:https://www.babylonjs-playground.com/#XCPP9Y#20 -

仅当AdvancedDynamicTexture处于全屏模式时,跟踪位置功能才起作用

自适应缩放

在全屏UI中,你可以选择给UI定义一个固定的分辨率。要定义这个分辨率,只需设置myAdvancedDynamicTexture.idealWidth = 600 myAdvancedDynamicTexture.idealHeight = 400.

如果都设置了,将以idealWidth为主(看来改变分辨率后全屏ui仍然是铺满整个视口的,顶层UI的宽高比是视口的宽高比)

在设置了理想分辨率之后,所有用像素表示的值都被认为是相对于这个分辨率的,并且会依此调整来适应当前的分辨率。(也就是比例不变?)

即使设定了理想尺寸,全屏UI仍会按照你的canvas的大小来绘制,但是你也可以决定强制纹理使用这个理想的尺寸作为分辨率(主要是为了性能)。要做到这一点,只需设置myAdvancedDynamicTexture.renderAtIdealSize = true.

为了同时使用IdealWidth和IdealHeight,请同时设置它们和set myAdvancedDynamicTexture.useSmallestIdeal = true。当窗口宽度小于窗口高度时-将使用IdealWidth,否则-将使用IdealHeight。当您可以将画布的大小调整为不同的宽高比时,这是一个很好的解决方案。

下面是如何使用水平自适应缩放的示例:https://www.babylonjs-playground.com/#XCPP9Y#39 -

旋转和缩放

控件可以使用以下属性进行转换:

PropertyTypeDefaultComments
rotationnumber0弧度值
scaleXnumber1
scaleYnumber1
transformCenterXnumber0.5定义X方向变形中心的位置,取值在0到1之间。(以这个点为轴旋转)
transformCenterYnumber0.5定义Y轴上的变换中心。值介于0和1之间

**请注意,转换是在渲染级别完成的,因此在进行所有计算之后。**这意味着将首先进行对齐或定位,而无需考虑变换。

下面是如何使用旋转和缩放的例子:https://www.babylonjs-playground.com/#XCPP9Y#22 -

四 控件标签

  • 被控制对象是UI的一片区域的抽象。有两种被控制对象:
    • 纯粹的被控制对象:纯粹的被控制对象定义一个对用户有用的行为或者信息。它可能是一个文本框或者一个按钮。
    • 容器:容器被用来组织你的UI,它们可以包含其他的被控制对象或者容器。

所有控件共享以下属性:

PropertyTypeDefaultComments
alphanumber1在0和1之间,0意为着完全的透明,1意味着完全的不透明
colorstringBlack前景颜色
fontFamilystringArial字体可以是继承的。这意味着如果你在一个容器上设置了它,它将被传递到这个容器的所有子元素上。
fontStylestringEmpty string字形可以被继承。取值可以是“细斜体”、“粗体”或者“斜体”
fontSizenumber18字号可以被继承
zIndexnumber0可以被用来在z轴上对被管对象进行排序

控件可以直接添加到AdvancedDynamicTexture或具有以下内容的容器中:

container.addControl(control);

可以使用以下方法删除它们:

container.removeControl(control);
  • 您还可以使用来控制控件的可见性control.isVisible = false。如果isVisible为true,则所有孩子也将不可见。

  • 如果您只想隐藏当前控件但保持其子控件可见,则可以使用control.notRenderable = true

1. 文本块(TextBlock)

将TextBlock是用于显示文本的简单控件:https://www.babylonjs-playground.com/#XCPP9Y#2 -

   // GUI创建textBlock
    var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");

    var text1 = new BABYLON.GUI.TextBlock();
    text1.text = "Hello world";    //内容
    text1.color = "white";
    text1.fontSize = 24;
    advancedTexture.addControl(text1);    

您可以定义以下属性:

属性类型注释
lineSpacing(0px)valueAndUnit可以设置配置文本行之间的垂直间距
text(null)string显示的文字
textWrapping (false)布尔值可以设置为true以启用文本环绕。
resizeToFit (false)布尔值可以设置为true以启用调整大小以适合。
textHorizontalAlignment (2)number可以设置为left,right或center
textVerticalAlignment(2)number可以设置为top,bottom或center
outlineWidth(0)number文字轮廓大小,以像素为单位。
outlineColor(“white”)string文字轮廓颜色。
wordSplittingFunctionstring用于将文本拆分为单词的函数

该控件当前提供1个可观察到的:

可观察的注释
onTextChangedObservable文字更改时引发

请注意,让你必须确保你的渲染分辨率与屏幕对准脆文本: https://www.babylonjs-playground.com/#2ARI2W#10 -

**强制引擎获取与屏幕相同的DPI: engine.setHardwareScalingLevel(1 / window.devicePixelRatio); **

缩放GUI以与屏幕分辨率对齐: advancedTexture.rootContainer.scaleX = window.devicePixelRatio;

											**advancedTexture.rootContainer.scaleY = window.devicePixelRatio;**

在自动换行模式下,文本在显示之前被拆分为单词,并且单词应至少由一个空格字符分隔。但是,在某些语言中,将文本分解为单词应遵循其他一些规则。

对于这些语言,您可以使用wordSplittingFunction属性提供自己的拆分功能:此功能将字符串作为输入,并且必须返回字符串数组(将输入字符串分解为单词)。

这是日语的示例:https : //jsfiddle.net/3ph9m0cx/

1.1 行间距

您可以配置像素之间的垂直行间距(以像素或百分比值表示)。

lineSpacing应该在textWrapping设置为true的情况下使用。

你可以在这里尝试:https://www.babylonjs-playground.com/#44KYLP -

1.2 适应性尺寸调整

当适应性尺寸调整被设为true时,被渲染的文字的宽度和高度将被自动的计算,然后应用到文本框上(也就是字的大小不变,改变文本框的大小)

这个属性允许你改变文本框的文字和字体,而不必担心人工的设置文本框预计渲染的宽度和高度

注意当适应性尺寸调整被设为真时,文字换行将被忽略。同时使用这两个属性在逻辑上没有意义,因为它们相互矛盾。

2. 文本输入框(inputText)

该inputText的是用来让用户插入的文本在一个单一的线的控制:https://www.babylonjs-playground.com/#UWS0TS -

   // GUI
        var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");
    
        var input = new BABYLON.GUI.InputText();
        input.width = 0.2;
        input.maxWidth = 0.2;
        input.height = "40px";
        input.text = "This is a very long text used to test how the cursor works within the InputText control.";
        input.color = "white";
        input.background = "green";
        advancedTexture.addControl(input);    

您可以定义以下属性:

属性(默认)类型注释
text (null)string显示文字
color (white)string前景色
background (black)string背景颜色
focusedBackground (black)string控件集中时使用的背景色
autoStretchWidth (true)布尔值控件将水平调整大小以适应文本大小
maxWidth(100%)valueAndUnit如果autoStretchWidth设置为true,则允许的最大宽度
margin (10px)valueAndUnit在控件本身内部左右使用的边距。此边距用于确定要在何处绘制文本
thickness (1)number边框厚度
highligherOpacity (0.4)number定义突出显示的文本背景的透明度
textHighlightColor(#D5E0FF)string高亮文本的背景颜色
onFocusSelectAll(false)布尔值输入为焦点时,默认情况下允许完全选择文本。

InputText是可聚焦的控件。这意味着您可以单击/触摸它以使其具有焦点并控制键盘事件。您可以通过按Enter或在控件外部单击来从控件中删除焦点。

该控件提供了一些监听器来跟踪其状态:

Observables注释
onTextChangedObservable文字更改时引发
onBeforeKeyAddObservable在将输入的密钥添加到文本之前引发
onFocusObservable当控件获得焦点时引发
onBlurObservable当控件失去焦点时引发
onTextHighlightObservable突出显示文本时引发
onTextCopyObservable在触发复制事件时引发
onTextCutObservable触发剪切事件时引发
onTextPasteObservable触发粘贴事件时引发
onKeyboardEventProcessedObservable在处理关键事件时引发

请注意,InputText具有非常有限的版本支持。以下是受支持的密钥:

  • Delete
  • Backspace
  • Home
  • End
  • Enter
  • Left / Right (used to move the cursor)

此外,请注意,由于JavaScript平台的限制,InputText无法调用屏幕键盘。在移动设备上,InputText将使用prompt()命令获取用户输入。你可以定义prompt``命令的标题,通过设置control.promptMessage.

2.1 扩展键盘布局和输入掩码

onBeforeKeyAddObservable观察对象可用于扩展或更改InputText控件接受文本的方式。例如,可以使用此功能实现对不同键盘布局的支持,其中某些键充当下一个输入键的修饰符,或者您可以实现仅接受数字键的输入掩码。

在将可打印键添加到控件中的文本之前,触发了observable。然后,附加的处理程序可以使用以下方法来获取有关键盘状态的信息并修改控件中键的处理方式:

方法描述
currentKey将附加到文本的密钥
addKey如果为true,则currentKey中的键将添加到文本中,否则将被跳过
死键如果用户按下键盘上的死键,则设置为true。处理程序必须重置为false

例如,如果处理程序希望将控件限制为仅接受数字键,则如果currentKey的值不是数字,则可以将addKey设置为false。密钥将不会被添加到文本中。类似地,可以通过检查deadKey标志并将currentKey设置为适用于死键+组合键的适当字符来实现死键支持。

请注意,observable仅由可打印键(即可以添加到文本中的键)触发,而不是由退格键和Enter键等控制键触发。

下面是示出两个输入,一个只接受数字键和一个具有简单死键支持的示例:https://www.babylonjs-playground.com/#I1Y5YT#1 -

inputText的还支持clipboardObservables,这里有一个例子:https://www.babylonjs-playground.com/#UWS0TS#20 -

2.2 输入密码

控件inputPassword是控制,显示输入的字符作为子弹,并因此适合用于输入密码: https://www.babylonjs-playground.com/#UB58DY -

否则,它的行为与InputText控件相同,并具有如上所述的相同属性。

没有特定于此控件的可用配置选项。例如,不可能显示输入的纯文本。

3. 按钮button

可以使用一个按钮与您的用户进行交互。以了解如何将事件与按钮连接起来。单击按钮时会引发onPointerClickObservable,这意味着向下和向上事件都在光标悬停在控件上时发生。

开箱即用的按钮共有三种:

  • ImageButton:图像按钮是由图像(在前)和文本组成的按钮。您可以使用以下方法创建一个:
  • 参数一:自定义名称
  • 参数二:按钮内的文本内容
  • 参数三:引入的图片的路径
var button = BABYLON.GUI.Button.CreateImageButton(
  "but",                    
  "Click Me",
  "textures/grass.png"
);

你可以在这里尝试:https://www.babylonjs-playground.com/#XCPP9Y#3 -

  • ImageWithCenterTextButton:具有图像背景和居中文字叠加层的图像按钮。(图像为背景)
var button = BABYLON.GUI.Button.CreateImageWithCenterTextButton(
  "but",
  "Click Me",
  "textures/grass.png"
);

你可以在这里尝试:https://www.babylonjs-playground.com/#PLTRBV -

  • SimpleButton:仅包含文本的简单按钮
var button = BABYLON.GUI.Button.CreateSimpleButton("but", "Click Me");

你可以在这里尝试:https://www.babylonjs-playground.com/#XCPP9Y#4 -

  • ImageOnlyButton:
var button = BABYLON.GUI.Button.CreateImageOnlyButton(
  "but",
  "textures/grass.png"
);

你可以在这里尝试:https://www.babylonjs-playground.com/#XCPP9Y#28 -

另请注意,默认情况下,按钮将根据其边界信息处理点击测试。如果您希望使用嵌入式控件来处理拣货,可以调用button.delegatePickingToChildren = true

3.1获取按钮内容

您可以使用以下属性来获取按钮的各个部分(如果有):

  • image:返回按钮的图像部分(如果有)
  • textBlock:返回按钮的文本相关属性
3.2 可视动画 Visual animations

默认情况下,按钮将更改其对pointerOver的不透明度,并在单击时更改其比例。您可以使用以下回调定义自己的动画:

  • pointerEnterAnimation
  • pointerOutAnimation
  • pointerDownAnimation
  • pointerUpAnimation
3.3 自定义按钮

BABYLON.GUI.Button.CreateMyCustomButton

你也可以通过手动的为按钮添加子元素来建立一个完全自定义的按钮。以下是如何构建图片按钮:

BABYLON.GUI.Button.CreateMyCustomButton = function(name, text, imageUrl) {
  var result = new BABYLON.GUI.Button(name);

  // Adding text
  var textBlock = new BABYLON.GUI.TextBlock(name + "_button", text);
  textBlock.textWrapping = true;
  textBlock.textHorizontalAlignment =
    BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER;
  textBlock.paddingLeft = "20%";
  result.addControl(textBlock);

  // Adding image
  var iconImage = new BABYLON.GUI.Image(name + "_icon", imageUrl);
  iconImage.width = "20%";
  iconImage.stretch = BABYLON.GUI.Image.STRETCH_UNIFORM;
  iconImage.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
  result.addControl(iconImage);

  return result;
};

4. 复选框

该复选框用于控制布尔值。您可以使用指定值checkbox.isChecked

更改isChecked属性将引发一个可观察到的checkbox.onIsCheckedChangedObservable

var checkbox = new BABYLON.GUI.Checkbox();
    checkbox.width = "20px";
    checkbox.height = "20px";
    checkbox.isChecked = true;
    checkbox.color = "green";
    checkbox.onIsCheckedChangedObservable.add(function(value) {
       //事件执行逻辑处理
    });

该控件使用以下属性呈现:

属性类型默认注释
colorstring白色前景色
backgroundstring黑色背景颜色
checkSizeRationumber0.8定义用于计算内部复选框大小的比率(默认为0.8,这意味着内部检查大小等于控件本身的80%)

这里是一个复选框的例子:https://www.babylonjs-playground.com/#U9AC0N#2 -

5. 单选按钮

单选按钮用于通过使用一组只能为真的单选按钮来定义列表中的值。您可以使用指定的值radiobutton.isChecked

更改isChecked属性将触发一个叫做checkbox.onIsCheckedChangedObservable的事件,此外,如果选择单选按钮,则同一组中的所有其他单选按钮将变为false。

    var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI();//创建全屏纹理
    var addRadio = function(text, parent) {
        var button = new BABYLON.GUI.RadioButton();
        button.width = "20px";
        button.height = "20px";
        button.color = "white";
        button.background = "green";     
        button.onIsCheckedChangedObservable.add(function(state) {
            if (state) {
              // 选中执行逻辑
            }
        }); 
        var header = BABYLON.GUI.Control.AddHeader(button, text, "100px", { isHorizontal: true, controlFirst: true });
        header.height = "30px";

        parent.addControl(header);    
    }


    addRadio("option 1", panel);
    addRadio("option 2", panel);
;

该控件使用以下属性呈现:

属性类型默认注释
colorstring白色前景色
backgroundstring黑色背景颜色
checkSizeRationumber0.8定义用于计算内部复选框大小的比率(默认为0.8,这意味着内部检查大小等于控件本身的80%)
groupstring空字符串使用group属性收集工作在相同值集上的单选按钮

这里是一个单选按钮的例子:https://www.babylonjs-playground.com/#U9AC0N#13 -

6. 滑块Slider

滑块用来在一个范围内控制一个值。你可以使用slider.minimumslider.maximum``来指定这个范围

这个值本身使用slider.value指定,并且将在它每次改变时触发一个事件(slider.onValueChangedObservable)

该控件使用以下属性呈现:

属性类型默认注释
borderColorstringwhite用于渲染拇指边框的颜色
colorstringwhite前景色
backgroundstringblack背景颜色
barOffsetvalueAndUnit5px垂直用于绘制背景栏的偏移量
thumbWidthvalueAndUnit30px拇指宽度
displayThumb布尔值true指示是否必须渲染拇指(用于模拟进度条)
isThumbCircle布尔值false指示拇指是否应为圆(如果为假则为正方形)
isThumbClamped布尔值false指示是否应夹紧拇指
isVertical布尔值false指示滑块将垂直呈现,而不是水平呈现
stepnumber0指示焊点值所需的精度等级(0表示全精度,其中0.01表示2位数精度)

使用垂直滑块时,必须确保高度大于宽度。使用时,相反的情况必须成立isVertical = false

 		//panel是一个父级盒子,滑块和滑块的值都在这个盒子中添加
 		var panel = new BABYLON.GUI.StackPanel();
				    panel.width = "200px";
				    panel.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_RIGHT;
				    panel.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER;
				    advancedTexture.addControl(panel);
				 //header是一个文本块,显示滑块的值
				    var header = new BABYLON.GUI.TextBlock();
				    header.text = "Y-rotation: 0 deg";
				    header.height = "30px";
				    header.color = "white";
				    panel.addControl(header); 
				 //滑块
				    var slider = new BABYLON.GUI.Slider();
				    slider.minimum = 0;              //滑块的最小值
				    slider.maximum = 2 * Math.PI;     //滑块的最大值
				    slider.value = 0;
				    slider.height = "20px";
				    slider.width = "200px";
				    slider.onValueChangedObservable.add(function(value) {    //滑块改变事件
				        header.text = "Y-rotation: " + (BABYLON.Tools.ToDegrees(value) | 0) + " deg";
				       
				    });
				    panel.addControl(slider);    

下面是一个滑块的一个例子:https://www.babylonjs-playground.com/#U9AC0N#1 -

6.1 基于图像的滑块

您可以使用ImageBasedSlider使用图片来自定义滑块。可以像滑动条一样配置此控件)

使用以下属性呈现它:

属性类型默认注释
backgroundImagestringnull用作背景的图像的路径
valueBarImagestringnull用于值栏的图像的路径
thumbImagestringnull拇指使用的图像路径
barOffsetvalueAndUnit5像素垂直用于绘制背景栏的偏移量
thumbWidthvalueAndUnit30像素拇指宽度
displayThumb布尔值true指示是否必须渲染拇指(用于模拟进度条)
isThumbClamped布尔值false指示是否应夹紧拇指
isVertical布尔值false指示滑块将垂直呈现,而不是水平呈现

这里是一个滑块和基于图像的滑块的一个例子:https://www.babylonjs-playground.com/#HATGQZ -

7. Line 线段

该线将在两点之间绘制一条线(!!)。

    // GUI
    //创建全屏模式显示纹理
    var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");
	//虚线
    var line = new BABYLON.GUI.Line();
    line.x1 = 10;
    line.y1 = 10;
    line.x2 = 1000;
    line.y2 = 500;
    line.lineWidth = 5;
    line.dash = [5, 10];
    line.color = "white";
    advancedTexture.addControl(line);    
 	//实线
    var line2 = new BABYLON.GUI.Line();
    line2.x1 = 10;
    line2.y1 = 1000;
    line2.x2 = 1000;
    line2.y2 = 500;
    line2.lineWidth = 2;
    line2.color = "white";
    advancedTexture.addControl(line2);       

您可以定义以下属性:

属性类型默认注释
x1number0第一点的X坐标
y1number0第一点的Y坐标
x2number0第二点的X坐标
y2number0第二点的Y坐标
dash数字数组 array of numbers空数组定义虚线的尺寸
lineWidthnumber1像素宽度

下面是一个行的一个示例:https://www.babylonjs-playground.com/#XCPP9Y#6 -

8. 多线 MultiLine

MultiLine将在任意数量的网格,控件和点之间绘制线。

MultiLine中的每个项目都称为MultiLinePoint,并且具有以下属性:

属性类型默认注释
mesh抽象网 AbstractMeshnull跟踪网格
control控制 Controlnull跟踪控件
Xnumbernull点的x,可以以px或%指定
ynumbernull点的y,可以以px或%指定

您可以使用以下功能:

  • add():接收任意数量的参数并将其相加,每个参数可以是网格,控件或点。返回MultiLinePoint的数组
  • push():接收1个参数并将其添加,每个参数可以是网格,控件或点。返回一个MultiLinePoint
  • remove():获取MultiLinePoint的索引或实例并将其删除
  • getAt():获取MultiLinePoint的索引并返回其实例。如果该索引中不存在MultiLinePoint,则会创建一个新的

您可以在MultiLine中定义以下属性:

属性类型默认注释
dash数字数组空数组定义破折号的大小 就是每条虚线组成线段的长度
lineWidthnumber1像素宽度 px

这里是一个多行组合的网格,一个控制和点的例子:https://www.babylonjs-playground.com/#H03KNW#2 -

9. 图片 Image

  var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");

    var image = new BABYLON.GUI.Image("but", "textures/grass.png");
    image.width = 0.2;
    image.height = "40px";
    advancedTexture.addControl(image);    

使用图像被控对象在你的UI里显示一张图片。你可以使用image.stretch属性控制这个图片使用的拉伸方式。你可以把它设置为这些值中的一个

  • 使用原始尺寸: BABYLON.GUI.Image.STRETCH_NONE:Use original size

  • 缩放图片来填满容器(默认值) BABYLON.GUI.Image.STRETCH_FILL: Scale the image to fill the container

  • 缩放图片填满容器,但是保持宽高比 BABYLON.GUI.Image.STRETCH_UNIFORM: Scale the image to fill the container but maintain aspect ratio

  • 缩放容器以适应图像大小 BABYLON.GUI.Image.STRETCH_EXTEND: Scale the container to adapt to the image size.

你可能希望让图片被管对象按照源图片调整尺寸。要做到这一点只需调用image.autoScale = true.

你可以随时修改图片源通过image.source="myimage.jpg".

你也可以使用以下属性定义你要使用源图片的哪个部分:

  • sourceLeft:源图像中的x坐标(以像素为单位)
  • sourceTop:源图像中的y坐标(以像素为单位)
  • sourceWidth:您要使用的源图像的宽度(以像素为单位)
  • sourceHeight:要使用的源图像的高度(以像素为单位)

下面是一个图像的一个例子:https://www.babylonjs-playground.com/#XCPP9Y#7 -

您可以使用属性使用动画页上的图像中image.cellIdimage.cellWidthimage.cellHeight。https://www.babylonjs-playground.com/#K60448#10 -

您也可以使用image.stretch属性将拉伸应用于动画表。

实施例1 -

实施例2 -

从babylon.js v4.0开始,您还可以设置img.detectPointerOnOpaqueOnly = true指示是否仅在alpha> 0的像素上验证指针。

9.1图标表批量加载SVG

您可以从一个SVG图标工作表中加载多个SVG图标,而无需为每个图像手动定义多个sourceLeft,sourceTop,sourceWidth,sourceHeight属性。

前提条件:有效的单层SVG文档,其宽度,高度,定义的视图框以及通过ID分组的图标。该图层不应具有任何变换属性。

onSVGAttributesComputedObservable将在自动计算sourceLeft,sourceTop,sourceWidth,sourceHeight属性时触发。您可以创建由多个SVG资产(发光,文本,图像等)构建的自定义SVG按钮,以获得更简洁的代码。

下面是一个使用SVG图像和按钮资产的例子:https://playground.babylonjs.com/#E5CARD -

已知问题:批量加载过程需要将整个SVG图标表作为HTMLObjectElement加载到DOM中。在某些浏览器上,随着资产加载,您可能会注意到画布上的图标表快速闪烁。为了减轻这种情况,您可以使用加载屏幕

10. 拾色器

拾色器控件允许用户在场景中设置颜色。

每当用户与颜色选择器交互时,都会触发一个(observable)(colorPicker.onValueChangedObservable),它返回颜色选择器的当前值(Color3)。

var picker = new BABYLON.GUI.ColorPicker();
    picker.value = skullMaterial.diffuseColor;
    picker.height = "150px";
    picker.width = "150px";
    picker.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER;
    picker.onValueChangedObservable.add(function(value) { // value 是一个color3的对象
        skullMaterial.diffuseColor.copyFrom(value);
    });
    panel.addControl(picker);     

该控件使用以下属性呈现:

属性类型默认注释
size字符串或数字“ 200px”size,width和height属性将始终是相同的值,因为颜色选择器只能是正方形。

下面是一个颜色选择器的一个例子:https://www.babylonjs-playground.com/#91I2RE#1 -

11. 显示网格

显示网格控件是用于在GUI内部显示网格的简单控件。

  var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");

    var displayGrid = new BABYLON.GUI.DisplayGrid();
    displayGrid.width = "500px";
    displayGrid.height = "500px";
    advancedTexture.addControl(displayGrid);    

该控件使用以下属性呈现:

属性类型默认注释
backgroundstring“Black”定义网格背景的颜色
cellWidthnumber20定义每个单元的宽度
cellHeightnumber20定义每个单元格的高度
minorLineTicknessnumber1个定义细线的滴答声
minorLineColorstring“DarkGray”定义次要线条的颜色
majorLineTicknessnumber2定义主要线条的滴答声
majorLineColorstring“White”定义主要线条的颜色
majorLineFrequencynumber5定义主线的频率

这里是一个显示网格的示例:https://www.babylonjs-playground.com/#747U9T -

12. 虚拟键盘 VirtualKeyboard

VirtualKeyboard是用于显示简单的屏幕键盘的控件。对于用户无法轻松使用其键盘的WebVR场景,

 var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");

 var input = new BABYLON.GUI.InputText();
 input.width = 0.2;
 input.maxWidth = 0.2;
 input.height = "40px";
 input.text = "单机显示键盘";
 input.color = "white";
 input.background = "green";
 advancedTexture.addControl(input);  

     
 var keyboard = BABYLON.GUI.VirtualKeyboard.CreateDefaultLayout();
 keyboard.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_BOTTOM;
 advancedTexture.addControl(keyboard);
//绑到input上
keyboard.connect(input);
12.1 按键

您可以使用以下代码定义键盘提供的键:

var keyboard = new BABYLON.GUI.VirtualKeyboard();
keyboard.addKeysRow([
  "1",
  "2",
  "3",
  "4",
  "5",
  "6",
  "7",
  "8",
  "9",
  "0",
  "\u2190"
]);

将使用以下属性指定的默认值创建每个键:

属性默认
defaultButtonWidth40像素
defaultButtonHeight40像素
defaultButtonPaddingLeft2像素
defaultButtonPaddingRight2像素
defaultButtonPaddingTop2像素
defaultButtonPaddingBottom2像素
defaultButtonColor#DDD
defaultButtonBackground#070707

您还可以通过提供一个包含键属性(或null)的数组来覆盖每个属性:

addKeysRow(["a", "b"], [null, { width: "200px" }]);

您可以基于以下类定义每个默认属性:

class KeyPropertySet {
      width?: string;
      height?: string;
      paddingLeft?: string;
      paddingRight?: string;
      paddingTop?: string;
      paddingBottom?: string;
      color?: string;
      background?: string;
  }
12.2 版面,布局

VirtualKeyboard提供了一种静态方法来创建默认布局:

var keyboard = BABYLON.GUI.VirtualKeyboard.CreateDefaultLayout();

默认布局等效于:

addKeysRow(["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "\u2190"]);
addKeysRow(["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"]);
addKeysRow(["a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "\u21B5"]);
addKeysRow(["\u21E7", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/"]);
addKeysRow([" "], [{ width: "200px" }]);
12.3 VirtualKeyboard活动

每次按下一个键,onKeyPressObservable就会触发观察。但是您也可以依靠keyboard.connect(inputText)自动将VirtualKeyboard连接到InputText。在这种情况下,只有当InputText成为焦点并且所有按键事件都将发送到InputText时,键盘才会出现。

你可以在这里找到一个完整的演示:https://www.babylonjs-playground.com/#S7L7FE -

13. Containers 容器

容器是用于承载其他控件的控件。使用它们来组织您的UI。容器具有一项特定属性:container.background。用它来定义容器的背景色。

默认情况下,容器不阻止鼠标事件(即使指针在容器上方,基础场景也将接收指针事件)。可以通过调用来防止此行为container.isPointerBlocker = true

容器负责管理孩子的布局。为防止布局循环,系统不会在一个周期内将布局更新超过3次。可以使用更改此值container.maxLayoutCycle。您也可以在使用检测到布局周期时打开控制台警告container.logLayoutCycleErrors = true

 var rect1 = new BABYLON.GUI.Rectangle(); //創建Containers 容器
    rect1.width = 0.2;
    rect1.height = "40px";
    rect1.cornerRadius = 20;
    rect1.color = "Orange";
    rect1.thickness = 4;            //边框宽度
    rect1.background = "green";

13.1 适应尺寸

您可以决定使用以下属性之一使容器适应其子代的大小:

  • AdaptWidthToChildren(默认为false)
  • AdaptHeightToChildren(默认为false)

如果将这些属性之一设置为true,则将根据直接子级尺寸计算关联的尺寸(宽度,高度或两者),只要以像素为单位定义(尺寸不能以百分比定义,因为这会产生无限循环)因为父级需要子级的大小),你可以在这里找到一个演示:https://www.babylonjs-playground.com/#GL5SIM -

13.2剪裁

默认情况下,容器会将其子代限制在边界范围内。您可以通过调用以下代码来禁用此选项:

container.clipChildren = false;

请注意,不修剪孩子可能会产生问题,adt.useInvalidateRectOptimization因此如果要使用未修剪孩子,建议关闭此优化。

你可以在这里找到一个演示:https://www.babylonjs-playground.com/#LBF8S2 -

13.3长方形

矩形是具有以下属性的矩形容器:

    // GUI
    var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");

    var rect1 = new BABYLON.GUI.Rectangle();
    rect1.width = 0.2;
    rect1.height = "40px";
    rect1.cornerRadius = 20;
    rect1.color = "red";
    rect1.thickness = 4;
    rect1.background = "green";
    advancedTexture.addControl(rect1);    
属性类型默认注释
thicknessnumber1边框厚度
cornerRadiusnumber0每个角的大小(以像素为单位)。用于创建圆角矩形

这里是一个矩形控制的一个例子:https://www.babylonjs-playground.com/#XCPP9Y#8 -

13.4 椭圆

椭圆是具有以下特性的椭圆形容器:

 // GUI
    var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");

    var ellipse1 = new BABYLON.GUI.Ellipse();
    ellipse1.width = "100px"
    ellipse1.height = "100px";
    ellipse1.color = "Orange";
    ellipse1.thickness = 4;
    ellipse1.background = "green";
    advancedTexture.addControl(ellipse1);    
属性类型默认注释
thicknessnumber1边框厚度

下面是一个椭圆形控制的一个例子:https://www.babylonjs-playground.com/#XCPP9Y#10 -

13.5 StackPanel 堆栈面板

StackPanel是一个控件,它根据其方向(可以是水平或垂直)来堆叠其子级。所有子代必须具有定义的宽度或高度(取决于方向),以像素为单位(如果不正确,则会向控制台写入警告。可以使用来关闭此警告panel.ignoreLayoutWarnings = true)。

StackPanel的高度(或宽度)是根据子代自动定义的。

 // GUI
    var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");

    var panel = new BABYLON.GUI.StackPanel();    
    advancedTexture.addControl(panel);   

    var button = BABYLON.GUI.Button.CreateSimpleButton("but", "Click Me");
    button.width = 0.2;
    button.height = "40px";
    button.color = "white";
    button.background = "green";
    panel.addControl(button);     

    var button2 = BABYLON.GUI.Button.CreateSimpleButton("but2", "Click Me also!");
    button2.width = 0.2;
    button2.height = "40px";
    button2.color = "white";
    button2.background = "green";
    panel.addControl(button2);             
属性类型默认注释
isVertical布尔值true面板方向

这里是一个StackPanel的一个例子:https://www.babylonjs-playground.com/#XCPP9Y#11 -

13.6 滚动查看器

由于具有丰富的功能集,ScrollViewer 在此处具有自己的专用页面。

13.7 格

网格是一个控件,它定义一组行和列,并允许子级指定他们要属于哪个单元格:

var grid = new BABYLON.GUI.Grid();
grid.addColumnDefinition(100, true);
grid.addColumnDefinition(0.5);
grid.addColumnDefinition(0.5);
grid.addColumnDefinition(100, true);
grid.addRowDefinition(0.5);
grid.addRowDefinition(0.5);

// This rect will be on first row and second column
var rect = new BABYLON.GUI.Rectangle();
rect.background = "green";
rect.thickness = 0;
grid.addControl(rect, 0, 1);

// This rect will be on second row and third column
rect = new BABYLON.GUI.Rectangle();
rect.background = "red";
rect.thickness = 0;
grid.addControl(rect, 1, 2);

您可以使用以下功能定义行和列:

  • addColumnDefinition(width,isPixel):使用此函数创建一个新列。如果isPixel为false(则为百分比模式),则宽度可以在0到1之间;如果isPixel为true,则宽度可以包含实际宽度。
  • addRowDefinition(height,isPixel):使用此函数创建一个新行。如果isPixel为false(则为百分比模式),则高度可以在0到1之间;如果isPixel为true,则可以包含实际宽度。

这是一个由4列组成的网格的示例,其中第一个和最后一个将具有50px的宽度,第二个和第三个将分别具有剩余空间的50%:

grid.addColumnDefinition(100, true);
grid.addColumnDefinition(0.5);
grid.addColumnDefinition(0.5);
grid.addColumnDefinition(100, true);

您可以使用以下功能更新或删除列和行:

  • setRowDefinition(index,height,isPixel):更新行定义
  • setColumnDefinition(index,width,isPixel):更新列定义
  • removeRowDefinition(index):删除指定索引处的行定义
  • removeColumnDefinition(index):删除指定索引处的列定义

两个属性还可以帮助您获取行数和列数:

  • rowCount:会给你行数
  • columnCount:将为您提供列数

要在网格中添加控件,必须指定行索引和列索引:

grid.addControl(control, 1, 2); // 2nd row, thrid column

您可以通过调用以下命令获取特定单元格中的控件列表:

var controls = grid.getChildrenAt(2, 3);

这里是一个网格的例子:https://www.babylonjs-playground.com/#KX33X8#1 -

14 style样式

从Babylon.js v3.3开始,您可以创建一个样式对象,该对象将用于在控件之间共享配置。为此,您可以使用以下代码:

var style = advancedTexture.createStyle();
style.fontSize = 24;
style.fontStyle = "italic";
style.fontFamily = "Verdana";

然后影响到控件的样式:

textControl.style = style;

这是到目前为止样式支持的属性lsit:

  • 字体大小
  • 字体样式
  • 字体系列
  • fontWeight

请注意,如果控件具有样式,则使用样式值,而不是直接在控件本身上定义的值。

你可以在这里找到一个演示:https://www.babylonjs-playground.com/#5N4JIS -

15. 快速搭建内置方法

为了减少完成频繁任务所需的代码量,您可以使用以下助手:

  • BABYLON.GUI.Control.AddHeader(control, text, size, options { isHorizontal, controlFirst }):此函数将创建一个StackPanel(基于选项的水平或垂直),并在其中添加控件和一个TextBlock。选项还可以用于指定控件是否在标头之后插入。根据方向,大小将指定用于文本块的宽度或高度。
  • BABYLON.GUI.Checkbox.AddCheckBoxWithHeader(title, onValueChanged):此函数将创建一个水平StackPanel,并将在显示该title属性的文本块旁边添加一个复选框。onValueChanged定义复选框状态更改时要调用的回调。
  • BABYLON.GUI.RadioButton.AddRadioButtonWithHeader(title, group, isChecked, onValueChanged):此函数将创建一个水平StackPanel,并将在显示该title属性的文本块旁边添加一个单选按钮(使用指定的组和isChecked参数设置)。onValueChanged定义单选按钮状态更改时要调用的回调。

GUI和后处理

图层蒙版

为了不将后处理应用于GUI,您将必须使用多摄像机方法:一种用于主场景,另一种用于GUI。

你可以在这里找到一个实现的例子:https://www.babylonjs-playground.com/#U9AC0N#58 -

关键是使用camera.layerMask属性隔离您的GUI:

var camera2 = new BABYLON.ArcRotateCamera(
  "Camera",
  0,
  0.8,
  100,
  BABYLON.Vector3.Zero(),
  scene
);
camera2.layerMask = 2;

// GUI - simply set advancedTexture layerMask to 2
var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI(
  "UI"
);
advancedTexture.layer.layerMask = 2;

然后,您的主场景的所有网格物体都会有一个附加到主摄像机的不同图层蒙版:

var camera1 = new BABYLON.ArcRotateCamera(
  "Camera",
  0,
  0.8,
  100,
  BABYLON.Vector3.Zero(),
  scene
);
camera1.layerMask = 1;

myMesh.layerMask = 1;

多场景

另一个选择是使用具有定义如下所示的renderloop的多场景方法:

guiScene.autoClear = false;
engine.runRenderLoop(function() {
  mainScene.render();
  guiScene.render();
});

在这种情况下,guiScene它将托管您的GUI,mainScene并将托管您的场景及其后处理。

GUI和HighDPI显示

如果在高dpi(或“视网膜”)设备(例如许多移动设备或某些笔记本电脑)上查看场景,则可能会注意到UI上的文本显示为“模糊”或“像素化”。这是因为从Babylon.js v2.6开始,该引擎不再默认适应设备像素比率。出于性能原因,此操作是在移动设备上完成的;启用它会对性能产生很大影响。为了改善文本的呈现效果(以性能为代价),adaptToDeviceRatio在构建引擎时需要启用该选项。

请参阅“关闭/打开AdaptToDeviceRatio”以了解更多有关权衡的信息。

进一步阅读

如何使用选择面板帮助器
如何使用巴比伦GUI滚动查看器 如何使用巴比伦GUI Xml加载程序
如何使用巴比伦GUI3D

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐