Laser Body — Multi-Person Stickman Studio

A browser-native full-body pose tracker that turns up to six people into glowing skeletons

WebAI No backend TensorFlow.js MoveNet MultiPose

What it is

Laser Body is a self-contained single HTML file that uses your device's camera to detect the full-body pose of every person visible, then renders each of them as a glowing multicolor stickman skeleton. Up to six people are tracked simultaneously — walk into frame with friends and everyone lights up with their own moving body of light.

Where Laser Hands tracks 21 fingers-and-palm landmarks per hand for close-up gesture work, Laser Body tracks 17 major body landmarks per person (head, shoulders, elbows, wrists, hips, knees, ankles) for full-body movement across a room. Both apps run entirely on-device — no video ever leaves the browser tab.

Delivery

1 HTML file

Dependencies

0 installed

Body landmarks

17 per person

Max people

6 simultaneous

Backbone

MoveNet Lightning

Backend calls

Zero

How to open it

Like all camera-based browser apps, this must be served over a secure origin — https:// or http://localhost. Direct file:// access is blocked by the browser for camera security.

▸ Python — python -m http.server 8080 in the file's folder, open http://localhost:8080/laser-body.html
▸ Node — npx serve . and use the printed link
▸ Static host — Netlify, Vercel, or GitHub Pages all serve over HTTPS automatically

Pose detection

MoveNet MultiPose is Google's real-time multi-person pose model, distributed via TensorFlow.js. It runs entirely in the browser using WebGL for GPU acceleration — every frame from your camera is passed through the neural network, which returns a list of detected people, each with their 17 keypoint coordinates and per-keypoint confidence scores.

🧍

Single person

Stand in front of the camera at full body distance (3–5 feet works best). Your skeleton renders in real time with a colored glowing outline.

👥

Multi-person

Up to 6 people simultaneously. Each person is tracked as a separate pose object and rendered with their own color scheme.

💃

Full-body motion

Dance, stretch, jump — every joint is tracked at 30+ fps on modern devices. Great for movement art, warmups, or performance capture visualization.

🤸

Partial occlusion

The model gracefully handles partial visibility — hidden limbs get low confidence scores and are omitted from rendering rather than drawing incorrectly.

Skeleton topology

MoveNet returns 17 canonical keypoints per person: nose, both eyes, both ears, both shoulders, both elbows, both wrists, both hips, both knees, both ankles. The app draws a curated set of connections between these to form a stickman — spine, arms (shoulder-elbow-wrist), and legs (hip-knee-ankle) — plus head decorations connecting the facial landmarks.

Keypoints per person

17 (nose to ankles)

Backbone model

MoveNet Lightning

Backend

WebGL (GPU)

Coordinate space

Pixels (mapped to canvas)

Confidence threshold

Per-keypoint filtering

Mirror correction

x = w − x

Technology stack

TensorFlow.js Core

JavaScript ML runtime

CDN · v4.10

TF.js Converter

Loads MoveNet's graph model format

CDN · v4.10

TF.js WebGL backend

GPU-accelerated tensor ops via WebGL shaders

CDN · v4.10

pose-detection model

MoveNet MultiPose Lightning wrapper

CDN · v2.1

HTML5 Canvas 2D

All skeleton rendering and glow effects

Native browser

WebRTC getUserMedia

Camera stream access

Native browser

How MoveNet works (non-technical)

MoveNet is a neural network trained on millions of images of people. When you load it in the browser, TensorFlow.js unpacks the model into your device's GPU using WebGL. Every frame from your camera, MoveNet finds each person in the image and marks 17 key body points — nose, shoulders, elbows, and so on down to the ankles. The app connects those points with glowing lines to make a stickman, and does this for every person at the same time.

How MoveNet works (technical)

The detection pipeline:

getUserMedia stream
→
<video> element
→
detector.estimatePoses()
→
WebGL inference
→
poses[] array
→
Canvas render

MoveNet MultiPose Lightning is optimized for speed over accuracy. The Lightning variant achieves ~30+ fps on modern mobile devices; the Thunder variant offers higher accuracy at lower fps. This app uses Lightning for its multi-person mode because interactive art favors responsive tracking of many bodies over perfect landmarks on one.

The render loop uses requestAnimationFrame; pose inference runs in parallel (async). The render loop reads whatever the latest inference produced — decoupling the two means dropped inference frames don't stall rendering, and vice versa.

Rendering techniques

Glowing skeleton lines

Each bone connection is drawn with a three-pass technique similar to Laser Hands: a wide soft outer glow using shadowBlur, a crisp colored core line, and a hot white center line. This creates the neon tube effect without any post-processing shaders or filters.

Per-person color assignment

Each detected person gets a distinct color scheme — the app assigns colors by tracking pose IDs across frames so the same person keeps the same color even as they move. When someone leaves and re-enters the frame, they may get a new color since MoveNet has no cross-frame identity system built in.

Per-keypoint confidence filtering

Each of the 17 keypoints returns a confidence score from MoveNet. If a keypoint's confidence is below a threshold (typically because the joint is occluded), the connections touching that keypoint are skipped for that frame. This prevents the "jumping to origin" bug where hidden joints snap to (0,0) and draw a line across the whole canvas.

Mirror correction

The camera feed is mirrored horizontally so users see themselves as they'd appear in a mirror. All keypoint x-coordinates are flipped (x = width − x) before rendering so the skeleton overlays the visible video correctly.

Camera lifecycle and privacy

✓All inference runs on-device using WebGL. Camera frames never leave your browser.
✓When the tab is backgrounded, the camera stream is stopped and the OS indicator light goes off.
✓Closing or navigating away releases the camera immediately via pagehide/beforeunload.
⚠Requires https:// or http://localhost. Camera access is blocked on file:// by browser security policy.
⚠Initial model load requires network access to CDN. Once loaded, no further requests are made.

Architecture overview

The entire app is a single flat script — no bundler, no framework, no build step. Model loading happens once at startup; a loading spinner shows during the ~2–3 second initial download and warmup. Once loaded, all subsequent inference runs against the already-loaded model in GPU memory.

State is a single state object holding the latest pose results, per-person color assignments, and rendering options. The render and detect loops are decoupled — the render loop consumes whatever pose data the detect loop last produced, so dropped inference frames never stall rendering.

The bone-connection table (BODY_CONNECTIONS) is a plain array of keypoint-index pairs. Adding or removing skeleton features means editing this array — no other code changes required.