From fa685d0e0d14228a795daaeec6dffc36d9749bdd Mon Sep 17 00:00:00 2001 From: Wendell Date: Sun, 22 Jul 2018 21:53:55 +0800 Subject: [PATCH] feat(carousel): add swipe gesture support (#1856) close #1816 --- angular.json | 4 ++- components/carousel/doc/index.en-US.md | 1 + components/carousel/doc/index.zh-CN.md | 1 + .../carousel/nz-carousel.component.html | 3 +- components/carousel/nz-carousel.component.ts | 34 +++++++++++++++++-- components/carousel/nz-carousel.spec.ts | 16 +++++++++ package.json | 2 ++ site_scripts/_site/src/index.html | 1 + 8 files changed, 57 insertions(+), 5 deletions(-) diff --git a/angular.json b/angular.json index 97180235703..91e1b2ee49a 100644 --- a/angular.json +++ b/angular.json @@ -24,7 +24,9 @@ "styles": [ "site/src/styles.less" ], - "scripts": [] + "scripts": [ + "node_modules/hammerjs/hammer.min.js" + ] }, "configurations": { "production": { diff --git a/components/carousel/doc/index.en-US.md b/components/carousel/doc/index.en-US.md index 59f101f1df8..04b30ef59b2 100644 --- a/components/carousel/doc/index.en-US.md +++ b/components/carousel/doc/index.en-US.md @@ -26,6 +26,7 @@ A carousel component. Scales with its container. | `[nzVertical]` | Whether to use a vertical display | boolean | `false` | | `(nzAfterChange)` | Callback function called after the current index changes | `EventEmitter` | - | | `(nzBeforeChange)` | Callback function called before the current index changes | `EventEmitter{ from: number; to: number }>` | - | +| `[nzEnableSwipe]` | Whether to support swipe gesture (would work if only you import hammer.js in your project) | `boolean` | `true` | #### Methods diff --git a/components/carousel/doc/index.zh-CN.md b/components/carousel/doc/index.zh-CN.md index a3e23618e2b..ae9b89e9fba 100644 --- a/components/carousel/doc/index.zh-CN.md +++ b/components/carousel/doc/index.zh-CN.md @@ -27,6 +27,7 @@ subtitle: 走马灯 | `[nzVertical]` | 垂直显示 | boolean | false | | `(nzAfterChange)` | 切换面板的回调 | `EventEmitter` | 无 | | `(nzBeforeChange)` | 切换面板的回调 | `EventEmitter<{ from: number; to: number }>` | 无 | +| `[nzEnableSwipe]` | 是否支持手势划动切换,仅在自行引入 hammer.js 的情形下生效 | `boolean` | `true` | #### 方法 | 名称 | 描述 | diff --git a/components/carousel/nz-carousel.component.html b/components/carousel/nz-carousel.component.html index 0d642d0482a..92a64a75b2e 100755 --- a/components/carousel/nz-carousel.component.html +++ b/components/carousel/nz-carousel.component.html @@ -1,5 +1,6 @@
-
+
diff --git a/components/carousel/nz-carousel.component.ts b/components/carousel/nz-carousel.component.ts index 258951e1f5a..7658f01aa7f 100755 --- a/components/carousel/nz-carousel.component.ts +++ b/components/carousel/nz-carousel.component.ts @@ -15,14 +15,13 @@ import { TemplateRef, ViewChild } from '@angular/core'; - import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; - import { toBoolean, toNumber } from '../core/util/convert'; - import { NzCarouselContentDirective } from './nz-carousel-content.directive'; +export type SwipeDirection = 'swipeleft' | 'swiperight'; + @Component({ selector : 'nz-carousel', preserveWhitespaces: false, @@ -73,6 +72,7 @@ export class NzCarouselComponent implements AfterViewInit, OnDestroy, AfterConte @ViewChild('slickTrack') slickTrack: ElementRef; @Output() nzAfterChange: EventEmitter = new EventEmitter(); @Output() nzBeforeChange: EventEmitter<{ from: number; to: number }> = new EventEmitter(); + @Input() nzEnableSwipe = true; @HostListener('window:resize', [ '$event' ]) onWindowResize(e: UIEvent): void { @@ -240,6 +240,34 @@ export class NzCarouselComponent implements AfterViewInit, OnDestroy, AfterConte } } + swipe(action: SwipeDirection = 'swipeleft'): void { + if (!this.nzEnableSwipe) { return; } + if (action === 'swipeleft') { this.next(); } + if (action === 'swiperight') { this.pre(); } + } + + /* tslint:disable:no-any */ + swipeInProgress(e: any): void { + if (this.nzEffect === 'scrollx') { + const final = e.isFinal; + const scrollWidth = final ? 0 : e.deltaX * 1.2; + const totalWidth = this.elementRef.nativeElement.offsetWidth; + if (this.nzVertical) { + const totalHeight = this.elementRef.nativeElement.offsetHeight; + const scrollPercent = scrollWidth / totalWidth; + const scrollHeight = scrollPercent * totalHeight; + this.transform = `translate3d(0px, ${-this.activeIndex * totalHeight + scrollHeight}px, 0px)`; + } else { + this.transform = `translate3d(${-this.activeIndex * totalWidth + scrollWidth}px, 0px, 0px)`; + } + } + if (e.isFinal) { + this.setUpAutoPlay(); + } else { + this.clearTimeout(); + } + } + constructor(public elementRef: ElementRef, private renderer: Renderer2) { } diff --git a/components/carousel/nz-carousel.spec.ts b/components/carousel/nz-carousel.spec.ts index 8027bcd6166..5dd8cfe3940 100644 --- a/components/carousel/nz-carousel.spec.ts +++ b/components/carousel/nz-carousel.spec.ts @@ -166,6 +166,22 @@ describe('carousel', () => { tick(200); expect(resizeSpy).toHaveBeenCalled(); })); + it('should swipe work', fakeAsync(() => { + fixture.detectChanges(); + testComponent.nzCarouselComponent.swipe('swipeleft'); + tick(1000); + fixture.detectChanges(); + expect(carouselContents[1].nativeElement.classList).toContain('slick-active'); + })); + it('should swipeInProgress work', () => { + fixture.detectChanges(); + fixture.detectChanges(); + testComponent.nzCarouselComponent.swipeInProgress({ isFinal: false, deltaX: 100 }); + expect(testComponent.nzCarouselComponent.transform).toBe('translate3d(120px, 0px, 0px)'); + testComponent.nzCarouselComponent.swipeInProgress({ isFinal: true }); + fixture.detectChanges(); + expect(testComponent.nzCarouselComponent.transform).toBe('translate3d(0px, 0px, 0px)'); + }); }); }); diff --git a/package.json b/package.json index b2b900f8e89..32e113835a7 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,7 @@ "@angular/router": "^6.0.0", "@schematics/angular": "^0.6.0", "@stackblitz/sdk": "^1.1.1", + "@types/hammerjs": "^2.0.35", "@types/jasmine": "~2.8.6", "@types/jasminewd2": "~2.0.3", "@types/node": "~8.9.4", @@ -78,6 +79,7 @@ "conventional-changelog-cli": "^2.0.1", "core-js": "^2.5.4", "fs-extra": "^6.0.1", + "hammerjs": "^2.0.8", "jasmine-core": "~2.99.1", "jasmine-spec-reporter": "~4.2.1", "karma": "~1.7.1", diff --git a/site_scripts/_site/src/index.html b/site_scripts/_site/src/index.html index c6de6b7c3a7..327c526b269 100644 --- a/site_scripts/_site/src/index.html +++ b/site_scripts/_site/src/index.html @@ -7,6 +7,7 @@ +