### Basic Gesture Recognition with Hammer.js
Source: https://github.com/hammerjs/hammer.js/blob/master/README.md
Demonstrates how to initialize Hammer.js on an HTML element and subscribe to pre-defined quick start events such as 'press'. It requires the hammer.js library to be included in the project.
```javascript
// Get a reference to an element.
var square = document.querySelector('.square');
// Create an instance of Hammer with the reference.
var hammer = new Hammer(square);
// Subscribe to a quick start event: press, tap, or doubletap.
// For a full list of quick start events, read the documentation.
hammer.on('press', function(e) {
e.target.classList.toggle('expand');
console.log("You're pressing me!");
console.log(e);
});
```
--------------------------------
### Install Hammer.js via NPM or Yarn
Source: https://github.com/hammerjs/hammer.js/blob/master/README.md
Instructions for installing the Hammer.js library using package managers like NPM or Yarn. This is the recommended approach for project integration.
```sh
npm install --save hammerjs
```
```sh
yarn add hammerjs
```
--------------------------------
### Hammer.js Gestures Simulator Setup and Execution (JavaScript)
Source: https://github.com/hammerjs/hammer.js/blob/master/tests/manual/simulator-googlemaps.html
This snippet sets up and runs the Hammer.js gestures simulator. It initializes a Google Maps instance, collects the target element, and then iteratively simulates predefined gestures using the Simulator.gestures API. It includes helper functions for generating random values and configuring gesture options.
```javascript
Simulator.events.touch.fakeSupport();
var el, map;
var container = document.getElementById('maps');
var program = [
['pan', ['deltaX', 'deltaY']],
['pinch', ['scale']],
['tap', ['pos']],
['swipe', ['deltaX', 'deltaY']],
['pinch', ['pos', 'scale']],
['pan', ['pos']],
['rotate', ['pos', 'rotation']],
['doubleTap', ['pos']],
['pinchRotate', ['pos', 'scale', 'rotation']]
];
function randomRange(min, max) {
return Math.random() * (max - min) + min;
}
function randomRangeInt(min, max) {
return Math.round(randomRange(min, max));
}
function gestureOption(name) {
var max = map.getDiv().offsetWidth * .9;
switch (name) {
case 'deltaY':
case 'deltaX':
return randomRangeInt(10, max * .5);
case 'pos':
return [randomRangeInt(10, max), randomRangeInt(10, max)];
case 'scale':
return randomRange(.2, 2);
case 'rotation':
return randomRange(-180, 180);
}
}
function walkProgram(done) {
var clone = [].concat(program);
(function next() {
if (clone.length) {
var entry = clone.shift();
var options = {};
for (var i = 0; i < entry[1].length; i++) {
options[entry[1][i]] = gestureOption(entry[1][i]);
}
Simulator.gestures[entry[0]](el, options, next);
} else {
done();
}
}());
}
function startSimulator() {
walkProgram(startSimulator);
}
(function setupGoogleMaps() {
map = new google.maps.Map(container, {
zoom: 14,
center: new google.maps.LatLng(51.98, 5.91)
});
google.maps.event.addListenerOnce(map, 'idle', function() {
el = container.childNodes[0].childNodes[0];
startSimulator();
});
})();
```
--------------------------------
### Initialize Hammer.js with Custom Options
Source: https://github.com/hammerjs/hammer.js/wiki/Getting-Started
Illustrates how to initialize Hammer.js with custom configuration options. This example disables 'drag' and 'transform' gestures by passing an options object as the second argument.
```javascript
var hammertime = Hammer(element, {
drag: false,
transform: false
});
```
--------------------------------
### Hammer.js Gesture Simulation and Logging
Source: https://github.com/hammerjs/hammer.js/blob/master/tests/manual/simulator.html
This JavaScript code initializes Hammer.js on an HTML element, configures gesture recognition, simulates a sequence of gestures with random options, and logs gesture details to the DOM. It defines helper functions for random number generation and gesture option creation.
```javascript
var program = [
['pan', ['deltaX', 'deltaY']],
['pinch', ['scale']],
['tap', ['pos']],
['swipe', ['deltaX', 'deltaY']],
['pinch', ['pos', 'scale']],
['pan', ['pos']],
['rotate', ['pos', 'rotation']],
['doubleTap', ['pos']],
['pinchRotate', ['pos', 'scale', 'rotation']]
];
function randomRange(min, max) {
return Math.random() * (max - min) + min;
}
function randomRangeInt(min, max) {
return Math.round(randomRange(min, max));
}
function gestureOption(name) {
var max = el.offsetWidth * .9;
switch (name) {
case 'deltaY':
case 'deltaX':
return randomRangeInt(10, max * .5);
case 'pos':
return [randomRangeInt(10, max), randomRangeInt(10, max)];
case 'scale':
return randomRange(.2, 2);
case 'rotation':
return randomRange(-180, 180);
}
}
function walkProgram(done) {
var clone = [].concat(program);
(function next() {
if (clone.length) {
var entry = clone.shift();
var options = {};
for (var i = 0; i < entry[1].length; i++) {
options[entry[1][i]] = gestureOption(entry[1][i]);
}
setTimeout(function() {
log.innerHTML = '';
Simulator.gestures[entry[0]](el, options, next);
}, 1000);
} else {
done();
}
}());
}
function startSimulator() {
walkProgram(startSimulator);
}
var el = document.querySelector("#hit");
var log = document.querySelector("#log");
var debug = document.querySelector("#debug");
var mc = new Hammer(el);
mc.get('pinch').set({ enable: true, threshold: .1 });
mc.get('rotate').set({ enable: true });
mc.on("swipe pan multipan press pinch rotate tap doubletap", logGesture);
function logGesture(ev) {
log.textContent = ev.toDirString();
}
Object.prototype.toDirString = function() {
var output = [];
for (var key in this) {
if (this.hasOwnProperty(key)) {
var value = this[key];
if (Array.isArray(value)) {
value = "Array(" + value.length + "):";
} else if (value instanceof HTMLElement) {
value = value + " (" + value.outerHTML.substring(0, 50) + "...)";
}
output.push(key + ": " + value);
}
}
return output.join("\n")
};
startSimulator();
```
--------------------------------
### Hammer Manager: Custom Gesture Configuration (JavaScript)
Source: https://context7.com/hammerjs/hammer.js/llms.txt
Illustrates using Hammer.Manager for fine-grained control over gesture recognition. It configures custom recognizers for 'doubletap', 'singletap', 'swipe', 'pan', and 'press' with specific options. The example shows how to prevent conflicts between gestures and log detected events with their properties.
```javascript
const element = document.getElementById('gesture-area');
const manager = new Hammer.Manager(element, {
touchAction: 'auto',
recognizers: [
[Hammer.Tap, { event: 'doubletap', taps: 2 }],
[Hammer.Tap, { event: 'singletap' }],
[Hammer.Swipe, { direction: Hammer.DIRECTION_ALL }],
[Hammer.Pan, { direction: Hammer.DIRECTION_ALL, threshold: 10 }],
[Hammer.Press, { time: 500 }]
]
});
manager.get('doubletap').recognizeWith('singletap');
manager.get('singletap').requireFailure('doubletap');
manager.on('singletap', function(ev) {
console.log('Single tap detected');
});
manager.on('doubletap', function(ev) {
console.log('Double tap detected');
console.log('Tap count:', ev.tapCount);
});
manager.on('press', function(ev) {
console.log('Press and hold detected');
console.log('Duration:', ev.deltaTime, 'ms');
});
```
--------------------------------
### Hammer.js Nested Recognizer Setup (JavaScript)
Source: https://github.com/hammerjs/hammer.js/blob/master/tests/manual/nested.html
Configures nested Hammer.js Pan recognizers for a carousel UI. It creates an outer horizontal scroller and inner vertical scrollers, using `requireFailure()` to ensure the outer pan only activates when the inner pan fails.
```javascript
// the horizontal pane scroller var outer = new HammerCarousel(document.querySelector(".panes.wrapper"), Hammer.DIRECTION_HORIZONTAL); // each pane should contain a vertical pane scroller Hammer.each(document.querySelectorAll(".pane .panes"), function(container) { // setup the inner scroller var inner = new HammerCarousel(container, Hammer.DIRECTION_VERTICAL); // only recognize the inner pan when the outer is failing. // they both have a threshold of some px outer.hammer.get('pan').requireFailure(inner.hammer.get('pan')); });
```
--------------------------------
### Hammer.js Carousel Implementation (JavaScript)
Source: https://github.com/hammerjs/hammer.js/blob/master/tests/manual/nested.html
Defines a HammerCarousel class to manage horizontal or vertical scrolling panes. It initializes Hammer.js, sets up Pan recognizers, and handles pan events to animate pane transitions. Dependencies include the Hammer.js library.
```javascript
var reqAnimationFrame = (function() { return window[Hammer.prefixed(window, "requestAnimationFrame")] || function(callback) { setTimeout(callback, 1000 / 60); } })(); function dirProp(direction, hProp, vProp) { return (direction & Hammer.DIRECTION_HORIZONTAL) ? hProp : vProp } /** * Carousel * @param container * @param direction * @constructor */ function HammerCarousel(container, direction) { this.container = container; this.direction = direction; this.panes = Array.prototype.slice.call(this.container.children, 0); this.containerSize = this.container[dirProp(direction, 'offsetWidth', 'offsetHeight')]; this.currentIndex = 0; this.hammer = new Hammer.Manager(this.container); this.hammer.add(new Hammer.Pan({ direction: this.direction, threshold: 10 })); this.hammer.on("panstart panmove panend pancancel", Hammer.bindFn(this.onPan, this)); this.show(this.currentIndex); } HammerCarousel.prototype = { /** * show a pane * @param {Number} showIndex * @param {Number} [percent] percentage visible * @param {Boolean} [animate] */ show: function(showIndex, percent, animate){ showIndex = Math.max(0, Math.min(showIndex, this.panes.length - 1)); percent = percent || 0; var className = this.container.className; if(animate) { if(className.indexOf('animate') === -1) { this.container.className += ' animate'; } } else { if(className.indexOf('animate') !== -1) { this.container.className = className.replace('animate', '').trim(); } } var paneIndex, pos, translate; for (paneIndex = 0; paneIndex < this.panes.length; paneIndex++) { pos = (this.containerSize / 100) * (((paneIndex - showIndex) * 100) + percent); if(this.direction & Hammer.DIRECTION_HORIZONTAL) { translate = 'translate3d(' + pos + 'px, 0, 0)'; } else { translate = 'translate3d(0, ' + pos + 'px, 0)' } this.panes[paneIndex].style.transform = translate; this.panes[paneIndex].style.mozTransform = translate; this.panes[paneIndex].style.webkitTransform = translate; } this.currentIndex = showIndex; }, /** * handle pan * @param {Object} ev */ onPan : function (ev) { var delta = dirProp(this.direction, ev.deltaX, ev.deltaY); var percent = (100 / this.containerSize) * delta; var animate = false; if (ev.type == 'panend' || ev.type == 'pancancel') { if (Math.abs(percent) > 20 && ev.type == 'panend') { this.currentIndex += (percent < 0) ? 1 : -1; } percent = 0; animate = true; } this.show(this.currentIndex, percent, animate); } };
```
--------------------------------
### Initialize Hammer.js with Event Listener
Source: https://github.com/hammerjs/hammer.js/wiki/Getting-Started
Demonstrates how to initialize Hammer.js on an HTML element and attach a 'tap' event listener. It shows the basic usage without requiring the 'new' keyword and highlights method chaining.
```javascript
var element = document.getElementById('test_el');
var hammertime = Hammer(element).on("tap", function(event) {
alert('hello!');
});
```
--------------------------------
### Hammer.js Touch Action Polyfill Initialization (JavaScript)
Source: https://github.com/hammerjs/hammer.js/blob/master/tests/manual/touchaction.html
This snippet demonstrates how to initialize Hammer.js instances with different touch-action values. It checks for browser support of the touch-action property and uses the polyfill if necessary. It configures pan, pinch, and rotate gestures and attaches event listeners for various touch gestures.
```javascript
var support = Hammer.prefixed(document.body.style, 'touchAction');
document.getElementById(support ? 'native' : 'no-native').className += ' show';
var touchActions = ['auto', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'];
Hammer.each(touchActions, function(touchAction) {
var el = document.getElementById(touchAction.replace(" ", "-"));
var mc = Hammer(el, {
touchAction: touchAction
});
mc.get('pan').set({
direction: Hammer.DIRECTION_ALL
});
mc.get('pinch').set({
enable: true
});
mc.get('rotate').set({
enable: true
});
mc.on("pan swipe rotate pinch tap doubletap press", function(ev) {
el.textContent = ev.type + " " + el.textContent;
});
});
```
--------------------------------
### Hammer.js Manager Lifecycle and Cleanup
Source: https://context7.com/hammerjs/hammer.js/llms.txt
This section explains how to properly initialize, manage, and destroy Hammer.js instances. It covers creating a manager with specific recognizers, setting up event handlers, temporarily stopping recognition, forcing a stop, and performing cleanup by removing listeners and destroying the manager. It also provides guidance for integrating cleanup into SPA/framework lifecycles.
```javascript
const element = document.querySelector('.temporary-element');
// Create manager
const manager = new Hammer.Manager(element, {
recognizers: [
[Hammer.Pan, { direction: Hammer.DIRECTION_ALL }],
[Hammer.Tap],
[Hammer.Press]
]
});
// Set up event handlers
manager.on('pan tap press', handleGesture);
function handleGesture(ev) {
console.log('Gesture:', ev.type);
}
// Stop recognition temporarily
function pauseGestures() {
manager.stop(false); // Stop current session
}
// Force stop immediately
function forceStopGestures() {
manager.stop(true); // Force stop
}
// Destroy and cleanup
function cleanup() {
// Remove all event listeners
manager.off('pan tap press', handleGesture);
// Destroy manager
manager.destroy();
console.log('Manager destroyed');
console.log('Element reference:', manager.element); // null
console.log('Handlers:', manager.handlers); // {}
}
// Call cleanup when element is removed
element.addEventListener('remove', cleanup);
// Or use in SPA/framework lifecycle
// React: useEffect cleanup
// Vue: onUnmounted
// Angular: ngOnDestroy
```
--------------------------------
### Hammer.js Direction Constants and Configuration
Source: https://context7.com/hammerjs/hammer.js/llms.txt
Demonstrates how to use built-in direction constants (e.g., DIRECTION_NONE, DIRECTION_LEFT, DIRECTION_ALL) to configure gesture recognizers like 'pan' and 'swipe'. It also shows how to check the direction of a detected gesture. This requires the Hammer.js library to be included.
```javascript
const element = document.querySelector('.directional');
const hammer = new Hammer(element);
// Direction constants
console.log('DIRECTION_NONE:', Hammer.DIRECTION_NONE); // 1
console.log('DIRECTION_LEFT:', Hammer.DIRECTION_LEFT); // 2
console.log('DIRECTION_RIGHT:', Hammer.DIRECTION_RIGHT); // 4
console.log('DIRECTION_UP:', Hammer.DIRECTION_UP); // 8
console.log('DIRECTION_DOWN:', Hammer.DIRECTION_DOWN); // 16
console.log('DIRECTION_HORIZONTAL:', Hammer.DIRECTION_HORIZONTAL); // 6
console.log('DIRECTION_VERTICAL:', Hammer.DIRECTION_VERTICAL); // 24
console.log('DIRECTION_ALL:', Hammer.DIRECTION_ALL); // 30
// Configure pan for vertical only
hammer.get('pan').set({
direction: Hammer.DIRECTION_VERTICAL
});
// Configure swipe for horizontal only
hammer.get('swipe').set({
direction: Hammer.DIRECTION_HORIZONTAL,
threshold: 50,
velocity: 0.5
});
// Handle specific directions
hammer.on('pan', function(ev) {
if (ev.direction === Hammer.DIRECTION_LEFT) {
console.log('Panning left');
} else if (ev.direction === Hammer.DIRECTION_RIGHT) {
console.log('Panning right');
} else if (ev.direction === Hammer.DIRECTION_UP) {
console.log('Panning up');
} else if (ev.direction === Hammer.DIRECTION_DOWN) {
console.log('Panning down');
}
});
// Check if direction matches
function isHorizontal(direction) {
return direction & Hammer.DIRECTION_HORIZONTAL;
}
function isVertical(direction) {
return direction & Hammer.DIRECTION_VERTICAL;
}
hammer.on('pan', function(ev) {
if (isHorizontal(ev.direction)) {
console.log('Horizontal pan detected');
}
if (isVertical(ev.direction)) {
console.log('Vertical pan detected');
}
});
```
--------------------------------
### Hammer.js Initialization and Event Handling
Source: https://github.com/hammerjs/hammer.js/blob/master/tests/manual/visual.html
Initializes Hammer.js on an element, sets up various gesture recognizers (Pan, Swipe, Rotate, Pinch, Tap, DoubleTap), and defines event handlers for each gesture. It also includes a listener for hammer.input events to reset the element's state after a gesture is completed.
```javascript
var reqAnimationFrame = (function () { return window[Hammer.prefixed(window, 'requestAnimationFrame')] || function (callback) { window.setTimeout(callback, 1000 / 60); }; })(); var log = document.querySelector("#log"); var el = document.querySelector("#hit"); var START_X = Math.round((window.innerWidth - el.offsetWidth) / 2); var START_Y = Math.round((window.innerHeight - el.offsetHeight) / 2); var ticking = false; var transform; var timer; var mc = new Hammer.Manager(el);
mc.add(new Hammer.Pan({ threshold: 0, pointers: 0 }));
mc.add(new Hammer.Swipe()).recognizeWith(mc.get('pan'));
mc.add(new Hammer.Rotate({ threshold: 0 })).recognizeWith(mc.get('pan'));
mc.add(new Hammer.Pinch({ threshold: 0 })).recognizeWith([mc.get('pan'), mc.get('rotate')]);
mc.add(new Hammer.Tap({ event: 'doubletap', taps: 2 }));
mc.add(new Hammer.Tap());
mc.on("panstart panmove", onPan);
mc.on("rotatestart rotatemove", onRotate);
mc.on("pinchstart pinchmove", onPinch);
mc.on("swipe", onSwipe);
mc.on("tap", onTap);
mc.on("doubletap", onDoubleTap);
mc.on("hammer.input", function(ev) { if(ev.isFinal) { resetElement(); } });
```
--------------------------------
### Dynamic Recognizer Management in Hammer.js
Source: https://context7.com/hammerjs/hammer.js/llms.txt
Demonstrates how to dynamically add, remove, configure, and manage gesture recognizers using Hammer.js. This allows for flexible gesture handling, including setting thresholds, directions, and enabling/disabling recognizers. Requires Hammer.js library.
```javascript
const element = document.querySelector('.dynamic-element');
const manager = new Hammer.Manager(element);
// Add recognizers dynamically
const pan = new Hammer.Pan({ direction: Hammer.DIRECTION_ALL });
const pinch = new Hammer.Pinch();
const rotate = new Hammer.Rotate();
manager.add([pan, pinch, rotate]);
// Make pinch and rotate work together
pinch.recognizeWith([rotate, pan]);
rotate.recognizeWith(pinch);
// Get recognizer by name
const panRecognizer = manager.get('pan');
// Update recognizer options
panRecognizer.set({
threshold: 20,
direction: Hammer.DIRECTION_HORIZONTAL
});
// Disable a recognizer
manager.get('pinch').set({ enable: false });
// Re-enable later
setTimeout(() => {
manager.get('pinch').set({ enable: true });
}, 2000);
// Remove a recognizer
manager.remove('rotate');
// Check recognizer state
console.log('Pan enabled:', panRecognizer.options.enable);
console.log('Pan threshold:', panRecognizer.options.threshold);
```
--------------------------------
### Configure Transform Gestures (Pinch, Rotate)
Source: https://github.com/hammerjs/hammer.js/wiki/Tips-&-Tricks
Sets up Hammer.js to handle transform gestures like pinch and rotate by enabling `preventDefault` to give Hammer full control over touch input, disabling default browser actions for a smoother experience.
```javascript
var options = {
preventDefault: true
};
var hammertime = new Hammer(element, options);
hammertime.on("transform", function(ev){ });
```
--------------------------------
### Instance-Specific Hammer.js Touch Action Configuration
Source: https://github.com/hammerjs/hammer.js/wiki/How-to-fix-Chrome-35--and-IE10--scrolling-(touch-action)
This code shows how to configure the `touchAction` property for a specific Hammer.js instance. It involves extending the default behavior object and then passing this custom configuration during the Hammer instance creation, allowing for granular control over touch interactions on individual elements.
```javascript
// clone the default behavior object
// for 1.0.x this is at the stop_default_behavior object
var myCustomBehavior = Hammer.utils.extend({}, Hammer.defaults.behavior);
myCustomBehavior.touchAction = 'pan-y';
var mc = new Hammer(document.body, {
behavior: myCustomBehavior
});
```
--------------------------------
### Initialize Hammer.js with Multiple Gestures and Event Handling (JavaScript)
Source: https://github.com/hammerjs/hammer.js/blob/master/tests/manual/multiple.html
This JavaScript code initializes Hammer.js on a given HTML element, enabling multiple gestures (pan, swipe, pinch, rotate) and setting their configurations. It also attaches event listeners for a combination of gestures, updating the element's text with event details.
```javascript
Object.prototype.toDirString = function() { var output = []; for(var key in this) { if(this.hasOwnProperty(key)) { var value = this[key]; if(Array.isArray(value)) { value = "Array("+ value.length +"):"+ value; } else if(value instanceof HTMLElement) { value = value +" ("+ value.outerHTML.substring(0, 50) +"...)"; } output.push(key +": "+ value); } } return output.join("\n") }; function addHammer(el) { var mc = new Hammer(el, { multiUser: true }); mc.get('pan').set({ direction: Hammer.DIRECTION_ALL }); mc.get('swipe').set({ direction: Hammer.DIRECTION_ALL }); mc.get('pinch').set({ enable: true }); mc.get('rotate').set({ enable: true }); mc.on("swipe pan press pinch rotate tap doubletap", function (ev) { ev.preventDefault(); el.innerText = ev.toDirString(); }); } addHammer(document.querySelector("#left")); addHammer(document.querySelector("#right"));
```
--------------------------------
### Custom Gesture Recognition with Hammer.js
Source: https://github.com/hammerjs/hammer.js/blob/master/README.md
Illustrates how to define and recognize custom gestures, like 'tripletap', using Hammer.js. This involves creating a Hammer.Manager instance, defining a new recognizer, adding it to the manager, and subscribing to the custom event.
```javascript
// Get a reference to an element.
var square = document.querySelector('.square');
// Create a manager to manage the element.
var manager = new Hammer.Manager(square);
// Create a recognizer.
var TripleTap = new Hammer.Tap({
event: 'tripletap',
taps: 3
});
// Add the recognizer to the manager.
manager.add(TripleTap);
// Subscribe to the event.
manager.on('tripletap', function(e) {
e.target.classList.toggle('expand');
console.log("You're triple tapping me!");
console.log(e);
});
```
--------------------------------
### Hammer.js Event Listener Management
Source: https://context7.com/hammerjs/hammer.js/llms.txt
Explains how to manage event listeners in Hammer.js using 'on', 'off', and event delegation. Covers adding single and multiple listeners, removing specific or all listeners for an event, and chaining listener calls. Requires Hammer.js library.
```javascript
const element = document.querySelector('.interactive');
const hammer = new Hammer(element);
// Add event listener
function handleTap(ev) {
console.log('Tap handler called');
console.log('Target:', ev.target.className);
}
hammer.on('tap', handleTap);
// Add multiple event listeners
hammer.on('swipeleft swiperight', function(ev) {
console.log('Horizontal swipe:', ev.type);
});
// Remove specific handler
hammer.off('tap', handleTap);
// Remove all handlers for event
hammer.off('swipeleft swiperight');
// Multiple handlers for same event
hammer.on('pan', handler1);
hammer.on('pan', handler2);
// Chainable API
hammer
.on('tap', handleTap)
.on('press', handlePress)
.on('swipe', handleSwipe);
function handler1(ev) {
console.log('Handler 1:', ev.type);
}
function handler2(ev) {
console.log('Handler 2:', ev.type);
// Stop after this handler
hammer.off('pan', handler2);
}
function handlePress(ev) {
console.log('Press detected');
}
function handleSwipe(ev) {
console.log('Swipe detected');
}
```
--------------------------------
### Basic Hammer Instance: Detect Tap and Swipe Gestures (JavaScript)
Source: https://context7.com/hammerjs/hammer.js/llms.txt
Demonstrates how to create a basic Hammer instance on a DOM element to detect 'tap' and 'swipeleft'/'swiperight' gestures. It logs gesture details like position, target, direction, and velocity to the console. This is useful for simple gesture interactions.
```javascript
const element = document.querySelector('.interactive-area');
const hammer = new Hammer(element);
hammer.on('tap', function(ev) {
console.log('Tapped!');
console.log('Position:', ev.center.x, ev.center.y);
console.log('Target:', ev.target);
});
hammer.on('swipeleft swiperight', function(ev) {
console.log('Swiped:', ev.type);
console.log('Direction:', ev.direction);
console.log('Velocity:', ev.velocityX);
});
```
--------------------------------
### Create and Use Custom Gesture Recognizer (Shake) in Hammer.js
Source: https://context7.com/hammerjs/hammer.js/llms.txt
This code demonstrates how to create a custom gesture recognizer for a 'shake' action in Hammer.js. It defines a `ShakeRecognizer` that inherits from `Hammer.Recognizer` and implements a `process` method to detect rapid movements within a time threshold. The custom recognizer is then added to a Hammer manager and can be listened to like any built-in gesture.
```javascript
// Define custom shake gesture recognizer
function ShakeRecognizer() {
Hammer.Recognizer.apply(this, arguments);
this.shakeThreshold = 15;
this.shakeTime = 500;
}
// Inherit from base Recognizer
Hammer.inherit(ShakeRecognizer, Hammer.Recognizer, {
defaults: {
event: 'shake',
threshold: 15,
time: 500
},
getTouchAction: function() {
return [Hammer.TOUCH_ACTION_AUTO];
},
process: function(input) {
const options = this.options;
const validTime = input.deltaTime < options.time;
const validMovement = Math.abs(input.velocityX) > options.threshold ||
Math.abs(input.velocityY) > options.threshold;
if (validTime && validMovement) {
this.state = Hammer.STATE_RECOGNIZED;
return Hammer.STATE_RECOGNIZED;
}
return Hammer.STATE_FAILED;
}
});
// Use custom recognizer
const element = document.querySelector('.shake-target');
const manager = new Hammer.Manager(element);
manager.add(new ShakeRecognizer());
manager.on('shake', function(ev) {
console.log('Shake detected!');
console.log('Velocity:', ev.velocityX, ev.velocityY);
});
```
--------------------------------
### Enable Fake Multitouch Gestures (JavaScript)
Source: https://github.com/hammerjs/hammer.js/wiki/Plugins
This plugin enables multitouch gestures on desktop browsers. It should be loaded after the main Hammer.js script and initialized by calling `Hammer.plugins.fakeMultitouch();`. No specific inputs or outputs are defined, but it modifies Hammer.js behavior.
```javascript
Hammer.plugins.fakeMultitouch();
```
--------------------------------
### Hammer.js - Initialize and Configure Pinch Gesture in JavaScript
Source: https://github.com/hammerjs/hammer.js/blob/master/tests/manual/input.html
This code initializes Hammer.js on an HTML element identified by '#hit'. It then enables the 'pinch' gesture and sets up an event listener for 'hammer.input' events. The listener updates a debug element with details about the touch input, such as event type, number of pointers, and movement deltas.
```javascript
var el = document.querySelector("#hit");
var log = document.querySelector("#log");
var debug = document.querySelector("#debug");
var mc = new Hammer(el);
mc.get('pinch').set({ enable: true });
mc.on("hammer.input", function(ev) {
debug.innerHTML = [ev.srcEvent.type, ev.pointers.length, ev.isFinal, ev.deltaX, ev.deltaY].join("
");
});
```
--------------------------------
### Accessing Gesture Event Data with Hammer.js
Source: https://context7.com/hammerjs/hammer.js/llms.txt
Learn how to access detailed data from various gesture events like pan, tap, and swipe. This includes timing, position, velocity, multi-touch information, and preventing default browser behavior. Requires Hammer.js library.
```javascript
const element = document.querySelector('.gesture-target');
const hammer = new Hammer(element);
hammer.get('pan').set({ direction: Hammer.DIRECTION_ALL });
hammer.on('pan tap swipe press', function(ev) {
// Event type
console.log('Gesture type:', ev.type);
// Timing information
console.log('Timestamp:', ev.timeStamp);
console.log('Delta time:', ev.deltaTime);
// Position data
console.log('Center point:', ev.center); // { x, y }
console.log('Delta movement:', ev.deltaX, ev.deltaY);
// Velocity and direction
console.log('Velocity:', ev.velocityX, ev.velocityY);
console.log('Overall velocity:', ev.overallVelocity);
console.log('Direction:', ev.direction);
console.log('Offset direction:', ev.offsetDirection);
// Distance and angle
console.log('Distance:', ev.distance);
console.log('Angle:', ev.angle);
// Multi-touch data
console.log('Scale:', ev.scale);
console.log('Rotation:', ev.rotation);
console.log('Pointers:', ev.pointers.length);
console.log('Max pointers:', ev.maxPointers);
// Pointer information
console.log('Pointer type:', ev.pointerType); // 'mouse', 'touch', 'pen'
console.log('Target element:', ev.target);
// Original event
console.log('Source event:', ev.srcEvent);
// Event flags
console.log('Is first:', ev.isFirst);
console.log('Is final:', ev.isFinal);
// Prevent default browser behavior
ev.preventDefault();
});
```
--------------------------------
### Hammer.js Gesture Recognition and Logging
Source: https://github.com/hammerjs/hammer.js/blob/master/tests/manual/log.html
This JavaScript code demonstrates how to use Hammer.js to detect various touch gestures on an HTML element and log the gesture details to the console and the DOM. It initializes Hammer.js on a specific element, enables pinch and rotate gestures, and sets up event listeners for multiple gesture types.
```javascript
Object.prototype.toDirString = function() {
var output = [];
for(var key in this) {
if(this.hasOwnProperty(key)) {
var value = this[key];
if(Array.isArray(value)) {
value = "Array(" + value.length +"):"+ value;
} else if(value instanceof HTMLElement) {
value = value + " ("+ value.outerHTML.substring(0, 50) +"...)";
}
output.push(key + ": "+ value);
}
}
return output.join("\n")
};
var el = document.querySelector("#hit");
var log = document.querySelector("#log");
var debug = document.querySelector("#debug");
var mc = new Hammer(el);
mc.get('pinch').set({ enable: true });
mc.get('rotate').set({ enable: true });
mc.on("swipe pan panstart panmove panend pancancel multipan press pressup pinch rotate tap doubletap", logGesture);
function DEBUG(str) {
debug.textContent = str;
}
function logGesture(ev) {
console.log(ev.timeStamp, ev.type, ev);
log.textContent = ev.toDirString();
}
```
--------------------------------
### Hammer.js Recognizer Dependencies and Simultaneous Recognition
Source: https://context7.com/hammerjs/hammer.js/llms.txt
Illustrates how to manage relationships between Hammer.js recognizers, such as setting dependencies (recognizeWith, requireFailure) to control when gestures are recognized. This allows for complex gesture interactions, like recognizing swipe and pan simultaneously or ensuring a double-tap doesn't trigger a single tap. Requires Hammer.js.
```javascript
const element = document.querySelector('.complex-gestures');
const manager = new Hammer.Manager(element);
// Create recognizers
const pan = new Hammer.Pan({ direction: Hammer.DIRECTION_ALL });
const swipe = new Hammer.Swipe({ direction: Hammer.DIRECTION_ALL });
const tap = new Hammer.Tap();
const doubleTap = new Hammer.Tap({ event: 'doubletap', taps: 2 });
const press = new Hammer.Press();
manager.add([pan, swipe, tap, doubleTap, press]);
// Recognize swipe and pan simultaneously
pan.recognizeWith(swipe);
// Tap requires doubletap to fail first (prevent false single taps)
tap.requireFailure(doubleTap);
// Allow press to work with pan
press.recognizeWith(pan);
// Drop recognition relationship
// pan.dropRecognizeWith(swipe);
// tap.dropRequireFailure(doubleTap);
manager.on('pan swipe', function(ev) {
console.log('Gesture:', ev.type);
console.log('Can recognize together');
});
manager.on('tap', function(ev) {
console.log('Single tap (doubletap failed)');
});
manager.on('doubletap', function(ev) {
console.log('Double tap detected');
});
```
--------------------------------
### Detect Input Types and Pointer Events with Hammer.js
Source: https://context7.com/hammerjs/hammer.js/llms.txt
This snippet demonstrates how to detect different input types (mouse, touch, pen) and access detailed pointer event information using Hammer.js. It logs the pointer type, specific event details like button or pressure, and raw pointer coordinates. Dependencies include the Hammer.js library.
```javascript
const element = document.querySelector('.multi-input');
const hammer = new Hammer(element);
// Input type constants
console.log('INPUT_TYPE_MOUSE:', 'mouse');
console.log('INPUT_TYPE_TOUCH:', 'touch');
console.log('INPUT_TYPE_PEN:', 'pen');
hammer.on('tap press pan', function(ev) {
// Detect input type
console.log('Pointer type:', ev.pointerType);
if (ev.pointerType === 'mouse') {
console.log('Mouse input detected');
console.log('Button:', ev.srcEvent.button);
} else if (ev.pointerType === 'touch') {
console.log('Touch input detected');
console.log('Number of touches:', ev.pointers.length);
} else if (ev.pointerType === 'pen') {
console.log('Stylus/pen input detected');
console.log('Pressure:', ev.srcEvent.pressure);
}
// Access raw pointer data
ev.pointers.forEach((pointer, index) => {
console.log(`Pointer ${index}:`, {
x: pointer.clientX,
y: pointer.clientY,
identifier: pointer.identifier
});
});
});
// Custom input class (advanced)
const customManager = new Hammer.Manager(element, {
inputClass: Hammer.TouchInput // Force touch input handling
});
```
--------------------------------
### Pan Gesture Recognition: Detect Dragging and Direction (JavaScript)
Source: https://context7.com/hammerjs/hammer.js/llms.txt
Shows how to enable and handle pan gestures for dragging elements. It configures pan detection, updates element position during 'panmove', and logs details like delta movement, direction, and velocity. It also demonstrates handling 'panstart', 'panend', and directional pan events ('panleft', 'panright', etc.).
```javascript
const element = document.querySelector('.draggable');
const hammer = new Hammer(element);
hammer.get('pan').set({ direction: Hammer.DIRECTION_ALL });
let startX = 0;
let startY = 0;
hammer.on('panstart', function(ev) {
startX = parseFloat(element.style.left) || 0;
startY = parseFloat(element.style.top) || 0;
element.classList.add('dragging');
console.log('Pan started at:', ev.center);
});
hammer.on('panmove', function(ev) {
element.style.left = (startX + ev.deltaX) + 'px';
element.style.top = (startY + ev.deltaY) + 'px';
console.log('Pan delta:', ev.deltaX, ev.deltaY);
console.log('Pan direction:', ev.direction);
console.log('Pan velocity:', ev.velocityX, ev.velocityY);
});
hammer.on('panend', function(ev) {
element.classList.remove('dragging');
console.log('Pan ended');
console.log('Final position:', element.style.left, element.style.top);
if (Math.abs(ev.velocityX) > 0.5) {
console.log('Fast swipe detected, velocity:', ev.velocityX);
}
});
hammer.on('panleft panright panup pandown', function(ev) {
console.log('Directional pan:', ev.type);
});
```
--------------------------------
### Pinch and Rotate Gestures with Hammer.js
Source: https://context7.com/hammerjs/hammer.js/llms.txt
Handles multi-touch pinch (zoom) and rotate gestures on an element. It allows for dynamic scaling and rotation of images or other elements. Requires Hammer.js.
```javascript
const image = document.querySelector('.zoomable-image');
const hammer = new Hammer(image);
// Enable pinch and rotate
hammer.get('pinch').set({ enable: true });
hammer.get('rotate').set({ enable: true });
let currentScale = 1;
let currentRotation = 0;
hammer.on('pinchstart rotatestart', function(ev) {
console.log('Multi-touch gesture started');
image.classList.add('transforming');
});
hammer.on('pinchmove', function(ev) {
currentScale = Math.max(0.5, Math.min(currentScale * ev.scale, 3));
updateTransform();
console.log('Pinch scale:', ev.scale);
console.log('Current scale:', currentScale);
console.log('Pinch direction:', ev.scale > 1 ? 'out' : 'in');
});
hammer.on('rotatemove', function(ev) {
currentRotation += ev.rotation;
updateTransform();
console.log('Rotation angle:', ev.rotation);
console.log('Total rotation:', currentRotation);
});
hammer.on('pinchend rotateend', function(ev) {
image.classList.remove('transforming');
console.log('Final scale:', currentScale);
console.log('Final rotation:', currentRotation);
});
// Handle pinch in/out specifically
hammer.on('pinchin pinchout', function(ev) {
console.log('Pinch type:', ev.type);
});
function updateTransform() {
image.style.transform =
`scale(${currentScale}) rotate(${currentRotation}deg)`;
}
```
--------------------------------
### Tap and Double Tap Recognition with Hammer.js
Source: https://context7.com/hammerjs/hammer.js/llms.txt
Recognizes single, double, and triple tap gestures on an element. It includes configuration for tap interval and position threshold to ensure accurate detection. Requires Hammer.js.
```javascript
const element = document.querySelector('.tappable');
const manager = new Hammer.Manager(element);
// Add tap recognizers
const singleTap = new Hammer.Tap({ event: 'singletap' });
const doubleTap = new Hammer.Tap({
event: 'doubletap',
taps: 2,
interval: 300, // max time between taps
posThreshold: 10 // max distance between taps
});
const tripleTap = new Hammer.Tap({
event: 'tripletap',
taps: 3
});
manager.add([tripleTap, doubleTap, singleTap]);
// Set up recognition dependencies
doubleTap.recognizeWith(singleTap);
singleTap.requireFailure([doubleTap, tripleTap]);
tripleTap.recognizeWith(doubleTap);
manager.on('singletap', function(ev) {
console.log('Single tap');
console.log('Position:', ev.center.x, ev.center.y);
console.log('Tap count:', ev.tapCount);
});
manager.on('doubletap', function(ev) {
console.log('Double tap detected');
console.log('Time between taps:', ev.deltaTime, 'ms');
// Zoom in or select action
});
manager.on('tripletap', function(ev) {
console.log('Triple tap detected');
// Special action
});
```
--------------------------------
### Hammer.js Touch Action and Browser Behavior Control
Source: https://context7.com/hammerjs/hammer.js/llms.txt
Explains how to configure the `touchAction` option in Hammer.js to control default browser behaviors like scrolling and zooming. It shows different settings such as 'auto', 'none', 'pan-y', 'pan-x', and 'manipulation' to customize touch interactions. This is useful for preventing conflicts between Hammer gestures and native browser gestures. Requires Hammer.js.
```javascript
const element = document.querySelector('.scroll-container');
// Let Hammer compute optimal touch-action
const manager = new Hammer.Manager(element, {
touchAction: 'auto'
});
// Disable all touch actions (no scrolling, no zooming)
const strictManager = new Hammer.Manager(element, {
touchAction: 'none'
});
// Allow vertical scrolling only
const verticalScrollManager = new Hammer.Manager(element, {
touchAction: 'pan-y'
});
// Allow horizontal scrolling only
const horizontalScrollManager = new Hammer.Manager(element, {
touchAction: 'pan-x'
});
// Allow pinch-zoom
const zoomManager = new Hammer.Manager(element, {
touchAction: 'manipulation'
});
// Configure pan with appropriate touch action
const panElement = document.querySelector('.pan-only');
const panManager = new Hammer.Manager(panElement, {
touchAction: 'pan-y' // Allow vertical scroll, prevent horizontal
});
panManager.add(new Hammer.Pan({
direction: Hammer.DIRECTION_HORIZONTAL
}));
panManager.on('pan', function(ev) {
console.log('Horizontal pan without interfering with vertical scroll');
console.log('Delta X:', ev.deltaX);
});
```
--------------------------------
### Configure Vertical Swipe and Drag Gestures
Source: https://github.com/hammerjs/hammer.js/wiki/Tips-&-Tricks
Configures Hammer.js for vertical swipe and drag gestures by enabling `preventDefault`. This is recommended because vertical movements can conflict with default browser scrolling, and this setting gives Hammer control.
```javascript
var options = {
preventDefault: true
};
var hammertime = new Hammer(element, options);
hammertime.on("dragup dragdown swipeup swipedown", function(ev){ });
```
--------------------------------
### Show Touches for Debugging (JavaScript)
Source: https://github.com/hammerjs/hammer.js/wiki/Plugins
This plugin visually displays touch points, useful in conjunction with the `fakemultitouch` plugin for desktop testing. It relies on the CSS `pointer-events` property, meaning it will not function in older Internet Explorer versions. It's typically enabled within a script block.
```javascript
//
//
```
--------------------------------
### Extend Object Prototype with toDirString in JavaScript
Source: https://github.com/hammerjs/hammer.js/blob/master/tests/manual/input.html
This snippet extends the Object prototype to add a `toDirString` method. This method iterates over an object's own properties and formats their values for display, handling arrays and HTMLElements specifically. It's useful for debugging and logging object structures.
```javascript
Object.prototype.toDirString = function() { var output = []; for(var key in this) { if(this.hasOwnProperty(key)) { var value = this[key]; if(Array.isArray(value)) { value = "Array("+ value.length +"):"+ value; } else if(value instanceof HTMLElement) { value = value +" ("+ value.outerHTML.substring(0, 50) +"...)"; } output.push(key +": "+ value); } } return output.join("\n") };
```
--------------------------------
### Configure Horizontal Swipe and Drag Gestures
Source: https://github.com/hammerjs/hammer.js/wiki/Tips-&-Tricks
Configures Hammer.js to prioritize horizontal swipe and drag gestures by locking the drag to an axis and blocking horizontal movement, improving the user experience for these specific actions.
```javascript
var options = {
dragLockToAxis: true,
dragBlockHorizontal: true
};
var hammertime = new Hammer(element, options);
hammertime.on("dragleft dragright swipeleft swiperight", function(ev){ });
```
--------------------------------
### Disable Viewport Scaling
Source: https://github.com/hammerjs/hammer.js/wiki/Tips-&-Tricks
This meta tag should be added to your page to prevent double-tap zooming and enable multitouch gestures. It also helps remove the 300ms delay on Chrome Mobile.
```HTML
```
--------------------------------
### Element Transformation Logic
Source: https://github.com/hammerjs/hammer.js/blob/master/tests/manual/visual.html
Contains functions to manage and update the CSS transformations (translate, scale, rotate) of an HTML element. It uses requestAnimationFrame for smooth updates and handles resetting the element's style and transform properties.
```javascript
function resetElement() { el.className = 'animate'; transform = { translate: { x: START_X, y: START_Y }, scale: 1, angle: 0, rx: 0, ry: 0, rz: 0 }; requestElementUpdate(); if (log.textContent.length > 2000) { log.textContent = log.textContent.substring(0, 2000) + "..."; } }
function updateElementTransform() { var value = [ 'translate3d(' + transform.translate.x + 'px, ' + transform.translate.y + 'px, 0)', 'scale(' + transform.scale + ', ' + transform.scale + ')', 'rotate3d('+ transform.rx +','+ transform.ry +','+ transform.rz +','+ transform.angle + 'deg)' ]; value = value.join(" "); el.textContent = value; el.style.webkitTransform = value; el.style.mozTransform = value; el.style.transform = value; ticking = false; }
function requestElementUpdate() { if(!ticking) { reqAnimationFrame(updateElementTransform); ticking = true; } }
function logEvent(str) { //log.insertBefore(document.createTextNode(str +"\n"), log.firstChild);
}
```
--------------------------------
### Hammer.js Gesture Event Handlers
Source: https://github.com/hammerjs/hammer.js/blob/master/tests/manual/visual.html
Provides specific callback functions for different Hammer.js gestures. These functions update the 'transform' object based on gesture data (delta, scale, rotation, direction) and trigger element updates.
```javascript
function onPan(ev) { el.className = ''; transform.translate = { x: START_X + ev.deltaX, y: START_Y + ev.deltaY }; requestElementUpdate(); logEvent(ev.type); }
var initScale = 1;
function onPinch(ev) { if(ev.type == 'pinchstart') { initScale = transform.scale || 1; } el.className = ''; transform.scale = initScale * ev.scale; requestElementUpdate(); logEvent(ev.type); }
var initAngle = 0;
function onRotate(ev) { if(ev.type == 'rotatestart') { initAngle = transform.angle || 0; } el.className = ''; transform.rz = 1; transform.angle = initAngle + ev.rotation; requestElementUpdate(); logEvent(ev.type); }
function onSwipe(ev) { var angle = 50; transform.ry = (ev.direction & Hammer.DIRECTION_HORIZONTAL) ? 1 : 0; transform.rx = (ev.direction & Hammer.DIRECTION_VERTICAL) ? 1 : 0; transform.angle = (ev.direction & (Hammer.DIRECTION_RIGHT | Hammer.DIRECTION_UP)) ? angle : -angle; clearTimeout(timer); timer = setTimeout(function () { resetElement(); }, 300); requestElementUpdate(); logEvent(ev.type); }
function onTap(ev) { transform.rx = 1; transform.angle = 25; clearTimeout(timer); timer = setTimeout(function () { resetElement(); }, 200); requestElementUpdate(); logEvent(ev.type); }
function onDoubleTap(ev) { transform.rx = 1; transform.angle = 80; clearTimeout(timer); timer = setTimeout(function () { resetElement(); }, 500); requestElementUpdate(); logEvent(ev.type); }
resetElement();
```