Components/BotAvatar

BotAvatar

An animated bot avatar drawn on a canvas.

VerifiedSince 0.6.2

Usage

Basic

Drive state from the agent's real status: working while it streams or runs, default when idle.

Loading demo...

Chat Reply

<template>
  <div class="msg msg--bot">
    <TxBotAvatar type="clover" :state="streaming ? 'working' : 'default'" :size="32" />
    <div class="msg-body">
      {{ streaming ? 'Thinking…' : content }}
    </div>
  </div>
</template>

Agent Roster

Each instance offsets its blink timing by default, so a row never blinks in unison.

<template>
  <ul class="roster">
    <li v-for="agent in agents" :key="agent.id">
      <TxBotAvatar :type="agent.avatar" :state="agent.busy ? 'working' : 'default'" :size="32" aria-hidden />
      <span>{{ agent.name }}</span>
      <span class="muted">{{ agent.status }}</span>
    </li>
  </ul>
</template>

Still Avatar

<template>
  <TxBotAvatar type="hexagon" :size="96" paused />
</template>

Best Practices

  • Set size; never put width, height, or margin in style or a class, or the avatar shifts or crops.
  • Leave room above the avatar: the canvas draws 1.5× the size box, so a jump leaves the layout box and an overflow: hidden parent crops it.
  • Map your own statuses: running / streaming / pending / busy → working; idle / ready / online → default; offline / away / disabled → default with paused.
  • When the name and status already appear as text beside it, mark the avatar decorative with aria-hidden.
  • Use it for bots only; give people a photo or initials.

API Reference

Props

PropTypeDefaultDescription
typeBotAvatarType'clover'Body shape; each has its own palette color.
faceBotAvatarFacetype's ownFace kind.
state'default' | 'working' | 'sleeping''default'Idle (looks around, blinks, jumps now and then), working (hops, spins, smiles), or sleeping.
sizenumber | string64Layout size; also accepts any CSS length.
colorstringtype paletteBody color.
inkstringautoFace ink; dark by default, light on a dark body.
brightness / saturationnumber1 / 1.5Lightness and vividness of the body color.
speednumber1Multiplier on every animation.
pausedbooleanfalseFreezes the animation on its current frame.
seednumberderived from instanceOffsets blink and glance timing so a row doesn't move in unison.
shading'plastic' | 'crisp' | 'smooth' | 'flat' | boolean'plastic'How the body is lit; true means crisp, false means flat.
shadow / highlightnumber0.35 / 1.3Strength of the shadow and lit sides.
depthnumber0.65Body thickness, 0.2–2.
lightnumber265Light direction in degrees clockwise from the top.
rimnumber0.5Lit rim width under crisp, Fresnel strength under plastic.
spreadnumber1.55Reach of the soft shading, or width of the highlight.
interactivebooleantrueEyes and head follow a nearby pointer; a click makes it hop and turn.
theme'auto' | 'dark' | 'light''auto'The surface beneath; auto reads an ancestor data-theme attribute or class, then the OS.
turnnumber1How far the head turns side to side while idle.
whirlnumber0Strength of the whirl ring around a spin.
whirlSize / whirlWidth / whirlLength / whirlTiltnumber1Whirl ring geometry.
jumpHeightnumber26Jump height in body units; the body is 100 tall.
jumpTimenumber0.68Seconds a jump spends in the air.
jumpStretch / jumpSquashnumber1 / 1.15Stretch in the air and squash on the ground.
jumpSquashTime / jumpSquashEasenumber / BotAvatarSquashEase0.37 / 'pulse'Seconds and easing of the landing squash, from contact to recovery.
jumpGroundTime / jumpGroundEasenumber / BotAvatarSquashEase0.11 / 'pulse'Seconds and easing of the hold at the deepest squash.
jumpRiseTime / jumpRiseEasenumber / BotAvatarSquashEase0.33 / 'pulse'Seconds and easing of the rise from the deepest squash back to shape.
jumpClickSquashTimenumber0.24Landing squash time for a click's jump.
jumpSpinnumber1Whole turns made in the air.
jumpLeannumber6Degrees of lean into a jump.
jumpEverynumber8Seconds between idle jumps, ±40%; 0 disables them.
jumpLandnumber0When the landing squash starts relative to touch-down, in seconds.

BotAvatarType has 18 shapes: clover, flower, triangle, square, blob, ghost, circle, drop, star, droid, mech, alien, hexagon, cat, cloud, pill, pebble, and puddle. BotAvatarFace is 'eyes' | 'mouth'. BotAvatarSquashEase is 'sharp' | 'pulse' | 'soft' | 'bouncy'.

Exposed Methods

NameTypeDescription
canvasHTMLCanvasElement | nullThe root <canvas> element.

Overview

  • The canvas is a role="img" whose aria-label follows the state ("Clover bot, idle"); pass aria-label to replace it.
  • Other attributes and DOM listeners pass straight to the <canvas>, so class, style, and data-* work as usual.
  • An unknown state falls back to default; an unknown type falls back to clover.
  • One shared requestAnimationFrame loop serves every avatar; drawing stops offscreen and while the tab is hidden.
  • Under reduced motion no loop starts and only the state's still pose is drawn; the preference is read at render time, not watched.
  • State changes cross-animate, so switching state on every token or tool call is safe.

Technologies

  • Device pixel ratio is capped at 2; plastic shading bakes each body type on idle time when it first appears, with a softer look standing in until then.
  • The drawing engine is a verbatim port of upstream Jakubantalik/Libraries · bot-avatars (MIT © Jakub Antalik); the Vue shell mirrors its React component.
  • Source: packages/tuffex/packages/components/src/bot-avatar/.
查看源码
packages/tuffex/packages/components/src/bot-avatar/index.ts