API reference
Every public class, method, and event in @codexo/exojs. Generated from source.
interfaceTextOptions
@codexo/exojs / rendering / stable
Construction options for a Text node - a flat merge of visual TextStyleOptions (appearance) and LayoutOptions (flow / overflow), plus two construction-only flags. The two source interfaces share no keys, so the flat shape is unambiguous. ```ts const label = new Text('Hello', { fillColor, fontSize: 24, maxWidth: 360 }); ```
39
props
0
methods
0
events
Import
import { TextOptions } from '@codexo/exojs'Construction options for a Text node - a flat merge of visual TextStyleOptions (appearance) and LayoutOptions (flow / overflow), plus two construction-only flags. The two source interfaces share no keys, so the flat shape is unambiguous.
```ts const label = new Text('Hello', { fillColor, fontSize: 24, maxWidth: 360 }); ```
Properties39
breakWords?: booleanBreak individual words that are wider than maxWidth at grapheme-cluster boundaries. Only applies when maxWidth is set. Defaults to false.
colorGlyphs?: booleanUse a colour-glyph (emoji) atlas + the text-color shader. Construction-only.
Rule colour. null (the default) takes the fill, gradient included, so a gradient-filled label gets a gradient-filled rule.
decorationOffset?: numberExtra downward offset in pixels applied to both rules, on top of the position the font's metrics put them at. Defaults to 0.
decorationThickness?: numberRule thickness in pixels. 0 (the default) derives it from the font size.
direction?: "ltr" | "rtl"Base direction for text layout. Defaults to 'ltr'. Direction-relative alignment is not derived from it - align stays literal in both directions.
ellipsis?: stringMarker appended to the last kept line under overflow: 'ellipsis'. Defaults to the horizontal ellipsis, U+2026. Set '...' for the three-period spelling, or '' to truncate without a marker. The marker is measured as text in the same font, so a long one eats proportionally more of the line it terminates. Truncation stops at grapheme-cluster boundaries, so a combining sequence or a flag is never cut in half.
font?: FontFaceA pre-constructed FontFace to use as the font for this node. When passed to Text, the face is automatically registered with document.fonts. Load the face via FontFactory before constructing the node so glyphs render immediately. Takes precedence over fontFamily when both are set. ts const face = await loader.load(Asset.type('font', 'roboto.woff2', { family: 'Roboto' })); const label = new Text('Score: 0', { font: face, fontSize: 24 });
fontFamily?: stringfontSize?: numberCSS font-variant-caps. Defaults to 'normal'.
CSS font-weight. Defaults to 'normal' so that single-weight custom fonts render without browser-synthesised bold artefacts. Set explicitly to 'bold' for display / title text that intentionally requires bold.
Multi-stop fill gradient. When set it overrides fillColor for the glyph interior; null disables it. The ramp spans the ink extent (getLocalBounds()), not the advance box.
leading?: numberExtra pixel gap between lines, added on top of lineHeight.
letterSpacing?: numberAdditional gap in pixels between glyphs (on top of the font's advance).
lineHeight?: numberMultiplier of fontSize for the distance between lines. Default 1.2 - not a pixel value.
locale?: stringLanguage tag ('en', 'ja', 'ar-EG') used for Unicode text segmentation - which clusters count as one character, and where a line may break. It selects no font and loads nothing; the platform default locale applies when it is absent.
maxHeight?: numberVertical boundary in pixels. Only whole lines that fit within it are kept. Has no effect on its own - pair it with an overflow policy.
maxLines?: numberHard cap on the number of laid-out lines, counted after wrapping. Unlike maxHeight this clips on its own, whatever overflow says - capping the line count is the whole point of asking for one. Pair it with overflow: 'ellipsis' to mark the last kept line. When both a cap and a maxHeight apply, the smaller one wins. Must be a positive integer.
maxWidth?: numberWord-wrap boundary in pixels. Lines exceeding this width are broken at word boundaries.
outlineWidth?: numberOutline width in SDF units (0..0.5). 0 disables the outline.
overflow?: "clip" | "ellipsis" | "visible"What to do with lines that do not fit maxHeight or maxLines. Defaults to 'visible'. - 'visible' - Keep every line; maxHeight is ignored. A maxLines cap still applies, silently. - 'clip' - Drop the lines that do not fit. - 'ellipsis' - Drop them and mark the last visible line with ellipsis, shortening it so it still fits maxWidth when one is set. Under a line cap the marker also reaches a last line that overflows maxWidth with no line dropped at all - a single unbreakable word under maxLines: 1.
pixelRatio?: numberDevice pixels per logical pixel this node's glyphs are RASTERIZED at. Omit it and the node inherits the pixelRatio of the Application it is drawn by - which is the deterministic default, and the only thing that ever happens without an explicit opt-in. Nothing in the text stack reads window.devicePixelRatio; there is no silent supersampling. Set it to decouple this node's glyph raster from the surface: ts const app = new Application({ canvas: { pixelRatio: 2 } }); new Text('9px label', { fontSize: 9 }); // rasterized at 2 new Text('9px label', { fontSize: 9, pixelRatio: 3 }); // rasterized at 3 The logical font size, layout, advances and line breaks are identical in both - only the raster grid behind the glyphs changes. Must be a positive finite number. The value to want is usually the inherited one. Lowering it lowers the raster resolution the distance field is built from, so the quality floor it hits depends on the glyph - size, thinnest stroke, SDF radius, outline - rather than on the ratio alone, and small text reaches that floor first. Raising it costs roughly the square of the ratio, and bought no visible sharpness for unscaled screen text when measured on hardware. Raise it for content whose ON-SCREEN density exceeds the surface ratio - a node scaled up at runtime, or one drawn through a zoomed camera; lower it to trade sharpness for atlas memory, which is safe on large text and harmful on small. Antialiasing is not part of the trade: the shader sizes its edge against the node's on-screen extent, so an edge lands at about one device pixel at every ratio.
sdfRadius?: numberSDF buffer radius in pixels. Construction-only.
shadowAlpha?: numberShadow opacity (0..1). 0 disables the shadow.
shadowBlur?: numberShadow blur softness (0..1). Larger values soften the shadow edge.
Drop-shadow color.
shadowOffsetX?: numberHorizontal shadow offset in pixels.
shadowOffsetY?: numberVertical shadow offset in pixels.
shaping?: "auto" | "browser" | "simple"How glyph appearance is resolved. Defaults to 'auto'. - 'auto' - use the shared-glyph fast path for content that is safe to render one cluster at a time, and hand anything else to the browser's text engine as a whole line. The classification is deliberately conservative and may admit more content to the fast path over time. - 'simple' - always use the shared glyph cache. The cheapest path and the right one for controlled content; a right-to-left line is reversed cluster by cluster rather than reordered, and contextual scripts render in their isolated forms. - 'browser' - always shape the whole line through the browser, which resolves bidi order and contextual forms. Each line becomes one node-owned raster instead of a run of shared glyphs, so a line whose text changes is rasterized again. A browser-shaped line is one glyph as far as the layout is concerned, so align: 'justify' cannot stretch it and caret geometry resolves to line granularity.
strikethrough?: booleanDraw a rule through each line. Defaults to false.
tabSize?: numberTab stop spacing, counted in space characters. Defaults to 8, the CSS tab-size initial value. A tab advances the pen to the next multiple of tabSize space widths from the start of its line, so a run of tabs lines columns up instead of adding a fixed gap each. Only reachable under whiteSpace: 'pre'; the collapsing modes turn a tab into a single space before layout runs, as CSS does. Must be a positive finite number. Ignored for browser-shaped lines, which the platform's text engine lays out whole.
Case mapping applied before layout. Defaults to 'none'. The mapping is Unicode-aware and never touches the node's text: reading it back gives the string that was assigned, so a transformed label stays editable and a caret still lands where the reader clicked. 'capitalize' uppercases the first grapheme cluster of each word and leaves the rest of the word alone, matching CSS. Word boundaries and the case mapping both follow locale when LayoutOptions.locale sets one.
underline?: booleanDraw a rule under each line. Defaults to false.
whiteSpace?: "normal" | "pre" | "pre-line"Whitespace handling mode: - 'normal' - Consecutive spaces collapse to one; \n becomes a space (standard wrap). - 'pre' - Spaces and newlines preserved verbatim. - 'pre-line' - Spaces collapse; \n preserved (default when no explicit mode). Defaults to 'pre-line' (current historical behaviour).
Source