Halftone orbPro
A voice orb as a sphere of halftone dots. Dot size follows the light and the voice level, and the sphere turns slowly while thinking. A drop-in swap for the free voice orb.
On this page
ProA sphere of halftone dots whose size follows the light and the voice. It turns while thinking.
Installation
Usage
import { HalftoneOrb } from "@/components/ui/chatcn/pro/halftone-orb"
<HalftoneOrb state="speaking" outputLevel={agent.getLevel} size="xl" />The dots sit on the sphere itself, on a latitude grid with fewer dots toward the poles, so they flatten into ellipses toward the edge and travel with the surface when it turns. Each dot is antialiased in the shader and sized from the light at its center, then grows with the voice.
Examples
States, sizes and reduced motion
ProAll eight voice states, the four sizes and the still frames drawn under reduced motion.
Props
| Prop | Type | Notes |
|---|---|---|
state | "idle" | "connecting" | "listening" | "thinking" | "speaking" | "interrupted" | "muted" | "error" | Default idle. Same states as VoiceOrb |
level, inputLevel, outputLevel | number | () => number | 0 to 1. Input drives listening, output drives speaking. A getter animates without re-rendering |
simulate | boolean | Speech-like levels where none are passed, for demos |
size | "sm" | "md" | "lg" | "xl" | number | 40, 72, 144, 224 px. Default lg |
renderer | "auto" | "webgl" | "2d" | auto uses the shared WebGL2 context, then canvas 2D. canvas and svg are accepted as aliases of 2d |
reducedMotion | boolean | Force it on or off. Defaults to the user's setting |
label | string | Accessible name. Default "Voice: listening" and so on |
ink | string | Token or CSS color for the marks. Default var(--chatcn-fg) |
paused, defaultPaused, onPausedChange | boolean | Controlled or uncontrolled pause |
pauseControl | boolean | Show the pause button. Default on from 120 px |
rows | number | Dot rows from pole to pole. Default about one per 7 px |
Keyboard
| Key | Action |
|---|---|
Tab, Enter | Focus and toggle the pause button, when it shows |
Accessibility
- One
role="img"named by state, "Voice: speaking", exactly like the free voice orb. Announce state changes in your own live region, as the examples do. - The canvas and the text grid are
aria-hidden; nothing animated is read out. - Error uses the red token and the state label as its backup, never color alone.
- Under
forced-colors: activethe effect hides and a plain outline keeps the orb's place. Underprefers-contrast: morethe marks snap to the text token.
Motion
- Each state is a target form. The orb eases toward it every frame with a critically damped approach, so any state can follow any other and nothing bounces. Interrupted snaps in quickly; the rest settle over about half a second.
- Loops run on the shared frame clock and stop offscreen, in hidden tabs and when paused. Time stops with them, so resuming continues instead of jumping.
- Under reduced motion each state is one still frame, redrawn only when the state changes.
- Thinking turns the sphere about once every 16 s, and the dots travel with it; the other states barely drift.