Animated React Robot Avatars for Agent Status – robot-heads

Description:

robot-heads is a React avatar component that displays an agent’s activity through an animated robot face.

It draws a rotating, shaded TV-style head on a 2D canvas, with LED expressions and an antenna light that change with the supplied state.

Preview

robot-heads

Install

Install the package with NPM

npm install robot-heads

Connect the avatar to agent status

Pass the agent’s current activity into state:

import { RobotHead } from 'robot-heads';
type AgentStatus = 'idle' | 'thinking' | 'speaking';
export function AgentAvatar({ status }: { status: AgentStatus }) {
  return (
    <RobotHead
      state={status}
      shape="rectangle"
      size={160}
      color="#2b49a3"
      aria-label={`Assistant status: ${status}`}
    />
  );
}

States and expressions

StateFace and motion
idleBlinking eyes, glances, and occasional hops
thinkingUpward-looking eyes, pulsing dots, and an amber antenna light
searchingA scanning beam, side-to-side movement, and a cyan light
listeningAn equalizer face, small nods, and a green light
speakingAn animated mouth and talking motion
workingA progress-bar face and busy head movement
happySmiling eyes and bouncing hops
errorRed cross-shaped eyes, head shaking, and a blinking red light
sleepingClosed eyes, rising sleep characters, and slow breathing

Customize the head

PropDefaultPurpose
modeltvRobot model; tv is the available value
stateidleOne of the nine activity states above
shaperectanglerectangle, square, circle, or hexagon
size160Resting layout box in pixels
color#2b49a3Shell color
trimColor#93a6c8Ears and antenna collar color
screenColor#e8f2ffLED color
speed1Animation speed multiplier
pausedfalseDraws the selected state’s still pose
interactivetruePointer tracking and click-triggered hops
antennatrueAntenna stem and light visibility
floorShadowtrueShadow beneath the head
seedGenerated per instanceValue from 0 to 1 that offsets blinks and glances
className, styleUnsetCSS classes and styles on the wrapper
refUnsetRef to the inner HTMLCanvasElement

Compact status avatars

For compact status lists, remove the antenna stem and disable pointer play.

Give each avatar a different seed so their idle movements do not synchronize:

import { RobotHead } from 'robot-heads';
export function WorkerAvatars() {
  return (
    <div style={{ display: 'flex', gap: 24 }}>
      <RobotHead state="working" shape="square" size={64}
        antenna={false} interactive={false} seed={0.2} />
      <RobotHead state="searching" shape="hexagon" size={64}
        antenna={false} interactive={false} seed={0.7} />
    </div>
  );
}

Layout and motion behavior

The wrapper occupies a size by size box. Hops, glow, and the floor shadow extend beyond it. Leave room around the avatar, and avoid a tightly clipped parent with overflow: hidden.

Every head shares an animation loop. The loop sleeps while the browser tab is hidden, and heads with matching shapes and sizes reuse baked textures.

Reduced-motion preferences select a still pose. Pass paused to stop animation explicitly. The wrapper has an image role and a state-based accessible label; override aria-label when the surrounding task needs a more specific description.

Standard attributes and event handlers pass to the wrapper. A forwarded ref reaches the canvas. The package also exports robotHeadShapes and robotHeadStates for controls that need the available values.

Related resources

Tags:

Add Comment