Load fonts, then draw, update and measure 3D text.
loadFont(source, options) reads TrueType or OpenType outlines and builds a mesh per glyph; prewarm known characters with chars, and others build on first use. Characters the font lacks draw as ?, and there's no complex shaping, color emoji or fallback font.
Source, depth and weight identify a shared font; a later call with other chars only adds glyphs. Font licences still apply.
| FontOptions | Meaning |
|---|---|
| depth | Extrusion as a fraction of the font size; 0 is flat. Default 0.2. |
| chars | Glyphs to prewarm (space and ? always). Default: ASCII and common symbols. |
| weight | Weight of a variable font, e.g. 600. Default: the font's own. |
Load a HUD font (React)
React · browser
import { loadFont } from "@nayan-ui/engine";export const loadHudFont = () =>loadFont("/fonts/Inter-SemiBold.ttf", { depth: 0, chars: "0123456789SCORE: ", weight: 600 });
Load a HUD font (React Native)
React Native · iOS and Android
import { loadFont } from "@nayan-ui/engine";export const loadHudFont = () =>loadFont(require("./assets/Inter-SemiBold.ttf"), { depth: 0, chars: "0123456789SCORE: ", weight: 600 });
Spawn an entity with text and font; letters are 1 unit tall at scale 1 and the line is a single row. Setting text again reuses the existing letter entities.
Each drawn letter is a child entity that counts against the World's capacity. Text is lit, shadowed geometry in a scene, and flat and unlit in an overlay.
| Text option | Meaning |
|---|---|
| text / font | The line to draw and its loaded Font. |
| align | "left" | "center" | "right" around position. Default "center". |
| letterSpacing | Extra space between letters, in ems. Default 0. |
| tabular | Digits share the widest advance so scores don't shift. Default false. |
A score label that doesn't jitter
React and React Native · shared engine API
import type { Font, World } from "@nayan-ui/engine";export function scoreLabel(world: World, font: Font) {const label = world.spawn({ text: "0", font, align: "left", tabular: true,position: [-2, 3, 0], scale: 0.5, color: "white" });return (score: number) => world.set(label, { text: String(score) });}
measureText(font, text, layout) returns a line's advance in ems, with the same glyph loading, spacing and fallbacks as drawing; multiply by the entity's scale for world units. Pass the letterSpacing and tabular you draw with.
| Type | Meaning |
|---|---|
| Font | id, capHeight (capital height at scale 1) and glyphs, which grows with use. |
| TextLayout | letterSpacing? and tabular?, shared by measureText and text entities. |
| TextAlign | "left" | "center" | "right". |
Shrink a title to fit
React and React Native · shared engine API
import { measureText, type Font, type TextLayout, type World } from "@nayan-ui/engine";const layout: TextLayout = { letterSpacing: 0.02 };export function fittedTitle(world: World, font: Font, text: string, maxWidth: number) {const width = measureText(font, text, layout); // ems at scale 1const scale = Math.min(1, maxWidth / Math.max(width, 0.001));return world.spawn({ text, font, ...layout, scale, position: [0, 2, 0] });}