ng-ytl-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
231 lines (203 loc) • 6.94 kB
text/typescript
import {
AfterViewInit,
Component,
ContentChildren,
ElementRef,
EventEmitter,
HostBinding,
HostListener,
Input,
OnDestroy,
Output,
QueryList,
Renderer2,
ViewChild,
ViewEncapsulation,
} from '@angular/core';
import { toBoolean } from '../util/convert';
import { NzCarouselContentDirective } from './nz-carousel-content.directive';
export class NzCarouselComponent implements AfterViewInit, OnDestroy {
private _autoPlay = false;
private _dots = true;
private _vertical = false;
private _pauseOnHover = true;
activeIndex = 0;
transform = 'translate3d(0px, 0px, 0px)';
interval;
slideContents: QueryList<NzCarouselContentDirective>;
_autoPlaySpeed = 3000;
_mouseHover = false;
set _slideContents(value: QueryList<NzCarouselContentDirective>) {
this.slideContents = value;
this.renderContent();
}
slickList: ElementRef;
slickTrack: ElementRef;
_nzCarousel = true;
nzEffect = 'scrollx';
nzAfterChange: EventEmitter<number> = new EventEmitter();
nzBeforeChange: EventEmitter<{form: number; to: number}> = new EventEmitter();
get nzAutoPlaySpeed(): number {
return this._autoPlaySpeed;
}
set nzAutoPlaySpeed(speed: number) {
// css transition speed is 500ms
this._autoPlaySpeed = Math.max(speed, 500);
}
_onMouseenter(): void {
this._mouseHover = true;
if (this.nzAutoPlay && this.nzPauseOnHover) {
this.clearInterval();
}
}
_onMouseleave(): void {
this._mouseHover = false;
if (!this.interval && this.nzAutoPlay) {
this.createInterval();
}
}
get _nextIndex(): number {
return this.activeIndex < this.slideContents.length - 1 ? (this.activeIndex + 1) : 0;
}
get _prevIndex(): number {
return this.activeIndex > 0 ? (this.activeIndex - 1) : (this.slideContents.length - 1);
}
set nzPauseOnHover(value: boolean) {
this._pauseOnHover = toBoolean(value);
}
get nzPauseOnHover(): boolean {
return this._pauseOnHover;
}
set nzDots(value: boolean) {
this._dots = toBoolean(value);
}
get nzDots(): boolean {
return this._dots;
}
set nzAutoPlay(value: boolean) {
this._autoPlay = toBoolean(value);
}
get nzAutoPlay(): boolean {
return this._autoPlay;
}
set nzVertical(value: boolean) {
this._vertical = toBoolean(value);
}
get nzVertical(): boolean {
return this._vertical;
}
constructor(public hostElement: ElementRef, private _renderer: Renderer2) {
}
setActive(content: NzCarouselContentDirective, i: number): void {
if ((this.nzAutoPlay && !this.nzPauseOnHover) || (this.nzAutoPlay && this.nzPauseOnHover && !this._mouseHover)) {
this.createInterval();
}
const beforeIndex = this.slideContents.toArray().findIndex(slide => slide.isActive);
this.nzBeforeChange.emit({ form: beforeIndex, to: i });
this.activeIndex = i;
if (this.nzEffect !== 'fade') {
if (!this.nzVertical) {
this.transform = `translate3d(${-this.activeIndex * this.hostElement.nativeElement.offsetWidth}px, 0px, 0px)`;
} else {
this.transform = `translate3d(0px, ${-this.activeIndex * this.hostElement.nativeElement.offsetHeight}px, 0px)`;
}
}
this.slideContents.forEach(slide => slide.isActive = false);
content.isActive = true;
this.nzAfterChange.emit(i);
}
ngAfterViewInit(): void {
this.renderContent();
}
renderContent(): void {
setTimeout(_ => {
if (this.slideContents.first) {
this.slideContents.first.isActive = true;
}
this.slideContents.forEach((content, i) => {
content.width = this.hostElement.nativeElement.offsetWidth;
if (this.nzEffect === 'fade') {
content.fadeMode = true;
if (!this.nzVertical) {
content.left = -i * content.width;
} else {
content.top = -i * this.hostElement.nativeElement.offsetHeight;
}
}
});
if (this.nzAutoPlay) {
this.createInterval();
}
if (this.nzVertical) {
this._renderer.removeStyle(this.slickList.nativeElement, 'height');
if (this.slideContents.first) {
this._renderer.setStyle(this.slickList.nativeElement, 'height', `${this.slideContents.first.nativeElement.offsetHeight}px`);
}
this._renderer.removeStyle(this.slickTrack.nativeElement, 'height');
this._renderer.setStyle(this.slickTrack.nativeElement, 'height', `${this.slideContents.length * this.hostElement.nativeElement.offsetHeight}px`);
} else {
this._renderer.removeStyle(this.slickTrack.nativeElement, 'width');
this._renderer.setStyle(this.slickTrack.nativeElement, 'width', `${this.slideContents.length * this.hostElement.nativeElement.offsetWidth}px`);
}
});
}
createInterval(): void {
this.clearInterval();
this.interval = setInterval(_ => {
this.setActive(this.slideContents.toArray()[this._nextIndex], this._nextIndex);
}, this.nzAutoPlaySpeed);
}
clearInterval(): void {
if (this.interval) {
clearInterval(this.interval);
this.interval = null;
}
}
nzSlickNext(): void {
this.setActive(this.slideContents.toArray()[this._nextIndex], this._nextIndex);
}
nzSlickPrev(): void {
this.setActive(this.slideContents.toArray()[this._prevIndex], this._prevIndex);
}
nzSlickGoTo(index: number): void {
if (index >= 0 && index <= this.slideContents.length - 1) {
this.setActive(this.slideContents.toArray()[index], index);
}
}
ngOnDestroy(): void {
this.clearInterval();
}
}