/// import { addClass, removeClass, getTouchCoords, getInitialItemsOrder, calcStepIndex } from './helpers'; import * as SE from './side-effects'; import { getNextIndex, getVars } from './helpers'; export const reorder = (index: CarouselIndex, items: SlidesOrder): SlidesOrder => { let fst = items.slice(items.length - index, items.length); let snd = items.slice(0, items.length - index); return fst.concat(snd); }; // This function will be called either by the event listener or in updateInfinite fn. export const afterInfiniteUpdated = (state: ICarousel, supposeToMoveToLeft: boolean): CarouselState => { let { element, container, itemsOrder, offset, index } = state; const { stepWidth } = getVars(element, container); let items = Array.from(container.children); if (supposeToMoveToLeft) { removeClass('as24-carousel__container--static', container); } else { addClass('as24-carousel__container--static', container); if (itemsOrder !== undefined) { SE.doSetPositioning(2, items, SE.doReorderItems(items, itemsOrder)); } } SE.doMove(container, 0); state.itemsOrder = getInitialItemsOrder(container.children); state.busy = false; return state; }; export const updateInfinite = (dir: MoveDirection, state: ICarousel, triggerNotifications: boolean): ICarousel => { let { element, container, touchStart, offset, index, pagination, mode } = state; const { stepWidth, itemsVisible } = getVars(element, container); let items = Array.from(container.children); index = dir !== 0 ? calcStepIndex(dir, state) : index; offset = dir === -1 ? (offset === 0 ? dir * stepWidth : dir * offset) : dir * stepWidth; const initialOrder = getInitialItemsOrder(container.children); const itemsOrder = reorder(index, initialOrder); let busy = true; if (dir < 0) { addClass('as24-carousel__container--static', container); SE.doSetPositioning(2, items, SE.doReorderItems(items, itemsOrder)); SE.doMove(container, -1 * offset); afterInfiniteUpdated(state, true); } else if (dir > 0) { removeClass('as24-carousel__container--static', container); SE.doMove(container, offset); } else { addClass('as24-carousel__container--static', container); SE.doMove(container, offset); SE.doSetPositioning(2, items, SE.doReorderItems(items, itemsOrder)); busy = false; } if (triggerNotifications) { SE.doNotify(element, dir, index); } SE.doUpdateIndicator(pagination.indicator, index + 1, container.children.length); return { index, touchStart, offset: 0, itemsOrder, busy, isSwiping: false, swipeDir: undefined, element, container, mode, pagination }; }; export const swipeStartsInfinite = (touch: PosCoordinates, state: ICarousel): CarouselState => { const { offset, index, container, itemsOrder } = state; addClass('as24-carousel__container--static', container); return { touchStart: touch, index, offset: 0, itemsOrder, isSwiping: undefined, swipeDir: undefined }; }; export const swipeContinuousInfinite = (currentPos: PosCoordinates, state: ICarousel): CarouselState => { let { touchStart, index, container, element, isSwiping, swipeDir } = state; let offset = 0, itemsOrder, items; const distanceX = Math.abs(currentPos.x - touchStart.x); const distanceY = Math.abs(currentPos.y - touchStart.y); const { stepWidth, itemsVisible } = getVars(element, container); if (swipeDir === undefined) { swipeDir = touchStart.x - currentPos.x > 0 ? 1 : -1; } if (isSwiping) { if (swipeDir === -1) { itemsOrder = reorder(calcStepIndex(swipeDir, state), getInitialItemsOrder(container.children)); items = Array.from(container.children); SE.doSetPositioning(2, items, SE.doReorderItems(items, itemsOrder)); offset = touchStart.x - currentPos.x > 0 ? stepWidth : stepWidth + (-1 * (currentPos.x - touchStart.x)); } else { offset = touchStart.x - currentPos.x < 0 ? 0 : -1 * (currentPos.x - touchStart.x); } SE.doMove(container, offset); } return { index, touchStart, offset, itemsOrder, swipeDir, isSwiping: isSwiping === undefined ? distanceX / distanceY > .6 : isSwiping }; }; export const swipeEndsInfinite = (finalTouch: PosCoordinates, state: ICarousel): CarouselState => { const { index, offset, touchStart, container, isSwiping, swipeDir } = state; if (isSwiping) { removeClass('as24-carousel__container--static', container); const swipedToFarToLeft = (swipeDir === -1 && touchStart.x - finalTouch.x > 0); const swipedToFarToRight = (swipeDir === 1 && touchStart.x - finalTouch.x < 0); if (swipedToFarToLeft || swipedToFarToRight) { return updateInfinite(0, state, false); } return updateInfinite(swipeDir, state, true); } };