Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Panning and Pinch-Zoom gesture handler for both touchscreens and trackpads; Works really well on a MacBook trackpad
// Target state
var tx = 0;
var ty = 0;
var scale = 1;
function visualiseTargetState() {
box.style.transform = `translate(${tx}px, ${ty}px) scale(${scale})`;
}
// The wheel event helps us capture non-touch zooming
document.addEventListener('wheel', event => {
event.preventDefault();
// Trackpad pinch-zoom
if (event.ctrlKey)
{
var s = Math.exp(-event.deltaY/100);
// Apply to target state
scale *= s;
}
// Otherwise, handle trackpad panning
else
{
var direction = natural.checked ? -1 : 1;
// Apply to target state
tx += event.deltaX * direction;
ty += event.deltaY * direction;
}
visualiseTargetState();
}, {
passive: false
});
// Track gesture state as we need it to compute the relative values to affect target state
var lastGestureX = 0;
var lastGestureY = 0;
var lastGestureScale = 1.0;
// Handle multi-touch gestures for pan/zoom
function onGesture(event) {
event.preventDefault();
// Capture initial gesture state for next gesture event
if(event.type === 'gesturestart')
{
lastGestureX = event.screenX;
lastGestureY = event.screenY;
lastGestureScale = event.scale;
}
// Now we can compute the differences
if(event.type === 'gesturechange')
{
var dx = event.screenX - lastGestureX;
var dy = event.screenY - lastGestureY;
// Apply to target state
tx += dx;
ty += dy;
}
// Apply to target state
scale *= 1.0 + (event.scale - lastGestureScale);
// Capture gesture state for next offfset
lastGestureX = event.screenX;
lastGestureY = event.screenY;
lastGestureScale = event.scale;
visualiseTargetState();
}
document.addEventListener('gesturestart', onGesture);
document.addEventListener('gesturechange', onGesture);
document.addEventListener('gestureend', onGesture);
// gesturestart
// Sent when two or more fingers touch the surface.
// gesturechange
// Sent when fingers are moved during a gesture.
// gestureend
// Sent when the gesture ends (when there are 1 or 0 fingers touching the surface).
// altKey
// A Boolean value indicating whether the alt key is pressed.
// ctrlKey
// A Boolean value indicating whether the control key is pressed.
// metaKey
// A Boolean value indicating whether the meta key is pressed.
// rotation
// The delta rotation since the start of an event, in degrees, where clockwise is positive and counter-clockwise is negative.
// scale
// The distance between two fingers since the start of an event, as a multiplier of the initial distance.
// shiftKey
// A Boolean value indicating whether the shift key is pressed.
// target
// The target of this gesture.
@Martin-Pitt

This comment has been minimized.

Copy link
Owner Author

Martin-Pitt commented Dec 20, 2019

Edited slightly with comments from https://jsbin.com/tagamoz/21/edit?js,output

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.