@zakkster/lite-gesture
v1.0.1
Published
Zero-GC multi-touch gesture recognition. Pan, pinch-to-zoom, velocity tracking. HOC wrapper around lite-pointer-tracker.
Maintainers
Readme
@zakkster/lite-gesture
Zero-GC multi-touch gesture recognition. Pan, pinch-to-zoom, velocity tracking.
Does NOT modify lite-pointer-tracker. Wraps it as a higher-order component.
Why lite-gesture?
| Feature | lite-gesture | Hammer.js | use-gesture | AlloyFinger | |---|---|---|---|---| | Zero-GC events | Yes (pre-allocated) | No | No | No | | Velocity on release | Yes (measured) | Approximate | Yes | No | | Pinch→Pan fallback | Yes (seamless) | Partial | Yes | No | | AbortController cleanup | Yes | No | React only | No | | PointerEvents native | Yes | Touch + Mouse | Yes | Touch only | | Bundle size | < 2KB | ~7KB | ~5KB | ~3KB |
Installation
npm install @zakkster/lite-gestureQuick Start
import { GestureTracker } from '@zakkster/lite-gesture';
const gesture = GestureTracker(canvas, {
onPanMove: (e) => {
ctx.translate(e.frameDx, e.frameDy);
},
onPanEnd: (e) => {
console.log('Release velocity:', e.vx, e.vy);
},
onPinchMove: (e) => {
currentZoom *= 1 + e.deltaScale;
},
});
// Later: gesture.destroy()Recipes
Canvas Pan + Zoom
let offsetX = 0, offsetY = 0, zoom = 1;
GestureTracker(canvas, {
onPanMove: (e) => { offsetX += e.frameDx; offsetY += e.frameDy; },
onPinchMove: (e) => { zoom *= 1 + e.deltaScale; },
});Swipe Card with Physics Handoff
import { Spring } from '@zakkster/lite-ui';
const sx = new Spring(0);
GestureTracker(card, {
onPanMove: (e) => { sx.value = e.dx; card.style.transform = `translateX(${e.dx}px)`; },
onPanEnd: (e) => { sx.velocity = e.vx; sx.set(0); },
});Image Viewer (Pinch Zoom Around Center)
let scale = 1, panX = 0, panY = 0;
GestureTracker(imageEl, {
onPinchMove: (e) => {
scale = e.scale;
panX = e.panX;
panY = e.panY;
imageEl.style.transform = `translate(${panX}px, ${panY}px) scale(${scale})`;
},
});API
| Callback | Event Fields |
|---|---|
| onPanStart | { x, y } |
| onPanMove | { x, y, dx, dy, frameDx, frameDy } |
| onPanEnd | { x, y, dx, dy, vx, vy } — velocity in px/s |
| onPinchStart | { centerX, centerY } |
| onPinchMove | { scale, deltaScale, centerX, centerY, panX, panY } |
| onPinchEnd | (no fields) |
| Property | Description |
|---|---|
| .isPanning | Whether a pan gesture is active |
| .isPinching | Whether a pinch gesture is active |
| .pointerCount | Number of active touch points |
| .destroy() | Clean up all listeners |
License
MIT
