UINode
A UINode is an ActorComponent that positions an actor in screen space using an anchor, offset, and pivot system. It is the base positioning layer for all 2D UI elements — UISprite extends it to add visuals and interaction.
When a UIRenderer exists in the game instance, every new UINode automatically registers itself with the renderer. Otherwise it falls back to listening to renderer resize events directly.
import { Actor, UINode } from "@jolly-pixel/engine";
const hud = new Actor(world, {
name: "hud",
parent: camera2D
})
.addComponent(UINode, {
anchor: { x: "right", y: "top" },
offset: { x: -16, y: -16 },
size: { width: 100, height: 40 }
});Anchor
The anchor determines which screen edge the element aligns to. Anchors are independent on each axis.
| Axis | Values | Description |
|---|---|---|
x | "left", "center", "right" | Horizontal screen edge |
y | "top", "center", "bottom" | Vertical screen edge |
When an anchor is set to "left", the element is pushed against the left edge of the screen. Combined with an offset you can create consistent margins that survive window resizes.
Offset
The offset shifts the element away from its anchor in world units. Positive X moves right, positive Y moves up.
// 20 units from the left edge, 10 units below the top
{
anchor: { x: "left", y: "top" },
offset: { x: 20, y: -10 }
}Pivot
The pivot is a normalized origin point from 0 to 1 that controls which part of the element sits at the computed position.
| Pivot | Meaning |
|---|---|
{ x: 0, y: 0 } | Bottom-left corner |
{ x: 0.5, y: 0.5 } | Center (default) |
{ x: 1, y: 1 } | Top-right corner |
Setting the pivot to { x: 0, y: 1 } makes the top-left corner the origin — useful for left-aligned HUD panels anchored to the top of the screen.
Size
The size defines the width and height of the element in world units. It is used by UISprite to create the mesh geometry and by the anchoring logic to keep the element fully on-screen.
{
size: { width: 200, height: 60 }
}Constructor
interface UINodeOptions {
anchor?: {
x?: "left" | "center" | "right";
y?: "top" | "center" | "bottom";
};
offset?: {
x?: number;
y?: number;
};
size?: {
width?: number;
height?: number;
};
pivot?: {
x?: number;
y?: number;
};
}| Option | Default | Description |
|---|---|---|
anchor | { x: "center", y: "center" } | Screen-edge alignment |
offset | { x: 0, y: 0 } | Offset from the anchor in world units |
size | { width: 0, height: 0 } | Element dimensions in world units |
pivot | { x: 0.5, y: 0.5 } | Normalized origin point (0 – 1) |
Positioning examples
Centered element:
// Defaults — centered on screen
{ anchor: { x: "center", y: "center" } }Top-right corner with margin:
{
anchor: { x: "right", y: "top" },
offset: { x: -16, y: -16 },
pivot: { x: 1, y: 1 }
}Bottom-left health bar:
{
anchor: { x: "left", y: "bottom" },
offset: { x: 20, y: 20 },
size: { width: 300, height: 24 },
pivot: { x: 0, y: 0 }
}API
class UINode extends ActorComponent {
get size(): { width: number; height: number };
get pivot(): { x: number; y: number };
addChildren(object: THREE.Object3D): void;
updateToWorldPosition(): void;
}See also
- UIRenderer — the orthographic overlay system
- UISprite — visual + interactive UI element
- ActorComponent — component base type