The Problem
Interactive web maps traditionally require a mouse or touch input, excluding users in kiosk, exhibit, or hands‑free contexts. This library adds gesture‑based control—pan, zoom, rotate—driven by MediaPipe hand‑tracking, letting users interact without physical contact.
What This Does
The core gesture detection lives in packages/map-gesture-core/src/; GestureController.ts opens the webcam and streams frames to MediaPipe’s Hand Landmarker, while GestureStateMachine.ts classifies each frame (left fist/pinch → pan, right fist/pinch → zoom, both hands → rotate) using a configurable dwell timer (actionDwellMs, default 80 ms) and release grace period (releaseGraceMs, default 150 ms). Two integration packages re‑export the core API and add map‑specific controllers: packages/ol-gesture-controls/src/GestureMapController.ts and OpenLayersGestureInteraction.ts translate hand deltas into OpenLayers pixel offsets; packages/google-maps-gesture-controls/src/GoogleMapsGestureInteraction.ts does the same for the Google Maps JavaScript API. All types, constants and utility functions are exported from packages/map-gesture-core/src/index.ts.
How To Use It
Setup – OpenLayers users install both the library and OpenLayers:
npm install @map-gesture-controls/ol ol
Google‑Maps users need the library, the JS API loader and type definitions:
npm install @map-gesture-controls/google-maps @googlemaps/js-api-loader npm install -D @types/google.maps
Basic OpenLayers example – import the controller and initialise it on an existing Map instance (see examples/demo-basic.ts):
import Map from 'ol/Map.js'; import View from 'ol/View.js'; import TileLayer from 'ol/layer/Tile.js'; import OSM from 'ol/source/OSM.js'; import { GestureMapController } from '@map-gesture-controls/ol';
const map = new Map({ target: 'map', layers: [new TileLayer({ source: new OSM() })], view: new View({ center: fromLonLat([0, 0]), zoom: 2 }), });
new GestureMapController(map);
Google Maps – after the loader is ready, mount the controller similarly (refer to examples/demo-basic-gmaps.ts). No environment variables are required; the only config is the API key supplied to the loader.
Real‑World Use
An interactive museum kiosk can display a map of the exhibition layout; visitors pan with a left‑hand fist and zoom with a right‑hand pinch, keeping their hands free for other actions. The code mirrors the OpenLayers snippet above, wrapping the map in a div#map container and letting GestureMapController handle all gesture logic internally.
Code Health & Issues
Missing license – root has no LICENSE file, so usage and redistribution rights are unclear (README.md references an MIT badge but the file is absent). Google‑Maps extra deps – the Google‑Maps package requires @googlemaps/js-api-loader and @types/google.maps; omitting them will cause runtime errors. CI configured – GitHub Actions workflows exist (.github/workflows/ci.yml, release.yml, docs.yml) and test suites contain 7 files across the three packages, indicating basic test coverage. Build not committed – the README notes that dist/ must be generated via npm run build before publishing; the repo does not commit that folder, so CI must include a build step.
The Bottom Line
The library delivers a lightweight, TypeScript‑first solution for hands‑free map interaction, with clean separation between core gesture logic and map‑specific integrations. It’s well suited for exhibits, kiosks, or any scenario where touch‑less control adds value. The main caveat is the absent license file and the need to install additional Google‑Maps dependencies; teams comfortable managing those items can adopt it quickly.