Fonts, text and measurement

Load fonts, then draw, update and measure 3D text.

Load a font

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.

Load a font reference
FontOptionsMeaning
depthExtrusion as a fraction of the font size; 0 is flat. Default 0.2.
charsGlyphs to prewarm (space and ? always). Default: ASCII and common symbols.
weightWeight of a variable font, e.g. 600. Default: the font's own.

Load a HUD font (React)

React · browser

Load a HUD font (React)
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

Load a HUD font (React Native)
import { loadFont } from "@nayan-ui/engine";
export const loadHudFont = () =>
loadFont(require("./assets/Inter-SemiBold.ttf"), { depth: 0, chars: "0123456789SCORE: ", weight: 600 });

Spawn and update text

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.

Spawn and update text reference
Text optionMeaning
text / fontThe line to draw and its loaded Font.
align"left" | "center" | "right" around position. Default "center".
letterSpacingExtra space between letters, in ems. Default 0.
tabularDigits 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

A score label that doesn't jitter
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) });
}

Measure text

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.

Measure text reference
TypeMeaning
Fontid, capHeight (capital height at scale 1) and glyphs, which grows with use.
TextLayoutletterSpacing? and tabular?, shared by measureText and text entities.
TextAlign"left" | "center" | "right".

Shrink a title to fit

React and React Native · shared engine API

Shrink a title to fit
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 1
const scale = Math.min(1, maxWidth / Math.max(width, 0.001));
return world.spawn({ text, font, ...layout, scale, position: [0, 2, 0] });
}