Configure Hammerjs events with angular2

前端 未结 4 1463
天命终不由人
天命终不由人 2020-12-14 05:25

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:

相关标签:
4条回答
  • 2020-12-14 05:44

    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 the bootstrap 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):

    • https://github.com/angular/angular/issues/6993
    0 讨论(0)
  • 2020-12-14 05:49

    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.

    0 讨论(0)
  • 2020-12-14 05:52

    After one of the pull requests to angular, now there is way to override configuration of hammerjs.

    I have answered in other thread about how to override default config variables of hammerjs in angular2 / typescript way.

    By this method you can override all default settings and there is no need to instantiate custom HammerJs plugin.

    Here is link to answer:

    Using mobile events in Angular2

    0 讨论(0)
  • 2020-12-14 05:53

    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.

    0 讨论(0)
提交回复
热议问题