Panel
<Panel slot> draws a pane in one of the screen’s nine slots: the four corners, the four edges and the centre. A Panel names a slot and an order, never a position. Each slot stacks its Panels in a column, so two Panels never overlap.
Its props are in PanelProps.
A slot Panel sits inside a Hud, which carries it to the screen.
import { Hud, Panel, Slot, Text } from "@daniel-zarinski/engine";
export function Readout({ coins, round }: { coins: number; round: number }) { return ( <Hud> <Panel slot={Slot.TopRight} order={1}> <Text>Coins {coins}</Text> </Panel> <Panel slot={Slot.TopRight} order={2}> <Text>Round {round}</Text> </Panel> </Hud> );}A Panel is glass by default, as Unity’s Panel and Godot’s PanelContainer draw a background. PanelVariant.Bare stacks its children with no pane, as Godot’s VBoxContainer does, so a Button in a bare Panel is not glass on glass.
A slot Panel inside an Entity stays in its slot and reads the entity; it does not follow it. That is screen UI, like Unity’s screen-space canvas or Roblox’s ScreenGui. A Panel that follows its entity in the world is anchored.
The Slot members are TopLeft, Top, TopRight, Left, Center, Right, BottomLeft, Bottom and BottomRight.
Anchored
Section titled “Anchored”<Panel anchor> follows the entity it sits in, like Roblox’s BillboardGui. It sits inside an Entity directly, with no Hud, and reads the entity through useEntity(). The screen layer always draws over it, so a nameplate slides under a slot Panel.
Its props are also in PanelProps, and Anchor says where it stands.
An anchored Panel takes the same variant and className as a slot Panel. It takes no pointer events itself, so a drag across a nameplate still turns the camera.
import { Anchor, Bar, HealthTrait, Panel, Text, useEntity,} from "@daniel-zarinski/engine";import { useTrait } from "koota/react";
export function Nameplate() { const health = useTrait(useEntity(), HealthTrait); if (!health) return null;
return ( <Panel anchor={Anchor.Above} maxDistance={40}> <Text>Yeti</Text> <Bar label="Yeti health" value={health.current} maximum={health.maximum} /> </Panel> );}