Embed a live 3D Posecode movement anywhere with one <script> tag.
posecode-embed ships a framework-free <posecode-player> web component. Drop
it into a blog post, docs page, physio program, or an LLM chat UI, and it renders
the movement as an animated 3D figure, right where a share link would have gone.
<script src="https://unpkg.com/posecode-embed@0.2.0/dist/posecode-embed.js"></script>
<!-- 1. From a share token (what a posecode.org permalink carries) -->
<posecode-player doc="cG9zZWNvZGUgZXhlcmNpc2Ug…"></posecode-player>
<!-- 2. From a URL to a .posecode file -->
<posecode-player src="/movements/squat.posecode"></posecode-player>
<!-- 3. From inline text: reads like the language itself -->
<posecode-player>
posecode exercise "Lateral raise"
rig humanoid
pose start = standing
step "Raise" 1.4s settle:
shoulders: abduct 90
elbows: flex 10
step "Lower" 1.6s drive:
shoulders: abduct 0
elbows: flex 0
repeat 8
</posecode-player>The script auto-registers the element and boots each player when it scrolls into view. That's it.
Pin a package version in production, as above, so a deployment always uses a
known parser/render pair. A src URL can be relative or absolute; cross-origin
movement files must be served with CORS permission.
npm install posecode-embedimport "posecode-embed"; // auto-registers <posecode-player>Or register it yourself for controlled timing:
import { definePosecodePlayer } from "posecode-embed";
definePosecodePlayer(); // idempotent| Attribute | Default | Description |
|---|---|---|
doc |
n/a | A posecode-share token (highest precedence). |
src |
n/a | URL of a .posecode file to fetch. |
| (inline text) | n/a | The element's text content, used if doc/src are absent. |
autoplay |
true |
Play as soon as the movement loads. |
loop |
true |
Loop the timeline. |
controls |
true |
Show the play/pause bar. |
autorotate |
true |
Slowly orbit the camera when idle. |
speed |
1 |
Playback multiplier (0.1–4). |
character |
(hosted default) | Realistic figure: a GLB URL (Mixamo rig), or off for the procedural mannequin. Load failures fall back to the mannequin. |
playground |
https://posecode.org/play |
Base URL for the "Edit ↗" link. |
Boolean attributes accept false / 0 / no / off to turn them off, so
autoplay="false" works as expected.
- Lazy & cheap. three.js loads only when a player scrolls into view; many embeds on one page stay idle until seen.
- Accessible. Honors
prefers-reduced-motion(no autoplay, no camera orbit) and exposes a labelled play/pause control. - Never blank. A bad token, a failed fetch, or an unparseable movement
renders a readable message instead of an empty canvas, and fires a
posecode:errorevent. - Isolated. Markup and styles live in a shadow root; nothing leaks into or out of the host page.
const player = document.querySelector("posecode-player");
player.addEventListener("posecode:ready", (e) => {
console.log(e.detail.version, e.detail.languageVersion, e.detail.warnings);
player.viewer.pause();
});
player.addEventListener("posecode:error", (e) => {
console.warn(e.detail.code, e.detail.error, e.detail.errors);
});
player.toggle(); // play / pause
player.viewer; // the underlying render Viewer (null until booted)The host element reflects data-posecode-state="loading|ready|error", plus the
package and language versions, for integration tests and monitoring. Existing
listeners that only read event.detail.error remain compatible.
CDN users can validate source without creating WebGL:
const result = Posecode.validatePosecode(source);
console.log(Posecode.version, Posecode.languageVersion, result.errors);For a movement library in CI, run:
npx posecode-parser@0.2.0 validate --strict ./movementsAGPL-3.0-only, part of Posecode. A separate commercial license is available for closed-source product use.