UNPKG

tape-slider

Version:

simple way ever to make your website interactive add tape slider for your website

99 lines (95 loc) 3.51 kB
import * as $ from 'jquery'; import { TapeSliderItem } from './TapeSliderItem'; import * as rxJs from 'rxjs'; import { TapeSliderOptions } from './TapeSliderOptions'; export class TapeSlider { private tapeSliderNodeRef: HTMLElement; private selector: string; private moveSub: rxJs.Subscription; private hold: boolean = false; private tapeSliderOptions: TapeSliderOptions; private startedEvent: rxJs.Subject<TapeSlider> = new rxJs.Subject<TapeSlider>(); private tickEvent: rxJs.Subject<number> = new rxJs.Subject<number>(); private stoppedEvent: rxJs.Subject<TapeSlider> = new rxJs.Subject<TapeSlider>(); constructor(selector: string, tapeSliderOptions: TapeSliderOptions) { this.selector = selector this.tapeSliderOptions = tapeSliderOptions; } boot() { try { this.tapeSliderOptions.validateOptions(); this.render(); this.registerElementListeners(); this.start(); } catch (e) { console.error(`%c`, e, { 'font-size': '15px' }); } } onStarted() { return this.startedEvent.asObservable(); } onStopped() { return this.stoppedEvent.asObservable(); } onTick() { return this.tickEvent.asObservable(); } private render() { this.tapeSliderNodeRef = this.parse(); $(this.selector).append(this.tapeSliderNodeRef); } private parse(): HTMLElement { const node = this.makeElementNode(); for (let i = 0; i < this.tapeSliderOptions.getData().itemsData.length; i++) { node.appendChild(new TapeSliderItem(this.tapeSliderOptions.getData().itemsData[i]).parse()); } return node; } private makeElementNode(): HTMLElement { const node = document.createElement('div'); node.setAttribute('class', 'ts-tapeSlider-container'); return node; } private registerElementListeners() { document.addEventListener('mouseup', (e: MouseEvent) => this.onMouseUp(e)); this.tapeSliderNodeRef.addEventListener('mousedown', (e: MouseEvent) => this.onMouseDown(e)); this.tapeSliderNodeRef.addEventListener('mousemove', (e: MouseEvent) => this.onMouseMove(e)); } start() { if (this.moveSub) { this.moveSub.unsubscribe(); } this.moveSub = rxJs.interval(this.tapeSliderOptions.getSpeed()).subscribe(tick => { this.tapeSliderNodeRef.scrollBy({ left: 1 }); if (this.isStartToEnd()) { this.restart(); } this.tickEvent.next(tick); }); this.startedEvent.next(this); } private isStartToEnd() { return (this.tapeSliderNodeRef.scrollLeft + this.tapeSliderNodeRef.clientWidth + (this.tapeSliderNodeRef.clientWidth / 2)) >= this.tapeSliderNodeRef.scrollWidth; } private onMouseDown(e: MouseEvent) { this.hold = true; this.stop(); } private onMouseMove(e: MouseEvent) { if (!this.hold) return; this.tapeSliderNodeRef.scrollBy({ left: -e.movementX }); } private onMouseUp(e: MouseEvent) { this.hold = false; this.start(); } stop() { this.moveSub.unsubscribe(); this.stoppedEvent.next(this); } restart() { this.tapeSliderNodeRef.scrollTo({ left: 0 }); } }