Particle orbPro
A voice orb as a point cloud sphere. It breathes in with the user's voice and ripples out with the agent's, with its own motion for every voice state. A drop-in swap for the free voice orb.
On this page
ProA point cloud sphere. Pick a state; it breathes in with the user's voice and ripples out with the agent's.
Installation
Usage
import { ParticleOrb } from "@/components/ui/chatcn/pro/particle-orb"
<ParticleOrb state={voice.state} inputLevel={mic.getLevel} outputLevel={agent.getLevel} size="xl" />Same props as VoiceOrb, so changing the import is the whole migration. About 1,400 points sit on a Fibonacci lattice at 144 px, each a little above or below the surface so the cloud reads as a shell, not a grid. Near points are larger and darker, the far side shows through, and the light of the shared orb form moves across them: it orbits while thinking and sweeps while connecting.
Examples
States, sizes and reduced motion
ProAll eight voice states, the 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 |
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 |
density | number | Point count multiplier. Default 1, capped at 3,200 points |
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 is
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 canvas 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 on the shared orb driver, eased with a critically damped approach, so any state can follow any other and nothing bounces. Interrupted snaps in; the rest settle over about half a second.
- Waves say who is talking: they run inward to the front of the sphere while the user speaks and outward while the agent speaks. The direction eases over about 200 ms, so it never flips mid ring.
- The loop runs on the shared frame clock and stops offscreen, in hidden tabs and when paused. Under reduced motion each state is one still frame.
- Speaking grows the points with the level and sparkles a share of them each frame, the particle version of grain.