Doop
Doop is an open-source multiplayer design canvas and design MCP for Claude Code, Codex, and any AI agent. Design side by side with agents — free in beta.
Open-source character animation engine. 8 elemental GLSL shaders, 339 gestures (179 core + 160 elemental), Canvas 2D + WebGL 3D.
Translation pending
DesignJavaScript · TypeScriptGitHub @joshtolOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Character animation for the web: emotions, gestures and elemental GLSL shaders. Canvas 2D and WebGL 2. MIT.
Taken from the repository README
Loading the full README.
Read the full README ↗Character animation for the web: emotions, gestures and elemental GLSL shaders. Canvas 2D and WebGL 2. MIT.
Real-time character animation engine with Canvas 2D and WebGL 3D rendering. 8 elemental shader systems. 160 elemental gestures. One replicable pattern.
Live · emotiveengine.com · Demo · elemental gestures · npm · @joshtol/emotive-engine · Status · active
npm install @joshtol/emotive-engine
import { EmotiveMascot3D } from '@joshtol/emotive-engine/3d';
const mascot = new EmotiveMascot3D({
coreGeometry: 'crystal',
assetBasePath: '/assets', // self-hosted assets (see below)
});
mascot.init(document.getElementById('container'));
mascot.start();
mascot.setEmotion('joy');
mascot.express('bounce');
mascot.morphTo('heart');
mascot.feel('happy, bouncing'); // Natural language control
3D mode requires Three.js (npm install three, version 0.170 or later) and a
browser with WebGL 2. Without WebGL 2, init() logs a warning and renders
nothing; it does not fall back to Canvas 2D, which is the separate
@joshtol/emotive-engine import below.
import { EmotiveMascot } from '@joshtol/emotive-engine';
const mascot = new EmotiveMascot();
await mascot.init(document.getElementById('container'));
mascot.start();
mascot.feel('happy, bouncing');
2D mode has no dependencies and requires no external assets. Both modes need
Node 20 or later to build (engines).
Every build is a separate entry, so a page that shows one elemental does not pay
for the other seven. Sizes are brotli over the wire (npm run size:report);
Three.js is a peer dependency and is not included in the 3D numbers.
| Import | Brotli | What you get |
|---|---|---|
@joshtol/emotive-engine | 178 KB | 2D canvas engine |
@joshtol/emotive-engine/lean | 166 KB | 2D, no rhythm sync / accessibility / profiling |
@joshtol/emotive-engine/minimal | 67 KB | 2D loading-screen build |
@joshtol/emotive-engine/3d | 232 KB | 3D, no elementals |
@joshtol/emotive-engine/3d-<element> | 249 to 256 KB | 3D + one elemental (see below) |
@joshtol/emotive-engine/3d-elementals | 303 KB | 3D + all eight elementals |
The eight single-element entries are 3d-fire, 3d-water, 3d-ice,
3d-electric, 3d-earth, 3d-nature, 3d-light and 3d-void. Each registers
only its own element and gestures; the other elements' shaders and gestures are
not in the file.
// A page that only shows the electric elemental
import { EmotiveMascot3D } from '@joshtol/emotive-engine/3d-electric';
const mascot = new EmotiveMascot3D({
coreGeometry: 'crystal',
assetBasePath: '/assets',
maxPixelRatio: 1.5, // cap the DPR (default 2.0): sharpness vs fill rate
hdri: false, // skip the optional 1.7 MB studio HDRI
glowHalo: false, // no screen-space halo when the canvas bleeds past its slot
surface: 'light', // or mascot.setSurface('light'): arcs drawn as ink on light pages
});
mascot.init(document.getElementById('container'));
mascot.start();
mascot.express('shock'); // any electric gesture; fire gestures etc. are not registered
A gesture from an element that is not in the entry is simply unknown to
express(). Import 3d-elementals when a page switches between elements.
Shared: 15 emotions · 179 gestures · Natural language feel() API ·
TypeScript definitions · Unified API
The npm package ships JavaScript only. GLB models, textures, and HDRI maps
must be self-hosted. They live in assets/ in this repository. The 3D engine
loads WebP textures (Crystal 282 KB, Moon 1.2 MB, Sun 0.8 MB); the PNG/JPEG
sources sit beside them and are not requested at runtime.
new EmotiveMascot3D({
assetBasePath: '/assets', // wherever you host the assets folder
});
| Hosting option | assetBasePath |
|---|---|
Copy to public/ | '/assets' |
| CDN / S3 | 'https://cdn.example.com/emotive-engine/assets' |
| GitHub Pages | 'https://joshtol.github.io/emotive-engine/assets' |
<assetBasePath>/
├── models/Elements/ # GLB models for elemental effects
├── textures/ # Crystal, Moon, Sun textures
└── hdri/ # Environment maps (optional)
<!-- 2D (UMD, no dependencies) -->
<script src="https://unpkg.com/@joshtol/emotive-engine/dist/emotive-mascot.umd.js"></script>
<!-- 3D (ESM, requires Three.js import map) -->
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/[email protected]/build/three.module.min.js"
}
}
</script>
<script type="module">
import { EmotiveMascot3D } from 'https://unpkg.com/@joshtol/emotive-engine/dist/emotive-mascot-3d.js';
</script>
| Doc | Description |
|---|---|
| API Reference | All methods, configuration options, emotions, gestures, geometries |
| LLM Integration | Natural language feel() API, system prompt examples |
| Gestures | Full gesture catalog (179 base + 160 elemental) |
| Quick Reference | Cheat sheet for emotions, undertones, and common patterns |
| Architecture | Internal design and rendering pipeline |
git clone https://github.com/joshtol/emotive-engine.git
cd emotive-engine
npm install && npm run build && npm run local
# → http://localhost:3000
MIT (SPDX MIT), © 2025-2026 Joshua Tollette. See LICENSE.md.
Created by Joshua Tollette