Companion
A small mascot that looks at the pointer: an animated bot with eighteen bodies, hats, glasses and finishes, or a blob with ten silhouettes and fourteen moods. It is a pet, not an avatar.
Playground
Every prop of the bot, live. Move the pointer around the stage and it follows. Pick Sleeping to see the resting pose, or turn on Clickable and press it.
Blob playground
The same for the blob. Hue, tone and shape are optional: left on Auto, the seed picks them.
Bodies
Eighteen bodies. Each has its own colour; the seed picks one when type is left out.
Finishes
plastic is glossy and costs the most to draw. fabric is a plush fur. flat is a single fill, cheap enough for a grid of thumbnails.
Hats
Four hats, drawn over the body. Their colour comes from accessoryColor.
Glasses and faces
Three kinds of glasses, and the two faces: eyes or a smile.
Accessories
Headphones and a bow tie, each with its own on/off. Both follow accessoryColor.
Body colours
color overrides the body's own colour. Leave it empty to keep the type's.
Sizes
size is any CSS length, so em scales with the text around it and rem or px pin it. The canvas overscans the box by 1.5x, so an inline companion does not push the line apart.
States
default looks around and blinks. sleeping closes its eyes and breathes. paused freezes whichever you picked on one frame.
Interaction
clickable makes it a button: it hops and emits activate, and Enter and Space work. interactive controls the eyes following the pointer and the idle hop of the blob.
Inline in text
inline sits the companion in a line of text and pulls its overscan back so the line height does not change.
Blob shapes
Ten silhouettes. shape takes a value between 0 and 1; BLOB_SHAPES holds the mid-point of each band.
Blob hue and tone
hue is an angle from 0 to 359. tone runs from pale to ink.
Blob moods
Fourteen expressions, set with expression.
Blob backgrounds
background puts the blob on a tile, or leaves it bare with none.
Seed
The same seed always draws the same companion, so a user id or an email gives each person a stable one. Type below and watch it change.
From a config
Companion takes one CompanionConfig and picks the bot or the blob for you. defaultCompanion gives what a person who has not chosen gets. randomCompanion gives a full random one.
<script setup>
import { Companion, defaultCompanion, randomCompanion } from "@/components/fx/companion";
const config = ref(defaultCompanion(user.email));
</script>
<template>
<Companion :config="config" :seed="user.email" size="4rem" :inline="false" />
<button @click="config = randomCompanion('bot')">Shuffle</button>
</template>Credits
The bot engine is bot-avatars by Jakub Antalik (libraries.dev), MIT, vendored in fx/companion/engine with a few local patches listed in fx/companion/NOTICE.
The blob is blobatar and @blobatar/vue, MIT, installed as packages.
API Reference
Companion
CompanionBot
CompanionBlob
Helpers
Accessibility
Keyboard shortcuts and ARIA behavior.
- A companion that is not clickable is decoration: it is hidden from screen readers and ignores the pointer.
- A clickable one is a button named by label.
- With prefers-reduced-motion the hop is skipped. The eyes still follow the pointer.
- The bot's canvas stops drawing when the tab is hidden.