Thinking Orb
A canvas thinking indicator that shares one clock and stops when offscreen.
Thinking Orb
Basic Usage
Thinking Orb
Loading demo...
Interaction Contract
statedefaults to'random', and the form is rolled once on mount and kept for the component's lifetime. To get a different orb, remount it with a newkey— changing the prop will not do it.- The nine forms are
working,searching,solving,listening,connecting,weaving,composing,breathingandshaping. - Every mounted orb shares one clock (
performance.now), so several on screen stay in phase rather than drifting apart. - The loop stops when the orb scrolls offscreen (
IntersectionObserver) and when the tab is hidden, so a long list of orbs does not keep burning CPU. - Under
prefers-reduced-motion: reducethe animation does not run; a single representative frame is drawn instead, and it still follows theme changes. sizeaccepts only20and64— the preset geometry is hand-tuned for those two. UsedisplaySizefor any other rendered size; it changes the CSS box only, not the drawing parameters.- The canvas is scaled by
devicePixelRatio, capped at 2. - Where there is no canvas (jsdom, for instance)
getContext('2d')returns null, and the component keeps the element but skips painting rather than throwing. - The accessible name defaults to an English label for the form (
Searching…and so on);labeloverrides it.
API
Props
| Name | Type | Default | Description |
|---|---|---|---|
state | OrbState | 'random' | 'random' | Which orb to draw. 'random' rolls once, on mount. |
size | 20 | 64 | 20 | Preset geometry size. Only these two are tuned. |
displaySize | number | same as size | Rendered CSS size in px; does not affect the drawing parameters. |
speed | number | 1 | Animation speed multiplier. |
paused | boolean | false | Whether to pause the animation. |
theme | 'auto' | 'dark' | 'light' | 'auto' | Colour theme; auto follows the environment. |
label | string | an English label per form | Accessible name. |
Events
TxThinkingOrb emits no component events.
Slots
TxThinkingOrb exposes no slots. It is a pure drawing surface — put any text in a sibling node.
Best Practices
- To get a new orb per thought, key the component by that thought. Changing
statewill not reroll it. - Pass an explicit
statewhere you need determinism; a random form makes screenshot tests and screen recordings differ every run. - Keep
sizeat20or64and adjust the visual size withdisplaySize; other values distort the tuned presets. - Supply
labelon non-English surfaces — the defaults are English. - Show one orb per thought. Several stay in phase, but they blur what exactly is in progress.