# Keyframe.it > Keyframe.it is a free, browser-based 2D skeletal animation editor for game-ready sprites. Rig artwork with bones, deform it with weighted meshes, animate on a keyframe timeline, and export straight to pixi-spine — no install required. It is especially suited to animating slot-machine and game symbols. ## What it is Keyframe.it runs entirely in a modern web browser. It is aimed at game developers, slot/casino-game artists, and 2D animators who want a fast, free alternative for rigging and animating 2D sprites and exporting them to game engines via the Spine runtime (pixi-spine). ## Key features - Bone rigging with forward kinematics (FK) and inverse kinematics (IK) - Mesh deformation with bone weighting (skinning) for natural bending and squash & stretch - Spring physics for automatic secondary motion (tails, hair, cloth, ears) - Keyframe timeline with a curve/graph editor and dope sheet - A scripting API and typed MCP tools that let an AI agent drive the editor - Built-in AI-assisted rigging from an image, and AI animation from a text description - One-click slot-symbol animation pack: idle, win, drop and destroy clips at once - Slot-symbol starters that come with idle, land, anticipation and win clips already keyed - One-click win-FX library (coin shower, shockwave, light rays, payline streak, and more) - Import and export Spine bundles (.json + .atlas + .png) compatible with pixi-spine - Additional exports: GIF, sprite sheet, and video - PSD import (each layer becomes an animatable part) - Built-in image editor: layers with blend modes, full selection toolkit (lasso, polygon, rect/ellipse, custom shape, magic wand, select brush), brushes, bezier Pen paths, editable Text layers (custom .ttf/.otf fonts, thick outlines, 13 Photoshop-style warps, vertical text, distortion), gradients, clone, effects - Sheet slicer that cuts parts with boxes, ovals, freehand lasso, or a one-click magic wand (Shift adds regions to a part, Alt carves them out) ## Pricing Free to use in the browser. Optional AI features use the user's own Anthropic API key (billed to them); donations are optional. ## MCP server (easiest setup for MCP clients) There is an official MCP server on npm — `keyframe-mcp`. It opens this editor in the user's installed Chrome in a dedicated persistent profile and exposes the scripting API as tools, with rendered frames returned as real images. One line, no clone: claude mcp add keyframe -- npx -y keyframe-mcp Or in any MCP client's config: command `npx`, args `["-y", "keyframe-mcp"]`. Connector 0.2.0 adds named tools: keyframe_session, keyframe_list_projects, keyframe_open_project, keyframe_save, keyframe_build_animation, keyframe_configure_animation, keyframe_apply_pose, keyframe_contact_sheet, keyframe_check_animation, keyframe_export, keyframe_image_layers, keyframe_image_layer_png, keyframe_edit_image_layers and keyframe_open_result. keyframe_open (call first), keyframe_methods, keyframe_call {method, args} and keyframe_screenshot remain available. Requires Node 18+ and Google Chrome installed. The connector saves changes before responding. keyframe_open_result saves and opens a visible editor window; use keyframe_export format:project to transfer work to a different browser. It does not attach to the user's existing Chrome tabs. KEYFRAME_PROFILE_DIR selects storage (default ~/.keyframe-mcp/profile); use a separate profile for concurrent connector instances. KEYFRAME_HEADLESS=0 shows work as it happens. KEYFRAME_EXPORT_DIR selects the export folder (default ~/.keyframe-mcp/exports). Package: https://www.npmjs.com/package/keyframe-mcp Everything below works either way — through the MCP server, or by driving `window.keyframe` directly in a browser you control. ## For AI agents driving the editor First await keyframe.ready(): the API appears before saved projects finish restoring. Read sessionInfo() for projectId/revision; pass those as the expected argument to buildAnimation, configureAnimation and editImageLayers to reject stale edits. New workflow methods return {ok:false,error} on failure. MCP also sets isError:true. Recommended animation workflow (browser API; the named MCP tools expose schemas): await keyframe.ready(); const expected = keyframe.sessionInfo(); keyframe.buildAnimation({ name: 'idle', duration: 2, fps: 24, loop: true, poses: [ {time: 0, bones: {root: {y: 0, scaleY: 1}}}, {time: 1, bones: {root: {y: -6, scaleY: 1.03}}} ] }, expected); await keyframe.renderContactSheet('idle', {samples: 8, size: 256}); await keyframe.inspectAnimation('idle'); await keyframe.saveProject(); await keyframe.exportArtifact({format: 'project', download: true}); buildAnimation validates the ENTIRE clip before one document update/undo step. Use actual unique bone names from getState. Transform channels: x,y,rotation, scaleX,scaleY,shearX,shearY. Partial values carry forward from setup, not the current playhead. Each time appears once; combine its bones into one pose. Easing defaults to easeInOut; linear, step, easeIn, easeOut, bezier are supported. Bezier requires [x1,y1,x2,y2] with x coordinates in 0..1. loop:true copies the first pose to duration, overriding any supplied end pose. Existing clip names require replace:true, which replaces all that clip's tracks. Limits: duration .05–120s, 1–2048 poses, FPS 1–60. FPS is project-wide. configureAnimation(name,{duration?,fps?},expected?) rejects shortening past existing keys/events. renderContactSheet(name?,{samples?:2..24,size?:64..512}) returns a PNG dataUrl, timestamps, emptyFrames and edgeFrames (possible clipping). It uses one auto-fit camera, not a game viewport. inspectAnimation(name?,{samples?:2..60}) reports loop endpoint discontinuities, sampled invisible parts and rig problems. Intentional fades/hides and non-looping clips can produce warnings; endpoint transform checks exclude spring simulation. Review rendered motion too. exportArtifact({format:'project'|'gif'|'spine',animation?,version?:'3.8'|'4.2', binary?,size?,fps?,download?}) returns {artifact:{name,mimeType,bytes,dataUrl}}. Project JSON preserves editable image layers. Spine ZIP contains textures, atlas, skeleton and test.html. Binary requires 4.2. GIF limits: size64–1024, FPS1–60, up to1200 frames and64 million frame-pixels. MCP writes the bytes to a local file and returns a resource link; resources/read can retrieve exports from that session. Image layers: getImageLayers(assetName) returns stable layer IDs in bottom-to-top order. getImageLayerPng(assetName,id) returns pixels. editImageLayers(assetName, operations,expected?) validates and commits a batch of 1–100 operations atomically: - {action:'add',name,src} for an embedded PNG/JPEG/WebP/SVG layer, or {action:'add',name,text} - {action:'update',id,patch:{name?,visible?,locked?,opacity?:0..1,mode?,text?}} - {action:'move',id,targetId,above:boolean} - {action:'delete',id} Text fields on add: str,font,size,bold,italic,outline,fill,stroke,x,y. Optional warp, vertical,distH,distV match the image editor. On update text fields merge with the existing text. Use installed/loaded fonts. Pixels use the asset's canvas dimensions; larger layers are clipped. Locked layers must be unlocked in a separate operation before content edits; a locked or final layer cannot be deleted. Close/Apply any human image-editor session before agent layer edits. Failed batches leave pixels and editable metadata unchanged. At most100 layers per asset. listProjects(), openProject(id) and saveProject() use this browser profile's local project storage. Different browsers/profiles have separate projects. Import/export project JSON to transfer them. Save before closing or handing off a direct browser session. The stage is a canvas — there is no DOM to read, and dragging pixels is slow and error-prone. Instead use the scripting API exposed on `window.keyframe` (available on every page load, no setup): - `window.keyframe.help()` — one line per method; start here - `window.keyframe.describe()` — mode, active animation, playhead, counts - `window.keyframe.getState()` — the whole document as JSON: bones (with parents and setup transforms), slots, animations with their keyed bones - `window.keyframe.getBone(name)` / `getWorldTransforms()` — numeric world positions and rotations at the current playhead. Verify poses with numbers, not screenshots. - `window.keyframe.poseBone(name, {x?, y?, rotation?, scaleX?, scaleY?})` — set bone values by name. Setup mode edits the rig; animate mode KEYS the pose at the playhead. - `applyPose({bone: patch, ...}, {time?})` — set MANY bones in one call (one undo step); `time` moves the playhead first. One call per animation frame. - `await renderFrame({time?, animation?, size?})` — a PNG data URL of the posed character, no UI chrome. LOOK at your pose after setting it, then adjust. - `await renderClip(animName?, {fps?, size?})` — an animated-GIF data URL of a whole clip, to judge the motion itself. - `checkpoint(label?)` / `listCheckpoints()` / `revertTo(idOrLabel)` — snapshot the document before an experiment and roll back cleanly if it didn't work. - `window.keyframe.keyBone(name)`, `deleteKey(name, time)`, `setPlayhead(seconds)`, `setMode('setup'|'animate')`, `setActiveAnimation(name)`, `createAnimation(name)`, `play()`, `pause()`, `undo()`, `redo()`, `selectBone(name)` - `getKeys(animName?)` — EVERY keyframe in a clip: per-bone transforms PLUS per-part `slotTracks` (colour keys incl. alpha, image swaps, mesh deform), draw-order and events. If a part is mysteriously invisible at some time, look here FIRST — a stray alpha-0 colour key shows up plainly in `slotTracks[part].color`. - `tintPart(partName, {r,g,b,a}|null, {time?, easing?})` — RGBA multiply tint (each 0..1). `easing:'step'` holds the colour until the next key (blinking lights). Setup mode sets the static tint (null clears); animate mode KEYS it at the playhead (fades, hit-flashes, glow pulses). `deleteColorKey(partName, time)` removes one colour key; `clearColorTrack(partName)` wipes the part's whole tint track from the active clip — the rescue when stray colour keys are hiding a part. - Rig editing: `addBone(parentName, {name?, x?, y?, rotation?, length?})`, `splitBone(name, t?)` (insert a joint mid-bone), `setBoneEndpoints(name, {start?, end?})` (reposition by WORLD start/end points — children keep their placement), `reparentBone(name, newParent)`, `renameBone`, `setBoneLength`, `deleteBone(name)` (removes the bone AND its child bones; parts always survive, reattaching to the parent bone with their world placement kept) - `screenFromWorld(x, y)` / `worldFromScreen(clientX, clientY)` — convert between world and viewport coordinates for the rare click the API doesn't cover. (In the UI, Alt-dragging a bone's joint/tip in setup mode moves just that endpoint too.) - Meshes: `await autoMesh(slotNames?)` traces deform meshes for parts, then `bindWeights(slotNames?)` binds them to nearby bones — parts bend at joints instead of staying rigid. Do this after rigging, before animating. - IK: `listIk()`, `addIk(boneName)`, `setIkTarget(name, x, y)` (world coords — setup edits the rig, animate KEYS it at the playhead), `setIkMix(name, 0..1)`. Plant feet / aim hands with IK targets instead of solving FK angles. - Curves: `setKeyEasing(bone, time, easing, bezier?)` — vary easing deliberately; uniform easeInOut everywhere reads as floaty. - Springs & wind: `setSpring(boneName, {stiffness?, damping?, gravity?, wind?, motion?} | null)` puts sway physics on a bone — automatic secondary motion for tails, hair, cloth, rising smoke (springs bake to FK keys on Spine export); `setWind({strength?, speed?})` drives all spring bones globally. - Draw & blend: `reorderPart(partName, -1|1)` steps a part back/front in draw order (animate mode keys it); `setBlend(partName, 'normal'|'additive'|'multiply'| 'screen')` — additive/screen for glows and smoke. - Game markers: `addPoint(boneName, {x, y, rotation?, name?})` / `movePoint` / `deletePoint` / `listPoints()` — point attachments in WORLD coords (muzzle flashes, emitters). `addBox(boneName, {points?, name?})` / `deleteBox` / `listBoxes()` — bounding-box hit areas (WORLD polygons). Both export to Spine. - Clipping: `setClip(partName, worldPoints[], {endPart?, inverse?})` turns a part into a mask over the parts drawn after it (windows, portals, iris wipes); `clearClip(partName)` removes it. - Events: `addEvent(name, time, {string?, int?, float?, audio?, volume?, balance?}?)` / `deleteAnimEvent(name, time?)` — named timeline markers with payloads, exported for game runtimes (footsteps, sfx cues). - Skins: `listSkins()` / `setSkin(name|null)` — per-part image override sets (outfits, or the characters of an imported multi-skin rig like goblins). renderFrame/renderClip and exports honor the active skin. - Win FX: `await listFx()` catalogs the one-click effect packs (win glow, light rays, sparkle & star bursts, shockwave/pulse rings, coin shower, confetti, payline streak, electric arcs, orbiting sparkles, shine sweep, hit flash, pop, anticipation). `await addFx(id, {count?, intensity?, tint?, strength?})` keys one into the `win` clip (idempotent — re-apply to retune); `await removeFx(id)` removes just that pack. Apply these as the FINISHER after the motion is done. - NOT scriptable yet (ask the human instead of clicking): path constraints, transform constraints, sliders, and the graph editor's bezier handles beyond setKeyEasing. - `await validate()` — the editor's Problems lint as JSON. Run it before saying you're done, and fix what it reports. - `swapImage(partName, imageName|null, {fade?, time?})` — swap which image a part shows. Setup mode = permanent; animate mode KEYS the swap at the playhead, and `fade` (seconds) crossfades it in — 0 for blinks, ~0.15 to melt mood changes. (Fades against NOTHING — null→image or image→null, e.g. blinks — export to Spine as baked slot-alpha keys, so they fade there too. A crossfade between two real images still SNAPS in a Spine export: the format has no per-attachment alpha.) See `recipes('expression-swaps')` for the full face workflow. - Assets: `listAssets()`; `getAssetPng(name, maxSize?)` returns the art as a PNG data URL so you can LOOK at it directly; `cleanAsset(name, {removeBg?, tolerance?, cleanEdges?, trim?})` removes solid backgrounds (flood from the corners, or pass seed points), defringes halos and crops margins; `detectSprites(name)` previews sprite bounding boxes in a sheet; `sliceAsset(name, {rects?, addToScene?})` cuts a sheet into individual assets (auto-detects sprites when rects are omitted); `addAsset(name, dataUrl)`; `duplicateAsset(name)` copies an asset so you can experiment on the copy; `openImageEditor(name)` hands control to the human editor. Text labels ("WILD", "BONUS", …): render them yourself to an offscreen canvas (fillText/strokeText) and `addAsset(name, canvas.toDataURL())` — or suggest the human use the image editor's Text tool (editable text layers with custom fonts, thick outlines, and 13 warp styles like Arc/Bulge/Twist). Don't try to drive the editor's text UI yourself. Typical sheet workflow: `getAssetPng(sheet)` to see it → `detectSprites(sheet)` → adjust/confirm rects → `sliceAsset(sheet, {addToScene: true})` → `cleanAsset(...)` per piece if edges look fringed. (`sliceAsset` cuts rectangles only; the human Slice-sheet UI can also cut oval/lasso/magic-wand-shaped parts — suggest it if a rect crop would drag in surrounding art.) - `await window.keyframe.loadExample('noir')` — load a demo rig ('noir' is a full production character: weighted meshes, springs, smoke clips; also 'monkey', 'cat', and slot symbols); resolves when the doc is actually in (returns bone/part counts, safe to getState() right after) - `await window.keyframe.exportSpineJson('4.2')` — the document as Spine JSON, to check work end-to-end WORK FAST — round-trips and tokens are your budget: - BATCH: run several API calls in ONE JavaScript evaluation and return a single compact summary object. Ten separate evaluations for ten poses is the slow way; one evaluation that poses, samples `getWorldTransforms()`, and returns just the numbers you need is the fast way. - Return SUMMARIES, never dumps. `getState()` once at the start to learn names; after that use the cheap probes: `describe()` (counts + mode), `getBone(name)`, `getWorldTransforms()`. Don't echo whole documents or data URLs into your context. - Render SMALL while iterating: `renderFrame({size: 160})` / `renderClip(name, {size: 160, fps: 8})` — a data URL scales with size², and a 512px PNG can be hundreds of KB of base64. Render big once, at the end, as the deliverable. - Skip renders when numbers suffice: pose checks are `getWorldTransforms()` comparisons; only LOOK when judging art or motion quality. - Recipes exist for: slice-and-clean, expression-swaps, rig-character, mesh-and-weights, idle-animation, walk-cycle — `recipes(name)` before starting any of these beats discovering the order of operations by trial and error. Mutations return `{ ok: true }` or `{ ok: false, error }`; errors name valid alternatives. Methods take bone/animation NAMES (from `getState()`), never internal ids. API edits are undoable and update the UI live. Typical animation loop: `getState()` → `setMode('animate')` → `checkpoint()` → `applyPose({...}, {time: t})` per frame → `renderClip()` to judge the motion → adjust or `revertTo()` → `exportSpineJson()` when happy. BEFORE starting a multi-step task, call `window.keyframe.recipes()` and read the matching recipe (`recipes('walk-cycle')` etc.) — they encode the right ORDER of operations for slicing sheets, rigging, meshing/weights, idle loops and walks. `attachSlot(partName, boneName)` attaches parts to bones (world position kept). SAVING: the project AUTOSAVES to the browser continuously — there is no save button you need to press. (The "+ save layout" button in the top bar saves the PANEL arrangement, not the project.) Deliverables leave through the API: exportSpineJson(), renderClip(), renderFrame() — or the human uses the Export menu. RIG & ANIMATION CRAFT (what separates alive results from stiff ones): - LOOK before you rig: `getAssetPng()` / `renderFrame()` + `getState()` first, and identify what the object IS — creature, logo, vehicle, slot symbol. Design a rig for THIS object, not a humanoid template: bones at its natural pivots, named for what they control (`ear_l_base`, `hair_curl_tip`, `jaw`, `wheel_front`). - Follow-through comes from CHAINS: give floppy parts a base→tip bone pair (or `splitBone`) and key the tip lagging the base by 1-2 frames — or skip the keys and `setSpring` the tip. Tips that move in lockstep with bases look like cardboard. - Mesh ONLY what must bend (`autoMesh` + `bindWeights` on trunks, tails, torsos). Ears, cheeks, whiskers, letters, coins: a pivoted bone reads just as well and exports lighter. Rigid part = plain region = crisp. - Loops (`idle` and friends): the LAST key must repeat the FIRST pose exactly — re-apply the t=0 pose at the end or the loop pops every cycle. - Slot-symbol clip conventions (match these names and meanings): `idle` = subtle seamless loop; `win` = big celebration that RETURNS to the idle pose; `destroy` = ends with NOTHING visible (scale/fly out + alpha to 0 on every part). - Key on the frame grid: read `getState().fps` (often 20-30) and put key times on multiples of 1/fps — humans can then edit your keys in the dope sheet, and the export bakes exactly what you authored. - Craft beats key count: anticipation before an action, overshoot and damped settling after it, STAGGERED timing across bones (head leads, accessories lag). BEFORE YOU SAY DONE: - `validate()` reports clean (or you explain what remains and why) - every looping clip returns to its first pose; `destroy` ends fully invisible - `renderClip()` each animation once at full size and actually LOOK at it - report back: what the asset is, the rig you built (bones + pivots), which parts are meshed vs rigid, and what you validated RULES THAT KEEP YOU OUT OF DEAD ENDS: 1. NEVER drive the editor with synthesized mouse/keyboard events — canvas drags, sliders, colour pickers and buttons are not reliably automatable, and failed clicks leave half-applied state behind (e.g. stray colour keys). Every keyable channel has an API method. If you genuinely can't find one, STOP and tell the user what's missing instead of clicking — that report is more valuable than a workaround. 2. `checkpoint('before-X')` BEFORE any experiment; if it goes sideways, `revertTo()` — never try to hand-undo a mess key by key. 3. Something invisible or moving wrong? Diagnose with data, not guesses: `getKeys()` lists every keyed channel per part; `renderFrame({time})` shows the truth at any instant; `validate()` lints the document. 4. Blinks/expressions are ATTACHMENT swaps (`swapImage` with `fade: 0`), never alpha-tint tricks — swaps export to Spine, per-frame alpha hacks read as bugs. Note: the app also has built-in AI Rig / AI Animate buttons under the 🧠 menu — those are for HUMAN users (they call a hosted model with the user's own Anthropic API key). As an agent, do NOT click them: do the rigging and animating yourself through this API — you'll do a better job with direct control, and it costs the user nothing extra. ## Links - Everything in one fetch (this file + every content page): https://www.keyframe.it.com/llms-full.txt - Free Spine alternative — comparison: https://www.keyframe.it.com/spine-alternative - Author animations for pixi-spine (with PixiJS v8 loading code): https://www.keyframe.it.com/pixi-spine - Slot symbol animation (idle/win/drop/destroy, win FX): https://www.keyframe.it.com/slot-symbol-animation - Web app: https://www.keyframe.it.com/ - Live demo deep links: https://www.keyframe.it.com/?example=noir (also: monkey, cat, gem, coin, seven, bell, cherry) --- # Full page content The sections below are the complete text of the site's content pages, inlined so an assistant can answer questions about Keyframe.it from a single fetch. --- # Free Spine Alternative in the Browser — Keyframe.it Source: https://www.keyframe.it.com/spine-alternative ## A free Spine alternative that runs in your browser Keyframe.it is a free 2D skeletal animation editor for game sprites. If you want Spine-style bone rigging, weighted mesh deformation, and a keyframe timeline — but you don’t want to buy a desktop license — you can do the whole workflow in a browser tab and export Spine-compatible bundles that load in pixi-spine and other Spine runtimes. No install, no signup, and your work autosaves locally. Try it now — open a full production rig ### What Keyframe.it covers - Bone rigging — FK hierarchies, bone splitting and reparenting, inverse kinematics with planted feet, transform and path constraints. - Weighted meshes — auto-traced deform meshes with bone weighting for natural bending, squash & stretch, and deform keyframes. - Animation — dope sheet, curve/graph editor with bezier easing, draw-order keys, image swaps with crossfades, animation events with payloads, skins. - Spring physics — automatic secondary motion for hair, tails, cloth and smoke that bakes to keyframes on export. - Export — Spine 3.8 and 4.2 bundles (.json or binary .skel + .atlas + packed .png), plus GIF, sprite sheet, and video. It imports existing Spine exports too. - Extras Spine doesn’t have — a built-in image editor and sheet slicer, AI-assisted rigging and animation, slot-symbol starters with clips already keyed, a win-FX library, and a scripting API any AI agent can drive. ### Honest differences | | Keyframe.it | Spine (Esoteric Software) | Price | Free | Paid desktop license (Essential/Professional) | Runs | In the browser, no install | Desktop app (Windows/Mac/Linux), works offline | Export | Spine-compatible 3.8 / 4.2 bundles | Native Spine format + official runtimes | Maturity | New and moving fast | 10+ years, deep ecosystem and docs | Runtime licensing | Exports load in community runtimes like pixi-spine; check your runtime’s license for commercial use | Official Spine Runtimes require a Spine editor license If you need offline desktop tooling or official runtime support contracts, buy Spine — it’s excellent software. If you want a fast, free, browser-based workflow that lands in pixi-spine — especially for slot and game symbols — that’s exactly what Keyframe.it is for. ### Try it in 10 seconds Live demos load instantly: noir character (meshes, springs, smoke) · monkey (breathing idle + blink) · slot symbol (idle/win/destroy pack) Open the editor Spine is a trademark of Esoteric Software LLC. Keyframe.it is an independent project and is not affiliated with or endorsed by Esoteric Software. More: author animations for pixi-spine · slot symbol animation · API docs for AI agents --- # Author pixi-spine Animations Free in the Browser — Keyframe.it Source: https://www.keyframe.it.com/pixi-spine ## Author animations for pixi-spine — free, in the browser PixiJS has first-class Spine runtimes, but every tutorial assumes you already own an editor that produces Spine files. Keyframe.it closes that gap: rig and animate your character in a browser tab, then export a Spine-compatible bundle (.json or binary .skel + .atlas + packed .png) that loads directly in spine-pixi-v8 (PixiJS v8) or pixi-spine (PixiJS v7). Free, no install, no signup. See a finished rig in the editor ### The workflow, end to end - Bring in art — drop in images, import a PSD (layers become parts), or slice a sprite sheet with the built-in slicer (boxes, lasso, magic wand). - Rig — draw bones over the art, attach parts, add IK where you need planted feet or aimed hands. Auto-mesh + auto-weights make parts bend at joints. - Animate — keyframe on a dope sheet with a curve editor; add spring physics for hair/tails/cloth (baked to keys on export); image-swap tracks handle blinks and expressions. - Export — choose Spine 4.2 (for spine-pixi-v8) or Spine 3.8 (for older pipelines). The bundle ships with a ready-to-open test.html so you can verify it before integrating. ### Load it in PixiJS v8 import { Application, Assets } from 'pixi.js' import { Spine } from '@esotericsoftware/spine-pixi-v8' const app = new Application() await app.init({ width: 800, height: 600 }) document.body.appendChild(app.canvas) Assets.add({ alias: 'skel', src: 'character.json' }) // from the Keyframe.it export Assets.add({ alias: 'atlas', src: 'character.atlas' }) await Assets.load(['skel', 'atlas']) const character = Spine.from({ skeleton: 'skel', atlas: 'atlas' }) character.position.set(400, 500) app.stage.addChild(character) character.state.setAnimation(0, 'idle', true) Every export also includes a standalone test.html preview wired to the same runtime, so “does it load in Pixi?” is answered before you write a line of integration code. The editor’s canvas and its exports are kept 1:1 by an automated parity suite that compares every frame against the official Spine runtime. ### For AI-driven workflows Keyframe.it exposes a scripting API (window.keyframe, 150+ methods) that coding agents like Claude Code can drive — slice, rig, animate and export without touching the UI. Docs live at keyframe.it.com/llms.txt. There's also an official MCP server, so any MCP client can drive the editor after a one-line install: claude mcp add keyframe -- npx -y keyframe-mcp It opens the editor in your own Chrome and returns rendered frames as real images, so the model can see the animation it's building — see keyframe-mcp on npm. Start animating Spine is a trademark of Esoteric Software LLC; pixi-spine and spine-pixi-v8 are their respective maintainers’ projects. Keyframe.it is an independent tool — check your runtime’s license terms for commercial projects. More: free Spine alternative · slot symbol animation --- # Slot Symbol Animation Tool — Idle, Win & Destroy Clips Free — Keyframe.it Source: https://www.keyframe.it.com/slot-symbol-animation ## Animate slot symbols in your browser — idle, win, drop, destroy Slot games need every symbol animated the same way: a subtle idle loop, a big win celebration that returns to rest, and a destroy that clears the reel. Keyframe.it is a free, browser-based animation editor built around exactly that workflow — from raw art to a game-ready pixi-spine bundle, GIF, sprite sheet or video, with no install and no signup. Open a live slot symbol demo ### Built for symbol work - Symbol starters with clips already keyed — pick a cell size and get idle, land, anticipation and win animations to tune on the dope sheet, rather than starting from an empty timeline. - One-click AI animation pack — generate the full idle / win / drop / destroy set for a symbol at once (uses your own Anthropic API key), then refine each clip by hand. - Win FX library — coin showers, shockwave rings, light rays, sparkle bursts, payline streaks, electric arcs, shine sweeps, hit flashes and anticipation shakes, keyed into your win clip with one click. - Slot-symbol canvas guides — cell-size guides (256²–1024²) so art sits correctly in the reel cell with FX headroom. - Spring physics — hair, cloth, chains and smoke sway automatically and bake to keyframes on export. - Character symbols too — full bone rigs with weighted meshes and IK for premium character symbols, like the noir character demo. - Every export a slot pipeline needs — Spine 3.8/4.2 bundles for engine integration, GIF/video for pitches, sprite sheets for lightweight reels. ### Works with PixiJS-based slot engines Modern slot front-ends — including stake-engine games — are built on PixiJS, where symbol animation is Spine-format skeletal animation. Keyframe.it exports load directly in spine-pixi-v8 / pixi-spine, and every export ships with a test.html preview so you can verify the clips before integration. See the pixi-spine loading guide for the exact code. ### Fits how studios actually work Artists can slice a symbol sheet, clean edges, and add text labels ("WILD", "BONUS") in the built-in image editor without round-tripping to Photoshop. Teams can package a whole project (art + rig + animations) into one file to share. And AI agents can drive the entire editor through its scripting API — useful for batch-animating symbol sets. Animate your first symbol now More: free Spine alternative · author animations for pixi-spine --- # Animation examples you can make your own · Keyframe.it Source: https://www.keyframe.it.com/examples Animation examples you can make your own · Keyframe.it - - - Skip to contentKeyframe.itExamplesLearnOpen editor ↗Start with something moving ## Animation examples Look inside a finished rig. Change one thing. Make it yours. AllCharactersGame symbolsAdvanced Breathing monkeyLive animation CharactersPlay Interactive preview loads when visible. CharactersBreathing monkeyA hand-rigged character with a gentle breathing idle and blink. A friendly first project for learning bones and keyframes. Explore this example → Gem win animationLive animation Game symbolsPlay Interactive preview loads when visible. Game symbolsGem win animationA sparkling gem with ready-made idle, land, anticipation and win clips. Explore squash, stretch, glow and a moving shine. Explore this example → Coin animation packLive animation Game symbolsPlay Interactive preview loads when visible. Game symbolsCoin animation packA gold coin with four animation clips, additive glow and sparkle effects. Start with the pack, then make the timing your own. Explore this example → Cat characterLive animation CharactersPlay Interactive preview loads when visible. CharactersCat characterAn editable character example for exploring the relationship between artwork, bones and animated poses. Explore this example → Noir characterLive animation AdvancedPlay Interactive preview loads when visible. AdvancedNoir characterA more detailed character with weighted meshes, spring motion and smoke clips. Open it when you are ready to explore a larger rig. Explore this example → Cherry animation packLive animation Game symbolsPlay Interactive preview loads when visible. Game symbolsCherry animation packA cherry symbol with an editable rig and four clips. A compact example for learning timing, bounce and game feedback. Explore this example → Made for the little things that move. · Keyframe.itSpine alternativePixiJS workflowFor AI agentsMCP connector --- # Breathing monkey — editable animation example · Keyframe.it Source: https://www.keyframe.it.com/examples/monkey Breathing monkey — editable animation example · Keyframe.it - - - Skip to contentKeyframe.itExamplesLearnOpen editor ↗← All examplesCharacters ## A character with a little life A hand-rigged character with a gentle breathing idle and blink. A friendly first project for learning bones and keyframes. Edit this animation ↗ Opens a new project. Your existing work stays in its own tab. Breathing monkeyLive animation Clip Play Interactive preview loads when visible. ### What you can try - See how a complete character is split into parts and connected with bones. - Scrub the idle animation, select a bone and adjust one keyed pose. - Export a GIF to share, or a Spine bundle to bring the character into your game. Follow the step-by-step guide → Made with Keyframe.it. Explore the rig, change the timing and export your own version. Made for the little things that move. · Keyframe.itSpine alternativePixiJS workflowFor AI agentsMCP connector --- # Gem win animation — editable animation example · Keyframe.it Source: https://www.keyframe.it.com/examples/gem Gem win animation — editable animation example · Keyframe.it - - - Skip to contentKeyframe.itExamplesLearnOpen editor ↗← All examplesGame symbols ## Make a game reward sparkle A sparkling gem with ready-made idle, land, anticipation and win clips. Explore squash, stretch, glow and a moving shine. Edit this animation ↗ Opens a new project. Your existing work stays in its own tab. Gem win animationLive animation Clip Play Interactive preview loads when visible. ### What you can try - Switch between the four clips to see how one rig tells different moments. - Adjust the symbol bone's scale keys to change the squash and stretch. - Export a Spine 4.2 bundle with an atlas and a ready-to-open preview. Follow the step-by-step guide → Made with Keyframe.it. Explore the rig, change the timing and export your own version. Made for the little things that move. · Keyframe.itSpine alternativePixiJS workflowFor AI agentsMCP connector --- # Coin animation pack — editable animation example · Keyframe.it Source: https://www.keyframe.it.com/examples/coin Coin animation pack — editable animation example · Keyframe.it - - - Skip to contentKeyframe.itExamplesLearnOpen editor ↗← All examplesGame symbols ## Give a coin a winning moment A gold coin with four animation clips, additive glow and sparkle effects. Start with the pack, then make the timing your own. Edit this animation ↗ Opens a new project. Your existing work stays in its own tab. Coin animation packLive animation Clip Play Interactive preview loads when visible. ### What you can try - Play idle, land, anticipation and win from the timeline selector. - Move a keyframe to change the timing of the celebration. - Keep the editable project JSON alongside your game-ready export. Follow the step-by-step guide → Made with Keyframe.it. Explore the rig, change the timing and export your own version. Made for the little things that move. · Keyframe.itSpine alternativePixiJS workflowFor AI agentsMCP connector --- # Cat character — editable animation example · Keyframe.it Source: https://www.keyframe.it.com/examples/cat Cat character — editable animation example · Keyframe.it - - - Skip to contentKeyframe.itExamplesLearnOpen editor ↗← All examplesCharacters ## Explore a complete character rig An editable character example for exploring the relationship between artwork, bones and animated poses. Edit this animation ↗ Opens a new project. Your existing work stays in its own tab. Cat characterLive animation Clip Play Interactive preview loads when visible. ### What you can try - Select a part in the hierarchy to find its bone and artwork. - Explore the supplied clips and compare their keyed poses. - Save a project copy before experimenting with the rig. Follow the step-by-step guide → Made with Keyframe.it. Explore the rig, change the timing and export your own version. Made for the little things that move. · Keyframe.itSpine alternativePixiJS workflowFor AI agentsMCP connector --- # Noir character — editable animation example · Keyframe.it Source: https://www.keyframe.it.com/examples/noir Noir character — editable animation example · Keyframe.it - - - Skip to contentKeyframe.itExamplesLearnOpen editor ↗← All examplesAdvanced ## Look inside a production rig A more detailed character with weighted meshes, spring motion and smoke clips. Open it when you are ready to explore a larger rig. Edit this animation ↗ Opens a new project. Your existing work stays in its own tab. Noir characterLive animation Clip Play Interactive preview loads when visible. ### What you can try - Inspect the meshes and see how their vertices follow the bones. - Play the clips to observe the spring-driven secondary motion. - Compare the editor result with the preview included in a Spine export. Follow the step-by-step guide → Made with Keyframe.it. Explore the rig, change the timing and export your own version. Made for the little things that move. · Keyframe.itSpine alternativePixiJS workflowFor AI agentsMCP connector --- # Cherry animation pack — editable animation example · Keyframe.it Source: https://www.keyframe.it.com/examples/cherry Cherry animation pack — editable animation example · Keyframe.it - - - Skip to contentKeyframe.itExamplesLearnOpen editor ↗← All examplesGame symbols ## Build a playful symbol animation A cherry symbol with an editable rig and four clips. A compact example for learning timing, bounce and game feedback. Edit this animation ↗ Opens a new project. Your existing work stays in its own tab. Cherry animation packLive animation Clip Play Interactive preview loads when visible. ### What you can try - Compare a quiet idle with a more expressive win animation. - Adjust transform keys and use Undo to explore variations. - Export a GIF preview and keep the editable project for your next iteration. Follow the step-by-step guide → Made with Keyframe.it. Explore the rig, change the timing and export your own version. Made for the little things that move. · Keyframe.itSpine alternativePixiJS workflowFor AI agentsMCP connector --- # Learn 2D animation with Keyframe · Keyframe.it Source: https://www.keyframe.it.com/learn Learn 2D animation with Keyframe · Keyframe.it - - - Skip to contentKeyframe.itExamplesLearnOpen editor ↗From first keyframe to game-ready ## Make something move. Three small projects to help you learn the workflow. Learn by doingGive a character a breathing idleStart with a rigged monkey, change a pose and export your first loop. Learn by doingTake a game symbol from Keyframe to PixiJSPreview a gem, export a Spine bundle and verify it before adding it to your game. Learn by doingBuild and review an animation with an AI agentConnect an MCP client, give it a clear brief and inspect the result before export. Made for the little things that move. · Keyframe.itSpine alternativePixiJS workflowFor AI agentsMCP connector --- # Give a character a breathing idle · Keyframe.it Source: https://www.keyframe.it.com/learn/animate-a-character Give a character a breathing idle · Keyframe.it - - - Skip to contentKeyframe.itExamplesLearnOpen editor ↗← All guidesA practical walkthrough ## Give a character a breathing idle Start with a rigged monkey, change a pose and export your first loop. Open the monkey example ↗ ### 1. Open the example and watch a loop Open the monkey example below. Play its idle clip, then pause and scrub the timeline. Notice which parts move together. The hierarchy connects each piece of artwork to the bone that moves it. ### 2. Make a small change Select a body bone in the hierarchy and switch to Animate mode. Select an existing keyframe near the middle of the idle clip. Make a small change to vertical position or scale in the inspector. Start with a subtle change; large breathing movements tend to look like jumping. ### 3. Check the seam Scrub from the last frame back to the first. Their poses should match for a seamless loop. If your edit makes the character snap, undo it and change a middle pose instead. Play several loops and check that feet and other planted parts stay steady. ### 4. Export and keep an editable copy Open Export, choose GIF and render the active animation. Use project JSON to keep an editable backup; a GIF contains rendered frames, not the bones and keyframes. Your project also autosaves in this browser. Next experiment: delay a head movement slightly after the body movement. That small offset can make the motion feel less mechanical. Made for the little things that move. · Keyframe.itSpine alternativePixiJS workflowFor AI agentsMCP connector --- # Take a game symbol from Keyframe to PixiJS · Keyframe.it Source: https://www.keyframe.it.com/learn/export-to-pixijs Take a game symbol from Keyframe to PixiJS · Keyframe.it - - - Skip to contentKeyframe.itExamplesLearnOpen editor ↗← All guidesA practical walkthrough ## Take a game symbol from Keyframe to PixiJS Preview a gem, export a Spine bundle and verify it before adding it to your game. Open the gem example ↗ ### 1. Choose the motion Open the gem example and switch clips in the timeline. Adjust the scale or timing of a win keyframe, then play the clip again. Save the editable project JSON alongside your game assets. ### 2. Match the runtime version Open Export and select Spine. Choose Spine 4.2 for a compatible Spine 4.2 runtime, such as spine-pixi-v8 with PixiJS 8. Choose 3.8 for a compatible legacy runtime. The skeleton version and runtime version must agree; follow the runtime documentation for installation and licensing. ### 3. Inspect the bundle The ZIP contains a skeleton, an atlas, texture pages and a test.html preview. Extract the files together. Serve the folder with a local web server and open the preview to check the clips, transparency and framing before integrating them into your game. ### 4. Bring it into the game Put the skeleton, atlas and textures in your game's public assets folder. Load them with your chosen Spine runtime, then play a clip using the name shown in the editor. Keep relative texture paths intact. Export limits: clips bake constraints and secondary motion into keys. Weighted meshes and deformation keys are included. Inverse clipping and attachment crossfades need particular care; compare the exported result with the editor. PixiJS integration guide → Official spine-pixi documentation → Made for the little things that move. · Keyframe.itSpine alternativePixiJS workflowFor AI agentsMCP connector --- # Build and review an animation with an AI agent · Keyframe.it Source: https://www.keyframe.it.com/learn/animate-with-an-agent Build and review an animation with an AI agent · Keyframe.it - - - Skip to contentKeyframe.itExamplesLearnOpen editor ↗← All guidesA practical walkthrough ## Build and review an animation with an AI agent Connect an MCP client, give it a clear brief and inspect the result before export. Open the coin example ↗The Keyframe MCP connector uses a dedicated Chrome profile so projects can persist between sessions. Install Node.js 18 or newer and Google Chrome, then add this server in your MCP client's settings and reconnect it: {"mcpServers":{"keyframe":{"command":"npx","args":["-y","keyframe-mcp"]}}} ### 1. Give it a specific brief Try this: Open Keyframe and load the coin example into a new project. Inspect the available bones and clips. Make a two-second looping celebration with a gentle squash, rise and settle. Keep the symbol inside the frame. Preserve the existing clips. ### 2. Ask for evidence Ask the agent to run keyframe_check_animation and keyframe_contact_sheet, then render a motion preview. Check the loop seam, framing and timing. A successful tool call does not guarantee a good animation; refine the brief and inspect the result. ### 3. Keep the editable result Ask for a project JSON export and a GIF preview. Use keyframe_open_result to save and open visible Chrome for manual edits. The connector's profile is separate from your usual browser; import the project JSON there to transfer the project. The connector is free. Model usage follows the pricing of your chosen AI client. The editor's optional built-in AI is a separate feature that uses your own provider key. Connector setup and tool reference → Browser scripting reference → Made for the little things that move. · Keyframe.itSpine alternativePixiJS workflowFor AI agentsMCP connector