Summary
Add a per-glyph effect hook to BitmapText (and ideally Text) so callers can offset/tint individual glyphs — wave, shake, per-glyph colour, per-glyph reveal — applied within the existing batched draw, not by splitting the string into N renderables.
Motivation
There's no per-glyph access today. To animate individual letters (the classic RPG "wavy text", shake-on-hit, rainbow, per-glyph typewriter) you must hand-roll one BitmapText/Text per character plus a Container — N draws, N renderables, per-frame bounds churn. The text example does exactly this (WavyText helper).
BitmapText already lays out and batches every glyph in a single draw. A per-glyph hook could offset each glyph's quad vertices (and apply a per-glyph tint via the per-vertex colour) inside that same batch, so an animated 100-char line stays ~1 draw call with zero extra objects. That is both more capable and dramatically cheaper than any userland helper — which is the main argument for doing it in-engine.
Proposed API (sketch)
A per-glyph callback invoked during layout/draw, receiving the glyph context and a reused, mutable output:
text.glyphEffect = (out, ctx) => {
// ctx: { index, char, code, time, x, y }
out.offsetY = Math.sin(ctx.time * 0.008 + ctx.index * 0.6) * 6; // wave
// out.offsetX / out.scale / out.rotation / out.tint?.setColor(...) optional
};
out is a reused scratch (zero-alloc steady state).
- Unset → the lean batched path is unchanged (no per-call cost).
- The batcher applies the offset to each glyph's vertices and the tint to its per-vertex colour during the existing flush.
Open design questions
- Scope to
BitmapText first (WebGL batched path). Text rasterises the whole string to one texture, so per-glyph there is harder — likely a slower fallback or out of scope.
- Callback vs a small declarative preset registry (wave / shake / rainbow), à la Godot's
RichTextLabel effects.
- Alternatively (or additionally) expose read-only glyph layout (positions) so callers can drive their own rendering.
Out of scope
Full BBCode / markup rich-text parsing. This ticket is just the per-glyph transform/tint primitive; presets and markup can build on it later.
References
- The
text example's WavyText helper — the userland workaround this would replace (N renderables → batched).
- Godot
RichTextLabel effects (wave/shake/rainbow + custom) as prior art.
Summary
Add a per-glyph effect hook to
BitmapText(and ideallyText) so callers can offset/tint individual glyphs — wave, shake, per-glyph colour, per-glyph reveal — applied within the existing batched draw, not by splitting the string into N renderables.Motivation
There's no per-glyph access today. To animate individual letters (the classic RPG "wavy text", shake-on-hit, rainbow, per-glyph typewriter) you must hand-roll one
BitmapText/Textper character plus aContainer— N draws, N renderables, per-frame bounds churn. The text example does exactly this (WavyTexthelper).BitmapTextalready lays out and batches every glyph in a single draw. A per-glyph hook could offset each glyph's quad vertices (and apply a per-glyph tint via the per-vertex colour) inside that same batch, so an animated 100-char line stays ~1 draw call with zero extra objects. That is both more capable and dramatically cheaper than any userland helper — which is the main argument for doing it in-engine.Proposed API (sketch)
A per-glyph callback invoked during layout/draw, receiving the glyph context and a reused, mutable output:
outis a reused scratch (zero-alloc steady state).Open design questions
BitmapTextfirst (WebGL batched path).Textrasterises the whole string to one texture, so per-glyph there is harder — likely a slower fallback or out of scope.RichTextLabeleffects.Out of scope
Full BBCode / markup rich-text parsing. This ticket is just the per-glyph transform/tint primitive; presets and markup can build on it later.
References
textexample'sWavyTexthelper — the userland workaround this would replace (N renderables → batched).RichTextLabeleffects (wave/shake/rainbow + custom) as prior art.