UNPKG

@zebra-ui/swiper

Version:

专为多端设计的高性能swiper轮播组件库,支持多种复杂的 3D swiper轮播效果。

162 lines (143 loc) 4.51 kB
import { preload } from '../../shared/process-lazy-preloader' import { isWeb } from '../../shared/utils' import type { GetActiveIndexByTranslate, UpdateActiveIndex } from '../../../types/components/core/update/update-active-index' import type { SwiperEvents } from '../../../types/swiper-events' export const getActiveIndexByTranslate: GetActiveIndexByTranslate = ( swiper ) => { const { slidesGrid, params } = swiper const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate let activeIndex: number | undefined for (let i = 0; i < slidesGrid.length; i += 1) { if (typeof slidesGrid[i + 1] !== 'undefined') { if ( translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - (slidesGrid[i + 1] - slidesGrid[i]) / 2 ) { activeIndex = i } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) { activeIndex = i + 1 } } else if (translate >= slidesGrid[i]) { activeIndex = i } } if (params.normalizeSlideIndex) { if ( (typeof activeIndex === 'number' && activeIndex < 0) || typeof activeIndex === 'undefined' ) activeIndex = 0 } return activeIndex || 0 } const updateActiveIndex: UpdateActiveIndex = function (newActiveIndex) { const swiper = this const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate const { snapGrid, params, activeIndex: previousIndex, realIndex: previousRealIndex, snapIndex: previousSnapIndex } = swiper let activeIndex = newActiveIndex let snapIndex: number const getVirtualRealIndex = (aIndex: number): number => { let realIndex = aIndex - swiper.virtual.slidesBefore if (realIndex < 0) { realIndex = swiper.virtual.slides.length + realIndex } if (realIndex >= swiper.virtual.slides.length) { realIndex -= swiper.virtual.slides.length } return realIndex } if (typeof activeIndex === 'undefined') { activeIndex = getActiveIndexByTranslate(swiper) } if (snapGrid.indexOf(translate) >= 0) { snapIndex = snapGrid.indexOf(translate) } else { const skip = Math.min(params.slidesPerGroupSkip || 0, activeIndex) snapIndex = skip + Math.floor((activeIndex - skip) / (params.slidesPerGroup || 1)) } if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1 if (activeIndex === previousIndex && !swiper.params.loop) { if (snapIndex !== previousSnapIndex) { swiper.snapIndex = snapIndex swiper.emit('snapIndexChange' as keyof SwiperEvents) } return } if ( activeIndex === previousIndex && swiper.params.loop && swiper.virtual && typeof swiper.params.virtual === 'object' && swiper.params.virtual.enabled ) { swiper.realIndex = getVirtualRealIndex(activeIndex) return } const gridEnabled = swiper.grid && params.grid && typeof params.grid === 'object' && params.grid.rows && params.grid.rows > 1 let realIndex: number if ( swiper.virtual && params.virtual && typeof params.virtual === 'object' && params.virtual.enabled && params.loop ) { realIndex = getVirtualRealIndex(activeIndex) } else if (gridEnabled) { const firstSlideInColumn = swiper.slides.filter( (slideEl) => slideEl.getAttribute('data-swiper-column') === String(activeIndex) )[0] const activeSlideIndex = parseInt( firstSlideInColumn?.getAttribute('data-swiper-slide-index') || '0', 10 ) realIndex = Math.floor( Number.isNaN(activeSlideIndex) ? // @ts-ignore Math.max(swiper.slides.indexOf(firstSlideInColumn), 0) : activeSlideIndex / (params.grid?.rows || 1) ) } else { const slideIndex = swiper.slides[activeIndex]?.getAttribute( 'data-swiper-slide-index' ) realIndex = slideIndex ? parseInt(slideIndex, 10) : activeIndex } Object.assign(swiper, { snapIndex, realIndex, previousIndex, activeIndex, previousRealIndex, previousSnapIndex }) if (isWeb() && swiper.initialized) { preload(swiper) } swiper.emit('activeIndexChange' as keyof SwiperEvents) swiper.emit('snapIndexChange' as keyof SwiperEvents) if (swiper.initialized || swiper.params.runCallbacksOnInit) { if (previousRealIndex !== realIndex) { swiper.emit('realIndexChange' as keyof SwiperEvents) } swiper.emit('slideChange' as keyof SwiperEvents) } } export default updateActiveIndex