The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.
The latest version can be found here: https://github.com/BabylonJS/Babylon.js/tree/master/dist/preview%20release/gui.
And the source code is available on the main Babylon.js repo: https://github.com/BabylonJS/Babylon.js/tree/master/gui.
You can find a complete demo here: http://www.babylonjs.com/demos/gui/
Babylon.GUI uses a DynamicTexture to generate a fully functionnal user interface. It is an alternative to Canvas2D.
The main difference is that Canvas2D is full GPU oriented (text constructrion, animations, etc..) where Babylon.GUI relies on HTML canvas API.
While it could be seen as a less performant approach, it is also more flexible. Furthermore, HTML canvas is also GPU accelerated on most recent browsers.
To begin with Babylon.GUI, you first need an AdvancedDynamicTexture object.
Babylon.GUI has two modes:
var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("myUI");
Here is an example of a simple fullscreen mode GUI: https://www.babylonjs-playground.com/#XCPP9Y#1 -
var advancedTexture2 = BABYLON.GUI.AdvancedDynamicTexture.CreateForMesh(myPlane, 1024, 1024);
Here is an example of a simple texture mode GUI: https://www.babylonjs-playground.com/#ZI9AK7#1 -
Please note that handling pointer move events could be costly on complex meshes, so you can turn off supporting pointer move events with a fourth parameter:
var advancedTexture2 = BABYLON.GUI.AdvancedDynamicTexture.CreateForMesh(myPlane, 1024, 1024, false);
Once you have an AdvancedDynamicTexture object, you can start adding controls.
All controls have the following observables:
Observables | Comments |
---|---|
onPointerMoveObservable | Raised when the cursor moves over the control. Only available on fullscreen mode |
onPointerEnterObservable | Raised when the cursor enters the control. Only available on fullscreen mode |
onPointerOutObservable | Raised when the cursor leaves the control. Only available on fullscreen mode |
onPointerDownObservable | Raised when pointer is down on the control. |
onPointerUpObservable | Raised when pointer is up on the control. |
You can also define that a control is invisble to events (so you can click through it for instance). To do so, just call control.isHitTestVisible
.
Please note that onPointerMoveObservable
, onPointerDownObservable
and onPointerUpObservable
will receive a Vector2 parameter containing the pointer coordinates. If you want to get the pointer coordinates in local control space, you have to call control.getLocalCoordinates(coordinates)
.
Here is an example of how to use observables: https://www.babylonjs-playground.com/#XCPP9Y#121 -
You can define the alignments used by your control with the following properties:
Property | Default | Comments |
---|---|---|
horizontalAlignment | BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER | Can be set to left, right or center. |
verticalAlignment | BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER | Can be set to top, bottom and center. |
Here is an example of how to use alignments: https://www.babylonjs-playground.com/#XCPP9Y#13 -
You can set controls' position with the following properties:
Property | Type | Default | Default unit |
---|---|---|---|
left | valueAndUnit | 0 | Pixel |
top | valueAndUnit | 0 | Pixel |
Size can be set with:
Property | Type | Default | Default unit |
---|---|---|---|
width | valueAndUnit | 100% | Percentage |
height | valueAndUnit | 100% | Percentage |
Paddings can be set with:
Property | Type | Default | Default unit |
---|---|---|---|
paddingTop | valueAndUnit | 0px | Pixel |
paddingBottom | valueAndUnit | 0px | Pixel |
paddingLeft | valueAndUnit | 0px | Pixel |
paddingRight | valueAndUnit | 0px | Pixel |
Please note that paddings are inside the control. This means that the usableWidth = width - paddingLeft - paddingRight. Same for usableHeight = height - paddingTop - paddingBottom.
All these properties can be defined using pixel or percentage as unit.
To set value as pixel, use this construct: control.left = "50px"
To set value as percentage, use this construct: control.left = "50%"
You can also not define the unit (In this case the default unit will be used): control.width = 0.5
(which is equivalent to control.width = "50%"
)
Here is an example of how to use positions and sizes: https://www.babylonjs-playground.com/#XCPP9Y#14 -
All controls can be moved to track position of a mesh.
To do this, just call control.linkWithMesh(mesh)
. You can then offset the position with control.linkOffsetX
and control.linkOffsetY
.
Here is an example of a trackable label: https://www.babylonjs-playground.com/#XCPP9Y#16 -
Please note that controls that want to track position of a mesh must be at root level (at AdvancedDynamicTexture level).
You can also move a control to a specific coordinates in your scene with control.moveToVector3(position)
. Please note that the control will not stick with the vector if you change it afterwards.
For Line control, you can also attach the second point to a control with line.connectedControl = control
. In this case the x2
and y2
properties are used to offset the second point from the connected control.
With these 2 options, you can create a complete trackable label: https://www.babylonjs-playground.com/#XCPP9Y#20 -
When in fullscreen UI, you can decide to define your UI with a fixed resolution.
To define this resolution, just set myAdvancedDynamicTexture.idealWidth = 600
or myAdvancedDynamicTexture.idealHeight = 400
.
If both are set, the idealWidth will be used.
When ideal resolution is set, all values expressed in pixels are considered relatively to this resolution and scaled accordingly to match the current resolution.
Even when ideal size is set, the fullscreen UI will be rendered at the same resolution of your canvas, but you can decide (mostly for performance reason) to force the texture to use the ideal size for resolution as well. To do so, just call myAdvancedDynamicTexture.renderAtIdealSize = true
.
Here is an example of how to use horizontal adaptive scaling: https://www.babylonjs-playground.com/#XCPP9Y#39 -
Controls can be transformed with the following properties:
Property | Type | Default | Comments |
---|---|---|---|
rotation | number | 0 | Value is in radians |
scaleX | number | 1 | |
scaleY | number | 1 | |
transformCenterX | number | 0.5 | Define the center of transformation on X axis. Value is between 0 and 1 |
transformCenterY | number | 0.5 | Define the center of transformation on Y axis. Value is between 0 and 1 |
Please be aawre that transformations are done at rendering level so after all computations. This means that alignment or positioning will be done first without taking transform in account.
Here is an example of how to use rotation and scaling: https://www.babylonjs-playground.com/#XCPP9Y#22 -
A control is an abstraction of a piece of UI. There are two kinds of controls:
All controls share the following properties:
Property | Type | Default | Comments |
---|---|---|---|
alpha | number | 1 | Between 0 and 1. 0 means completely transparent. 1 means fully opaque |
color | string | Black | Foreground color |
fontFamily | string | Arial | Font family can be inherited. This means that if you set it on a container, it will be transmitted to all children of the container |
fontSize | number | 18 | Can be inherited |
zIndex | number | 0 | the zIndex can be used to reorder controls on the z axis |
Controls can be added directly to the AdvancedDynamicTexture or to a container with:
container.addControl(control);
They can be removed with:
container.removeControl(control);
You can also control the control visibility with control.isVisible = false
.
The TextBlock is a simple control used to display text: https://www.babylonjs-playground.com/#XCPP9Y#2 -
Here are the properties you can define:
Property | Type | Default | Comments |
---|---|---|---|
text | string | null | Text to display |
textWrapping | boolean | false | Can be set to true to enable text wrapping. |
textHorizontalAlignment | number | BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER | Can be set to left, right or center |
textVerticalAlignment | number | BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER | Can be set to top, bottom or center |
A button can be used to interact with your user. Please see the events chapter to see how to connect your events with your buttons.
There are three kinds of buttons available out of the box:
var button = BABYLON.GUI.Button.CreateImageButton("but", "Click Me", "textures/grass.png");
You can try it here: https://www.babylonjs-playground.com/#XCPP9Y#3 -
var button = BABYLON.GUI.Button.CreateSimpleButton("but", "Click Me");
You can try it here: https://www.babylonjs-playground.com/#XCPP9Y#4 -
var button = BABYLON.GUI.Button.CreateImageOnlyButton("but", "textures/grass.png");
You can try it here: https://www.babylonjs-playground.com/#XCPP9Y#28 -
By default a button will change its opacity on pointerover and will change it scale when clicked. You can define your own animations with the following callbacks:
You can also create a complete custom button by manually adding children to the button. Here is how the ImageButton is built:
var result = new 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;
The checkbox is used to control a boolean value.
You can specify the value with checkbox.isChecked
.
Changing the isChecked
property will raise an observable called checkbox.onIsCheckedChangedObservable
.
The control is rendered using the following properties:
Property | Type | Default | Comments |
---|---|---|---|
color | string | white | Foreground color |
background | string | black | Background color |
checkSizeRatio | number | 0.8 | Define the ratio used to compute the size of the inner checkbox (0.8 by default, which means the inner check size is equal to 80% of the control itself) |
Here is an example of a checkbox: https://www.babylonjs-playground.com/#U9AC0N#2 -
The radio button is used to define a value among a list by using a group of radio buttons where only one can be true.
You can specify the selected value with radiobutton.isChecked
.
Changing the isChecked
property will raise an observable called checkbox.onIsCheckedChangedObservable
. Furthermore, if you select a radio button, all other radio buttons within the same group will turn to false.
The control is rendered using the following properties:
Property | Type | Default | Comments |
---|---|---|---|
color | string | white | Foreground color |
background | string | black | Background color |
checkSizeRatio | number | 0.8 | Define the ratio used to compute the size of the inner checkbox (0.8 by default, which means the inner check size is equal to 80% of the control itself) |
group | string | empty string | Use the group property to gather radio buttons working on the same value set |
Here is an example of a radiobutton: https://www.babylonjs-playground.com/#U9AC0N#13 -
The slider is used to control a value within a range.
You can specify the range with slider.minimum
and slider.maximum
.
The value itself is specified with slider.value
and will raise an observable everytime it is changed (slider.onValueChangedObservable
).
The control is rendered using the following properties:
Property | Type | Default | Comments |
---|---|---|---|
borderColor | string | white | Color used to render the border of the thumb |
color | string | white | Foreground color |
background | string | black | Background color |
barOffset | valueAndUnit | 5px | Offset used vertically to draw the background bar |
thumbWidth | valueAndUnit | 30px | Width of the thumb |
Here is an example of a slider: https://www.babylonjs-playground.com/#U9AC0N#1 -
The line will draw a line (!!) between two points.
Here are the properties you can define:
Property | Type | Default | Comments |
---|---|---|---|
x1 | number | 0 | X coordinate of the first point |
y1 | number | 0 | Y coordinate of the first point |
x2 | number | 0 | X coordinate of the second point |
y2 | number | 0 | Y coordinate of the second point |
dash | array of numbers | Empty array | Defines the size of the dashes |
lineWidth | number | 1 | Width in pixel |
Here is an example of a line: https://www.babylonjs-playground.com/#XCPP9Y#6 -
Use the image control to display an image in your UI.
You can control the stretch used by the image with image.stretch
property. You can set it to one of these values:
You may want to have the Image control adapt its size to the source image. To do so just call image.autoScale = true
.
You can change image source at any time with image.source="myimage.jpg"
.
You can also define which part of the source image you want to use with the following properties:
Here is an example of an image: https://www.babylonjs-playground.com/#XCPP9Y#7 -
The containers are controls used to host other controls. Use them to organize your UI.
Containers has one specific property: container.background
. Use it to define the background color of your container.
The Rectangle is a rectangular container with the following properties:
Property | Type | Default | Comments |
---|---|---|---|
thickness | number | 1 | Thickness of the border |
cornerRadius | number | 0 | Size in pixel of each corner. Used to create rounded rectangles |
Here is an example of a rectangle control: https://www.babylonjs-playground.com/#XCPP9Y#8 -
The Ellipse is a ellipsoidal container with the following properties:
Property | Type | Default | Comments |
---|---|---|---|
thickness | number | 1 | Thickness of the border |
Here is an example of an ellipse control: https://www.babylonjs-playground.com/#XCPP9Y#10 -
The StackPanel is a control which stacks its children based on its orientation (can be horizontal or vertical). All children must have a defined width or height (depending on the orientation).
The height (or width) of the StackPanel is defined automatically based on children.
Here is an example of a StackPanel: https://www.babylonjs-playground.com/#XCPP9Y#11 -
The color picker control allows users to set colors in your scene.
Whenever a user interacts with the color picker an observable is triggered (colorPicker.onValueChangedObservable
) which returns the current value (Color3) of the color picker.
The control is rendered using the following properties:
Property | Type | Default | Comments |
---|---|---|---|
size | string or number | "200px" | The size, width, and height property will always be the same value since the color picker can only be a square. |
Here is an example of a color picker: https://www.babylonjs-playground.com/#91I2RE#1 -
To reduce the amount of code required to achieve frequent tasks you can use the following helpers:
BABYLON.GUI.Control.AddHeader(control, text, size, options { isHorizontal, controlFirst })
: This function will create a StackPanel (horizontal or vertical based on options) and will add your control plus a TextBlock in it. Options can also be used to specify if the control is inserted first of after the header. Depending on the orientation, size will either specify the widht or the height used for the TextBlock.