heyyarun/hands-free

design concept for gesture-based web scrolling

TypeScript

0

30 commits

updated Oct 6, 2026

See the code

See what people are saying

SourceMessageScoreDate

Making MediaPipe hand landmarks stable enough to scroll a web page and play a game, all in the browser (r/computervision)

I built a web page you control with a webcam: pinch and move your hand to scroll, pinch with both hands and pull them apart or together to zoom, and hold a Victory sign to open a T-Rex runner where a pinch jumps and a fist ducks. It runs MediaPipe's Gesture Recognizer (two hands) in the browser, so…

2

Oct 10, 2026

README

Hands Free

A web page you control with your hands. Your webcam feeds MediaPipe's hand-gesture model in the browser, and the gestures drive a three.js scene and a T-Rex runner game. No video leaves your machine.

Live at https://www.handfree.live/ — it needs a webcam and a browser with WebAssembly, and the model is fetched on first use.

Run it

Requires Node 22+ and a webcam.

npm install
npm run dev

Open http://localhost:5173 and click Start camera. The first run downloads the MediaPipe model (~8 MB) and copies its wasm runtime into public/ (both gitignored).

Gestures

Demo page (/)

GestureAction
Pinch, then move up/downScroll
Pinch both hands, move them apartZoom in
Pinch both hands, move them togetherZoom out
Hold a Victory signOpen T-Rex game

Scroll and zoom are relative to where the pinch started, so the page follows your hands one-to-one: zoom tracks the ratio between the two pinches, so the same gesture goes either way. Hold a Victory sign for a moment to open the T-Rex game.

Two animated glyphs stay fixed at the bottom of the screen while you interact — a pinching hand travelling up and down its track, and a pair of hands opening and closing between chevrons that light up in the direction currently being shown.

T-Rex game (/#game)

Open it from the "Play T-Rex with your hands →" link in the control panel.

GestureAction
PinchJump
FistDuck

Birds fly at three heights. Jump the low ones, duck under the middle ones, and run under the high ones.

Press D on either page for the debug panel.

Keyboard fallbacks (off)

The keyboard does nothing: hands are the only way to scroll the page or play the game.

For development without a camera, copy .env.example to .env.local, set VITE_KEYBOARD_CONTROLS=true and restart the dev server (the flag is read at build time). Each page then takes its own keys:

  • Demo page (/): ↑/↓ move between sections.
  • Game (/#game): space or ↑ jump, ↓ ducks.

Scripts

CommandWhat it does
npm run devDev server on port 5173
npm run buildProduction build to dist/
npm run previewServe the production build
npm run typecheckTypeScript check
npm testVitest unit tests

Project layout

src/
  App.tsx             demo page (three.js scene + story sections)
  main.tsx            hash routing between the page and #game
  cv/                 MediaPipe recognizer, landmark smoothing, gesture logic
  components/         shared camera layer
  game/               T-Rex runner: physics, obstacles, collision, rendering, hand input
  state/              shared frame/UI store
scripts/
  fetch-assets.mjs    stages the MediaPipe model and wasm into public/

Recording test samples

The pinch/fist thresholds are tested against recorded hand landmarks in src/game/fixtures/. To add real webcam samples: open /#game, press D, hold a pose with one hand and press P (pinch), F (fist) or O (other) with the other. Only the posed hand should be in view, because every visible hand gets the same label. Press S to download, save the file as src/game/fixtures/webcam-*.json, and run npm test.

Credits

T-Rex game rules and tuning are ported from Chromium's offline dino game (BSD license; its notice is kept in src/game/constants.ts). The sprites are original.

Built with offrun.dev.

License

MIT, see LICENSE.

heyyarun/hands-free

design concept for gesture-based web scrolling

TypeScript

0

30 commits

updated Oct 6, 2026

See the code

See what people are saying

SourceMessageScoreDate

Making MediaPipe hand landmarks stable enough to scroll a web page and play a game, all in the browser (r/computervision)

I built a web page you control with a webcam: pinch and move your hand to scroll, pinch with both hands and pull them apart or together to zoom, and hold a Victory sign to open a T-Rex runner where a pinch jumps and a fist ducks. It runs MediaPipe's Gesture Recognizer (two hands) in the browser, so…

2

Oct 10, 2026

README

Hands Free

A web page you control with your hands. Your webcam feeds MediaPipe's hand-gesture model in the browser, and the gestures drive a three.js scene and a T-Rex runner game. No video leaves your machine.

Live at https://www.handfree.live/ — it needs a webcam and a browser with WebAssembly, and the model is fetched on first use.

Run it

Requires Node 22+ and a webcam.

npm install
npm run dev

Open http://localhost:5173 and click Start camera. The first run downloads the MediaPipe model (~8 MB) and copies its wasm runtime into public/ (both gitignored).

Gestures

Demo page (/)

GestureAction
Pinch, then move up/downScroll
Pinch both hands, move them apartZoom in
Pinch both hands, move them togetherZoom out
Hold a Victory signOpen T-Rex game

Scroll and zoom are relative to where the pinch started, so the page follows your hands one-to-one: zoom tracks the ratio between the two pinches, so the same gesture goes either way. Hold a Victory sign for a moment to open the T-Rex game.

Two animated glyphs stay fixed at the bottom of the screen while you interact — a pinching hand travelling up and down its track, and a pair of hands opening and closing between chevrons that light up in the direction currently being shown.

T-Rex game (/#game)

Open it from the "Play T-Rex with your hands →" link in the control panel.

GestureAction
PinchJump
FistDuck

Birds fly at three heights. Jump the low ones, duck under the middle ones, and run under the high ones.

Press D on either page for the debug panel.

Keyboard fallbacks (off)

The keyboard does nothing: hands are the only way to scroll the page or play the game.

For development without a camera, copy .env.example to .env.local, set VITE_KEYBOARD_CONTROLS=true and restart the dev server (the flag is read at build time). Each page then takes its own keys:

  • Demo page (/): ↑/↓ move between sections.
  • Game (/#game): space or ↑ jump, ↓ ducks.

Scripts

CommandWhat it does
npm run devDev server on port 5173
npm run buildProduction build to dist/
npm run previewServe the production build
npm run typecheckTypeScript check
npm testVitest unit tests

Project layout

src/
  App.tsx             demo page (three.js scene + story sections)
  main.tsx            hash routing between the page and #game
  cv/                 MediaPipe recognizer, landmark smoothing, gesture logic
  components/         shared camera layer
  game/               T-Rex runner: physics, obstacles, collision, rendering, hand input
  state/              shared frame/UI store
scripts/
  fetch-assets.mjs    stages the MediaPipe model and wasm into public/

Recording test samples

The pinch/fist thresholds are tested against recorded hand landmarks in src/game/fixtures/. To add real webcam samples: open /#game, press D, hold a pose with one hand and press P (pinch), F (fist) or O (other) with the other. Only the posed hand should be in view, because every visible hand gets the same label. Press S to download, save the file as src/game/fixtures/webcam-*.json, and run npm test.

Credits

T-Rex game rules and tuning are ported from Chromium's offline dino game (BSD license; its notice is kept in src/game/constants.ts). The sprites are original.

Built with offrun.dev.

License

MIT, see LICENSE.