import { MouseEvent , TouchEvent } from 'react' ; import { SlideDirection , Item } from '../types/carousel' ; export class Circular < T > { constructor ( private arr , private currentIndex ) { } next ( ) { const i = this . currentIndex ; const arr = this . arr ; this . currentIndex = i < arr . length - 1 ? i + 1 : 0 ; return this . current ( ) ; } prev ( ) { const i = this . currentIndex ; const arr = this . arr ; this . currentIndex = i > 0 && i < arr . length ? i - 1 : arr . length - 1 ; return this . current ( ) ; } current ( ) { return this . arr [ this . currentIndex ] ; } } export const rotateItems = ( items , showingItems , start , show , slide , direction ) : any [ ] => { const circular = new Circular ( items , start ) ; const newItems = Array . from ( showingItems ) ; switch ( + direction ) { case SlideDirection . Left : for ( let i = slide ; i >= 0 ; i -- ) { if ( slide - i < 0 || ! newItems [ i - slide ] ) { newItems . unshift ( circular . current ( ) ) ; } circular . prev ( ) ; } break ; case SlideDirection . Right : for ( let i = 0 ; i < show + slide ; i ++ ) { if ( ! newItems [ 2 * slide + i ] ) { newItems . push ( circular . current ( ) ) ; } circular . next ( ) ; } break ; } return newItems ; } ; export const getTransformAmount = ( width , slideCount , direction ) : number => { return direction * width * slideCount ; } ; export const getCurrent = ( current , slide , length , direction ) => { const slideTo = current - direction * slide ; if ( slideTo < 0 ) { return length + slideTo ; } else if ( length <= slideTo ) { return slideTo - length ; } return slideTo ; } ; export const getShowArrow = ( items , show , infinite , current ) : { left : boolean ; right : boolean ; } => { const isItemsMore = items > show ; if ( infinite ) { return { left : isItemsMore , right : isItemsMore , } ; } return { left : isItemsMore && current !== 0 , right : isItemsMore && current + show < items , } ; } ; export const cleanItems = ( showingItems , slide , direction ) : any [ ] => { if ( direction === SlideDirection . Left ) { return showingItems . slice ( 0 , - 1 * slide ) ; } return showingItems . slice ( slide ) ; } ; export const initItems = ( items , slide , infinite ) : Item [ ] => { if ( ! infinite ) { return items ; } const newArray = Array . from ( items ) ; const circular = new Circular ( items , 0 ) ; for ( let i = 0 ; i < slide ; i ++ ) { newArray . unshift ( circular . prev ( ) ) ; } return newArray ; } ; export function getPageX ( e ) { if ( e . nativeEvent instanceof MouseEvent ) { return e . nativeEvent . pageX ; } else if ( e . nativeEvent instanceof TouchEvent ) { return e . nativeEvent . changedTouches [ 0 ] . pageX ; } return 0 ; } export function getOuterWidth ( el ) { const style = getComputedStyle ( el ) ; return ( el . offsetWidth + ( parseInt ( style . marginLeft , 10 ) || 0 ) + ( parseInt ( style . marginRight , 10 ) || 0 ) ) ; } export function updateNodes ( oldItems , newItems , prevChildren , slide , infinite ) { if ( prevChildren && prevChildren . length < newItems . length ) { return initItems ( newItems , slide , infinite ) ; } const matchedItems = oldItems . map ( ( oldItem ) => { return newItems . find ( ( newItem ) => oldItem . key === newItem . key ) as Item ; } ) ; if ( areItemsNotMatched ( matchedItems ) ) { return initItems ( newItems , slide , infinite ) ; } return matchedItems ; } export function areItemsNotMatched ( items ) { return items . some ( ( item ) => item === undefined ) ; }