codex-pets-react
v0.2.0
Published
Declarative React wrapper for Codex pet spritesheets.
Maintainers
Readme
Codex Pets React
Declarative React components and state helpers for Codex pet spritesheets.
Brought to you by Plannotator, the review surface for agent work: use it before an agent starts to sharpen plans, and after an agent finishes to review code.
The package includes:
SpriteAnimatorfor atlas row/frame playback.PetWidgetfor fixed-position rendering, dragging, pinning, and animation completion events.petReducerandusePetControllerfor state-driven app integration.- A shared
codexPetAtlasandCodexPetAnimationNamecontract for Codex pet spritesheets.
Install
npm install codex-pets-reactExample App
The plannotator pet playground lives in examples/plannotator-pet.
npm install
npm run devThe example loads Tater from /pets/tater/spritesheet.webp, exposes animation actions, screen pinning, dragging, a simulation toggle, automatic waiting, frame pausing, nudging, scaling, and a live state/event view.
Importing Codex Pets
Codex pets live on your machine under:
~/.codex/pets/<pet-id>/
├── pet.json
└── spritesheet.webpFor example, the included playground uses:
/Users/ramos/.codex/pets/tater/
├── pet.json
└── spritesheet.webpTo use one in a web app, copy the pet folder into your app's public assets and pass the public spritesheet URL to PetWidget:
mkdir -p public/pets/tater
cp ~/.codex/pets/tater/pet.json public/pets/tater/pet.json
cp ~/.codex/pets/tater/spritesheet.webp public/pets/tater/spritesheet.webpCodex pets share the same atlas contract, so render the copied spritesheet with codexPetAtlas:
<PetWidget
src="/pets/tater/spritesheet.webp"
atlas={codexPetAtlas}
animation={pet.animation}
position={pet.position}
pin={pet.pin}
draggable
onAction={petDispatch}
/>The pet.json file identifies the pet and its spritesheet path. The React wrapper needs the browser-accessible src plus codexPetAtlas, which describes the shared grid, frame rows, and frame durations.
Usage
import {
PetWidget,
codexPetAtlas,
usePetController,
type CodexPetAnimationName
} from "codex-pets-react";
export function PetLayer() {
const { pet, petDispatch } = usePetController<CodexPetAnimationName>({
initialState: {
animation: { name: "idle", mode: "loop" },
pin: "bottom-right"
},
defaultAnimation: "idle",
waitingAnimation: "waiting",
waitingAfterMs: 6000
});
return (
<PetWidget
src="/pets/tater/spritesheet.webp"
atlas={codexPetAtlas}
animation={pet.animation}
position={pet.position}
pin={pet.pin}
draggable
onAction={petDispatch}
/>
);
}Dispatch actions to drive the pet from app state:
petDispatch({
type: "animation.play",
animation: "waving",
mode: "once",
then: "idle"
});
petDispatch({ type: "pin.set", pin: "bottom-right" });
petDispatch({ type: "position.set", position: { x: 240, y: 420 } });
petDispatch({ type: "animation.set", animation: "waiting" });Drag Gesture Animations
Keep gesture animation opt-in by observing pet actions and dispatching follow-up animation actions:
const observeDragGesture = usePetDragGestureAnimations<CodexPetAnimationName>({
enabled: true,
animations: {
left: "running-left",
right: "running-right",
up: "jumping",
down: "waving"
},
restAnimation: "idle",
minimumDistance: 16,
axisBias: 1.12,
onGestureAction: petDispatch
});
const onAction = (action: PetAction<CodexPetAnimationName>) => {
petDispatch(action);
observeDragGesture(action);
};minimumDistance filters pointer jitter. axisBias requires one axis to clearly dominate before changing animations, so diagonal or shaky drags do not flicker between states.
Build
npm run buildThis typechecks the repo, emits library declarations to dist/types, builds the library to dist/lib, and builds the example to dist/examples/plannotator-pet.
