oneko.js, but anything chases your cursor.
o-nandemo (何でも) — "anything." the honorable cat, generalized: bring any sprite sheet and it wakes up, chases your mouse, and naps when it catches you.
one tag, zero config — the classic cat:
<script src="https://unpkg.com/onandemo/dist/onandemo.js"></script>swap the companion with data-preset="soldier" or data-preset="slime" — the
preset files ship inside the package and resolve from the script's own URL.
or bring a sheet (a grid of cells) and a frame map (which cells mean what):
<script
src="https://unpkg.com/onandemo/dist/onandemo.js"
data-sheet="./dino.png"
data-frame-map="./dino.json"
></script>or from npm — bun add onandemo:
import { onandemo } from "onandemo";
const destroy = onandemo(); // the cat
onandemo({ sheet: "/dino.png", frameMap }); // anythingplain JSON: a cell size and state-named lists of [col, row] cells. this one
is the classic cat's actual layout:
{
"cellSize": 32,
"states": {
"idle": [[3, 3]],
"alert": [[7, 3]],
"E": [
[3, 0],
[3, 1]
],
"W": [
[4, 2],
[4, 3]
],
"sleeping": [
[2, 0],
[2, 1]
]
}
}idle plus one run direction is a complete companion — missing directions
resolve down a ladder (mirror, snap, fall back) so a side-view-only sheet still
chases in all eight. alert is optional. any other state name is an antic:
a rare idle performance, triggered the oneko way — only after lingering, about
once every twenty seconds.
| knob | default | what it does |
|---|---|---|
sheet + frameMap |
— | your art and its map |
preset |
"neko" |
bundled companion by name |
speed |
10 |
chase speed in px per tick |
restRadius |
48 |
distance inside which it rests |
scale |
1 |
display multiplier |
zIndex |
2147483647 |
stacking |
persist |
true |
remember its position across loads |
every knob is also a data-* attribute on the script tag (data-speed="15").
inherited from oneko, engine behavior rather than options:
- bails out entirely under
prefers-reduced-motion— no element, no listeners. - never intercepts input and hides from assistive tech.
- the loop dies when the element leaves the DOM.
- remembers where it was (
persist: falseis the one opt-out). - ten frames per second, always. the shuffle is the charm.
every 100 ms the engine measures the distance to your cursor. past the rest
radius it runs one of eight directions at speed px per tick — the animation
is just background-position moving over your sheet, nothing else. inside the
rest radius it idles, and after lingering it might perform an antic from your
sheet. that is the whole product: 11.6 KB minified with the cat inlined — zero
dependencies, zero extra requests.
- more presets — shepardskin's CC0 cat (needs a repack), ninja adventure friends; receipts continue in NOTICE.md.
- onandemo.jass.gg — live demo, a recipe that hands you a sheet and its frame map (pick a layout tier), and a playground that drops the pair into a live, mint-able companion.
- npm
0.1.0— the engine above is built and tested; the publish is imminent. - a demo gif right here.
- chrome extension, then an electron desktop companion — the cat goes home.