UNPKG

rb-carrousel

Version:
145 lines (123 loc) 4.12 kB
// @flow import React, { Component } from 'react'; import Hammer from 'hammerjs'; import './carrousel.css'; type PropsType = { data: Array<{ alt: string, src: string, onClick: ?() => any, }>, position: number, onClick: ?(position: number) => any, }; class Thumbnails extends Component<PropsType> { componentDidMount() { if (this.thumbnailsContainer) this.hammerHandler = new Hammer(this.thumbnailsContainer); if (this.hammerHandler) { this.hammerHandler.on('panleft panright panend', (event) => { if (event.type === 'panend') { this.startLeft = Number(this.thumbnails[0].style.left.replace('px', '')); this.startPosition = undefined; this.thumbnails.forEach((element) => { const thumbnail = element; thumbnail.style.transition = 'all 0.3s cubic-bezier(.25, .8, .25, 1)'; thumbnail.style.pointerEvents = 'auto'; }); } else if (this.startPosition === undefined) { this.startPosition = event.center.x; this.thumbnails.forEach((element) => { const thumbnail = element; thumbnail.style.transition = 'initial'; thumbnail.style.pointerEvents = 'none'; }); } else { this.thumbnails.forEach((element) => { const thumbnail = element; thumbnail.style.left = `${this.startLeft + (event.center.x - (this.startPosition || 0))}px`; }); } }); } } componentDidUpdate() { this.fixLeft(); } totalWidth(position: number): number { let total:number = 0; if (position !== undefined) { this.thumbnails.forEach((element, index) => { if (index <= position) total += element.offsetWidth; }); } else { this.thumbnails.forEach((element) => { total += element.offsetWidth; }); } return total; } fixLeft(): void { if (this.thumbnailsContainer) { const { data, position } = this.props; const width: number = this.thumbnailsContainer.offsetWidth; const pos: number = (position || 0) >= 0 ? (position || 0) % data.length : (data.length - 1) - ((Math.abs(position || 0) - 1) % data.length); this.thumbnails.forEach((element) => { const thumbnail = element; thumbnail.style.left = `${(((width / 2) - this.totalWidth(pos)) - (pos * 16)) + (this.thumbnails[pos].offsetWidth / 6)}px`; }); this.startLeft = Number(this.thumbnails[0].style.left.replace('px', '')) || 0; } } startLeft: ?number; startPosition: ?number; hammerHandler: ?Hammer; thumbnailsContainer: ?HTMLDivElement; thumbnails: Array<HTMLDivElement> = []; render() { const { data, position, onClick, } = this.props; return ( <div className="rbcarrousel__thumbnails" ref={(ref) => { this.thumbnailsContainer = ref; }} > {data.map((element, index) => { const pos = (position || 0) >= 0 ? (position || 0) % data.length : (data.length - 1) - ((Math.abs(position || 0) - 1) % data.length); return ( <div className={`rbcarrousel__thumbnail${pos === index ? ' rbcarrousel__thumbnail--current' : ''}`} key={element.alt} onClick={() => { if (onClick) onClick(index); }} onKeyDown={(event) => { const { keyCode } = event; if (keyCode === 8) { if (onClick) onClick(index); } }} ref={(ref) => { this.thumbnails[index] = ref || document.createElement('div'); }} role="button" tabIndex={index} > <img src={element.src} alt={element.alt} onLoad={() => this.fixLeft.bind(this)()} onError={() => this.fixLeft.bind(this)()} /> </div> ); })} </div> ); } } export default Thumbnails;