raea/text

Text in the 3D world, fonts, and time anchored to the words said.

View as Markdown

Two kinds of text live here. <RichText> and <Text3D> put text into a 3D scene, each glyph a lit entity that the same named moves as 2D can animate glyph by glyph. word(), findPhrase and useWords anchor time to speech: the frame a phrase is said, from the transcript raea cut writes, wherever the cut puts it.

TSX
import { Sequence } from "raea";
import { word } from "raea/text";

function Callout() {
  const at = word("forty countries");
  return (
    <Sequence from={at} durationInFrames={60}>
      <h1 style={{ fontSize: 96, color: "#fff" }}>40 countries</h1>
    </Sequence>
  );
}

See Cutting by words.

TS
import { findPhrase, loadFont, RichText, Span } from "raea/text"

raea/text exports 3 components, 1 hook, 3 functions, 6 types. Bevy's counterpart: bevy_text. Source: sdk/raea/src/text.ts.

Components

RichText

Text in the 3D world: every glyph a real lit, shaded entity (bevy_rich_text3d's mesh over its glyph atlas, a StandardMaterial of its own), laid out as one line of shaped text (kerning, spans of other fonts and sizes) and then moved, turned, scaled, recoloured, faded and revealed glyph by glyph with the motion code 2D uses: the named moves staggered (enter="rise" each={2}), a typewriter's reveal, or a glyph function of the frame.

Hello world <RichText glyph={(g) => ({ position: [0, Math.sin(frame / 6 + g.index) * 0.05, 0] })}>WAVE

Takes RichTextProps's props.

Span

A run of a 's text in its own font, weight, size or colour. Only inside a .

Takes SpanProps's props.

Text3D

Solid 3D letters (Manifold's text3d), as a Mesh's geometry: <Mesh><Text3D size={0.6}>SALE</Text3D>...</Mesh>.

Takes Text3DProps's props.

Hooks

useWords

Every word heard on the timeline, in the frames of the nearest enclosing Sequence.

TS
function useWords(): TimelineWord[]

Functions

findPhrase

Finds the composition frame where phrase is said in a transcript.

TS
function findPhrase(words: readonly HeardWord[], phrase: string, options?: WordOptions): number

loadFont

The page gets Google Fonts' family ("Inter", "Space Grotesk"); fontFamily is the name to style text with.

TS
function loadFont(family: string): { fontFamily: string; }

word

The composition frame where phrase is said. Call it while rendering (it reads the Clock).

TS
function word(phrase: string, options?: WordOptions): number

Types

GlyphInfo

What a glyph is, for a 's glyph function.

FieldTypeWhat it is
index (required)numberits place among the drawn glyphs (spaces aren't glyphs), from 0
count (required)numberhow many glyphs the block has
char (required)stringthe character it draws
word (required)numberits word's place among the words, from 0, and how many there are
words (required)numberhow many words the block has
inWord (required)numberits place in its word, and the word's glyph count
wordLength (required)numberhow many glyphs its word has
line (required)numberits line (by the newlines in the text), from 0
span (required)numberits run: the it's in (0 for text outside any, counted in order)

GlyphStyle

A glyph's motion this frame, about its own centre, in the block's space: added to (position, rotation), multiplied into (scale, opacity) or replacing (color, visible) what the block's moves give it.

FieldTypeWhat it is
positionVec3metres, from its place in the block
rotationVec3radians, XYZ
scalenumber | Vec3multiplies its size: one number, or x, y and z
colorstringreplaces its colour
opacitynumbermultiplies its opacity, 0..1
visiblebooleanfalse hides it this frame

RichTextProps

FieldTypeWhat it is
namestringwhat it's called across frames, and its glyphs' names over world.* (${name}:${index})
passstringthe composition pass it draws in ("scene" by default): a frame-wide effect told to skip a pass (, , , ) leaves its pixels as drawn, and gives one its own paint; a piece names at most three passes besides "scene"; keyed per frame
positionVec3where the block's origin is, metres (x, y, z)
rotationVec3the block's rotation, radians (x, y, z)
scalenumber | Vec3the block's scale: one number, or x, y and z
sizenumberthe em in metres (0.5 by default)
fontstringa family (raea's bundled faces: Inter by default, Montserrat, Oswald, Playfair Display...; or one on this machine)
weightnumber100..900 (700 by default)
italicbooleanslanted (false by default)
colorstringeach glyph's colour unless its gives one
align"left" | "center" | "right"where the origin is: the left edge, the middle (default) or the right edge of the lines; the block's middle vertically
lineHeightnumbertimes the em (1.2 by default)
maxWidthnumberwrapped at this width in metres (no wrapping by default)
roughnessnumber0..1, smooth to matte
metalnessnumber0..1, a dielectric to a metal
emissivestringthe colour it glows with
emissiveIntensitynumberhow strongly it glows (1 by default; 2-10 with bloom)
unlitbooleandrawn in its flat colour, without light or shade
castShadowbooleanletter-shaped shadows (true by default)
receiveShadowbooleanother things' shadows fall on it
layersnumber[]the render layers it's on ([0] by default): a camera draws only the layers it's given
enterMoveLikeeach glyph's (or word's) entrance: a move's name, a move or several (rise, pop, slam, slide, fade... the 2D ones, their px read at 100 an em, their degrees as degrees), each frames apart from at
eachnumberframes between one glyph's (or word's) entrance and the next (2 by default)
by"letter" | "word"the entrance and exit staggered by letter (default) or by word
atnumberthe local frame the first entrance starts (0)
exitMoveLikeeach glyph's (or word's) exit: a move or its name, played backwards from exitAt
exitAtnumberthe local frame the first exit starts; an exit needs it
exitEachnumberframes between exits (0: together)
revealnumberhow many glyphs are shown, a typewriter's count: the next one fades in over its fraction
glyph(g: GlyphInfo) => GlyphStyleeach glyph's own motion this frame, from anything the frame gives (useCurrentFrame, spring, interpolate)
childrenReactNodethe text: strings and runs

SpanProps

FieldTypeWhat it is
childrenReactNodethe run's text
fontstringa family (raea's bundled faces: Inter, Montserrat, Oswald, Playfair Display...; or one on this machine)
weightnumber100..900 (the block's by default)
italicbooleanslanted (the block's by default)
sizenumbertimes the block's size
colorstringthe run's colour (the block's by default)

Text3DProps

FieldTypeWhat it is
childrenstringthe words, extruded
textstringthe words, when they aren't its child (no quotes or backslashes)
sizenumberletter height in scene units (default 0.5)
depthnumberextrusion depth (default 0.2)
fontstringa family (Inter by default, or another of raea's bundled faces)
weightnumber100..900 (800 by default)

WordOptions

FieldTypeWhat it is
occurrencenumberwhich time the phrase is said, from 1
edge"start" | "end""start": the phrase's first frame; "end": the frame after its last word ends