Configure Hammerjs events with angular2
Solution 1
With Angular 2.0.1, there's actually a direct way to configure hammerjs:
// app.module.ts
import { HammerGestureConfig, HAMMER_GESTURE_CONFIG } from '@angular/platform-browser';
export class MyHammerConfig extends HammerGestureConfig {
overrides = <any>{
// override hammerjs default configuration
'pan': {threshold: 5},
'swipe': {
velocity: 0.4,
threshold: 20,
direction: 31 // /!\ ugly hack to allow swipe in all direction
}
}
}
@NgModule({
imports: [ ...],
declarations: [ ... ],
bootstrap: [ ... ],
providers: [ {
provide: HAMMER_GESTURE_CONFIG,
useClass: MyHammerConfig
} ]
})
Note that I'm using a hack to allow swipe in all direction by using the current value of Hammer.DIRECTION_ALL. Though that value might not change for a while, I'll update this post as soon as someone whispers a way to access Hammer.DIRECTION_ALL value directly from the app module.
Solution 2
It's not something easy since it's internally handled by the CustomHammerGesturesPlugin class. I see two approaches:
-
Provide your own Hammer plugin and register it. When the
Hammer
object is instantiated, you need to provide your configuration as second parameter:@Injectable() export class CustomHammerGesturesPlugin extends HammerGesturesPlugin { addEventListener(element: HTMLElement, eventName: string, handler: Function): Function { var zone = this.manager.getZone(); eventName = eventName.toLowerCase(); return zone.runOutsideAngular(function() { // Creating the manager bind events, must be done outside of angular var mc = new Hammer(element); // <------- mc.get('pinch').set({enable: true}); mc.get('rotate').set({enable: true}); var handler = function(eventObj) { zone.run(function() { handler(eventObj); }); }; mc.on(eventName, handler); return () => { mc.off(eventName, handler); }; }); } }
Since the
HammerGesturesPlugin
provider is automatically register when using thebootstrap
function, you need to use this code to bootstrap your application (see https://github.com/angular/angular/blob/master/modules/angular2/platform/browser.ts#L110 and https://github.com/angular/angular/blob/master/modules/angular2/src/platform/browser_common.ts#L79):platform(BROWSER_PROVIDERS).application(appProviders).bootstrap(appComponentType);
-
A workaround could be to intercept the instantiation of the
Hammer
object (see Can I intercept a function called directly?):<script> window.TargetHammer = window.Hammer; window.Hammer = function() { var mc = new TargetHammer(arguments[0]); mc.get('press').set({ time: 1000 }); return mc; } </script>
See this plunkr: https://plnkr.co/edit/eBBC9d?p=preview.
Otherwise I don't know which version of Angular2 you use but there is a problem with Hammer events (beta.0 seems to be okay):
Solution 3
In order to configure Hammer.js events you can use recognizer (options for the event). This can be used in a directive as shown here:
import {Directive, ElementRef, Input, OnInit, OnDestroy} from '@angular/core';
import {Gesture} from 'ionic-angular/gestures/gesture';
declare var Hammer: any
@Directive({
selector: '[spLongPress]'
})
export class LongPressDirective implements OnInit, OnDestroy {
el: HTMLElement;
pressGesture: Gesture;
constructor(el: ElementRef) {
this.el = el.nativeElement;
}
ngOnInit() {
this.pressGesture = new Gesture(this.el, {
recognizers: [
[Hammer.Press, { time: 500 }]
]
});
this.pressGesture.listen();
this.pressGesture.on('press', e => {
console.log('pressed!!');
})
}
ngOnDestroy() {
this.pressGesture.destroy();
}
}
This fires the event after 500ms.
Admin
Updated on June 09, 2022Comments
-
Admin almost 2 years
How can I configure hammerjs events in angular2?
To use hammerjs events with angular2 I just have to include events on my html like this:
<div (press)="onLongPress($event)"></div>
In this case (press) will have time of 251 milliseconds, by default. Hammerjs press event documentation
How do I configure this time to have different value?