What is the best way to implement swipe navigation in Angular 2?

后端 未结 4 1545
[愿得一人]
[愿得一人] 2020-12-12 23:24

I\'m new to Angular 2 and am looking for a way to implement a good tab touch swipe navigation for mobile users with a swipe transition to the next tab view.

So far I

相关标签:
4条回答
  • 2020-12-13 00:05

    First install hammerjs and action touch-action polyfill:

    $ npm install hammerjs hammer-timejs
    

    Then add the imports to 'app.module.ts' so they will be used/bundled:

    import 'hammerjs';
    import 'hammer-timejs';
    

    Now you can handle the events for the actions:
    Rotate
    Pinch
    Press
    Pan
    Tap
    Swipe

    For example you can say:

    <li *ngFor="let employee of employeesList;" (swiperight)="myswiperight(employee)" (swipeleft)="myswipeleft(employee)">

    Or:

    <div (panstart)="onPanStart($event)" (panmove)="onPan($event)">

    Reference: https://saschwarz.github.io/angular2-gestures-slides/#/

    0 讨论(0)
  • 2020-12-13 00:08

    For the swipe detection here is a simpler solution than adding HammerJS:

    In app.component.html:

    <div (touchstart)="swipe($event, 'start')" (touchend)="swipe($event, 'end')">
      App content here
    </div>
    

    In app.component.ts:

    private swipeCoord?: [number, number];
    private swipeTime?: number;
    
    swipe(e: TouchEvent, when: string): void {
      const coord: [number, number] = [e.changedTouches[0].clientX, e.changedTouches[0].clientY];
      const time = new Date().getTime();
    
      if (when === 'start') {
        this.swipeCoord = coord;
        this.swipeTime = time;
      } else if (when === 'end') {
        const direction = [coord[0] - this.swipeCoord[0], coord[1] - this.swipeCoord[1]];
        const duration = time - this.swipeTime;
    
        if (duration < 1000 //
          && Math.abs(direction[0]) > 30 // Long enough
          && Math.abs(direction[0]) > Math.abs(direction[1] * 3)) { // Horizontal enough
            const swipe = direction[0] < 0 ? 'next' : 'previous';
            // Do whatever you want with swipe
        }
      }
    }
    

    Note: I tried the HammerJS solution but configuring it to ignore mouse gestures was impossible because you don't have direct access to the Hammer object. So selecting some text was forcing navigation to the next page...

    0 讨论(0)
  • 2020-12-13 00:09

    You can use HammerJS to implement for touch actions, You can follow this plunker for example.

    Include hammer.js file

    <script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.js"></script>
    

    or

    npm install hammerjs --save
    

    For browser touch support with hammerjs, include

     <script src="http://cdn.rawgit.com/hammerjs/touchemulator/master/touch-emulator.js"></script>
    <script>
    

    Import in app.module.ts

    import { HammerGestureConfig, HAMMER_GESTURE_CONFIG } from '@angular/platform-browser';
    
    export class MyHammerConfig extends HammerGestureConfig  {
      overrides = <any>{
        'swipe': {velocity: 0.4, threshold: 20} // override default settings
      }
    }
    
    @NgModule({
      imports: [BrowserModule],
      declarations: [AppComponent],
      bootstrap: [AppComponent],
      providers: [{ 
        provide: HAMMER_GESTURE_CONFIG, 
        useClass: MyHammerConfig 
      }] // use our custom hammerjs config
    })
    

    plunker link for example

    To implement tabs angular2-material is a good place to start, follow this link

    0 讨论(0)
  • 2020-12-13 00:13

    I managed to come up with a write-once-use-everywhere type of function which I put in a dir called "gestures" and then created a file called "swipe.ts" and put this inside.

    let swipeCoord = [0, 0];
    let swipeTime = new Date().getTime();
    
    export function swipe(e: TouchEvent, when: string): void {
    
        const coord: [number, number] = [e.changedTouches[0].clientX, e.changedTouches[0].clientY];
        const time = new Date().getTime();
    
        if (when === 'start') {
            swipeCoord = coord;
            swipeTime = time;
        } else if (when === 'end') {
            const direction = [coord[0] - swipeCoord[0], coord[1] - swipeCoord[1]];
            const duration = time - swipeTime;
    
            if (duration < 1000 //
                && Math.abs(direction[0]) > 30 // Long enough
                && Math.abs(direction[0]) > Math.abs(direction[1] * 3)) { // Horizontal enough
                const swipeDir = direction[0] < 0 ? 'next' : 'previous';
                if (swipeDir === 'next') {
                    alert('swipe next');
                } else {
                    alert('swipe prev');
                }
            }
        }
    }
    

    Then import into the desired component, like so:

    import {swipe} from '../../gestures/swipe';
    

    And create a function called:

    onSwipe(e: TouchEvent, when: string) {
            swipe(e, when);
        }
    

    In the HTML of the desired component, go with this:

        <div (touchstart)="onSwipe($event, 'start')"
             (touchend)="onSwipe($event, 'end')">
    
           <!-- whatever content you have goes here -->
    
        </div>
    

    PS - credit goes to @pikiou. I just came up with a higher level of abstraction, which to me makes a lot more sense.

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