Plasma Orb
Shader mesh gradient on canvas, no Three.js. Organic distortion.
Idle
State
Speed
Size
Color
From
To
Shader (canvas)gpu
Shader (canvas)
Shader mesh gradient on canvas, no Three.js. Organic distortion.
Shader mesh gradient on canvas, no Three.js. Organic distortion.
Every orb implements the same contract, so they are interchangeable: swap the import and keep the props.
| Prop | Type | Default | Description |
|---|---|---|---|
| state | 'idle' | 'connecting' | 'listening' | 'thinking' | 'speaking' | 'error' | 'disabled' | 'idle' | Assistant lifecycle state driving the animation. error and disabled are optional extensions. |
| size | number | 160-184 (per orb) | Diameter of the orb in pixels, also exposed as the --orb-size CSS variable. |
| speed | number | 1 | Animation speed multiplier, also exposed as the --orb-speed CSS variable. |
| colorFrom | string | per-orb gradient start | Gradient start color (any CSS color), exposed as --orb-color-from. |
| colorTo | string | per-orb gradient end | Gradient end color (any CSS color), exposed as --orb-color-to. |
| levelRef | RefObject<number> | undefined | Live audio amplitude in 0..1 read every frame without re-render; a negative value falls back to the procedural animation. |
| label | string | 'Assistant orb' | Accessible name announced by screen readers via aria-label. |
| className | string | undefined | Extra class names merged onto the root element. |
| ref | Ref<HTMLDivElement> | undefined | React 19 ref to the root element for measuring, animating or scrolling into view. |
Copy the component files from the playground above, then render the orb with its default configuration. First install @paper-design/shaders-react.
import { PlasmaOrb } from '@/registry/orbe/plasma-orb/plasma-orb';
export const Assistant = () => (
<PlasmaOrb
state="idle"
size={168}
speed={1}
colorFrom="#7c3aed"
colorTo="#06b6d4"
/>
);
Drive state from your assistant lifecycle and pass a levelRef with the live amplitude. The bundled useAudioLevel hook opens the microphone and writes a 0..1 level into the ref every frame without re-rendering; while the value is negative the orb falls back to its procedural animation.
'use client';
import { useState } from 'react';
import type { OrbState } from '@/registry/lib/orb-state';
import { useAudioLevel } from '@/registry/lib/use-audio-level';
import { PlasmaOrb } from '@/registry/orbe/plasma-orb/plasma-orb';
export const Assistant = () => {
const [state, setState] = useState<OrbState>('idle');
const { levelRef } = useAudioLevel(state === 'listening');
return <PlasmaOrb state={state} levelRef={levelRef} />;
};