import {
AfterContentInit,
ChangeDetectorRef,
Component,
ContentChildren,
ElementRef,
Input, OnDestroy,
OnInit,
QueryList
} from "@angular/core";
import {SliderColumnComponent} from "./slider-column.component";
export class Stage {
value: number;
max: number;
}
@Component({
selector: 'slider-container',
template: `
0" class="uk-flex uk-flex-center uk-margin-large-top">
`
})
export class SliderContainerComponent implements OnInit, OnDestroy, AfterContentInit {
private static INTERVAL = 10;
private static ANIMATION_DURATION = 600; // UIKit progress animation duration
@ContentChildren(SliderColumnComponent) sliders: QueryList;
@Input()
navigation: 'progress' | null = null;
@Input()
total: number = 0;
@Input()
period: number = 3000; // in ms (>= 1000ms)
@Input()
infinite: boolean = false;
@Input()
parent: HTMLDivElement;
stages: Stage[] = [];
time: number = 0;
interval: any;
observer: IntersectionObserver;
initialized: boolean = false;
stopped: boolean = true;
constructor(private cdr: ChangeDetectorRef, private element: ElementRef) {
}
ngOnInit() {
this.period = this.period - SliderContainerComponent.ANIMATION_DURATION;
}
ngOnDestroy() {
if(this.observer && typeof IntersectionObserver !== 'undefined') {
this.observer.disconnect();
}
}
ngAfterContentInit() {
this.setObserver();
this.sliders.forEach(slider => {
slider.setContainer(this);
slider.navItems.forEach(item => {
if(this.parent) {
item.background = getComputedStyle(this.parent).backgroundColor;
}
});
});
}
setObserver() {
if(typeof IntersectionObserver !== 'undefined') {
let options = {
root: null,
rootMargin: '0px',
threshold: 0.1
};
this.observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting && !this.initialized) {
this.stopped = false;
this.start(0);
this.initialized = true;
} else {
this.initialized = false;
this.stopped = true;
}
});
}, options);
this.observer.observe(this.element.nativeElement);
}
}
start(time: number) {
this.stages = [];
for(let i = 0; i < this.total; i++) {
this.stages.push({value: (time > i?this.period:(time - i)), max: this.period});
}
if(this.interval) {
clearInterval(this.interval);
}
this.cdr.detectChanges();
this.interval = setInterval(() => {
let current = Math.floor(time);
this.stages[current].value += SliderContainerComponent.INTERVAL;
this.time = current + this.stages[current].value/this.stages[current].max;
this.sliders.forEach(slider => {
slider.change(this.time);
});
if(this.stages[current].value >= this.stages[current].max) {
clearInterval(this.interval);
let next = (current + 1 > this.total - 1)?0:current + 1;
if(!this.stopped && (this.infinite || next > current)) {
setTimeout(() => {
this.start(next);
}, SliderContainerComponent.ANIMATION_DURATION);
}
}
}, SliderContainerComponent.INTERVAL);
}
}