import { window } from 'ssr-window'; import Utils from '../../../utils/utils'; export default function () { const swiper = this; const params = swiper.params; const { $wrapperEl, size: swiperSize, rtlTranslate: rtl, wrongRTL, } = swiper; const isVirtual = swiper.virtual && params.virtual.enabled; const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length; const slides = $wrapperEl.children(`.${swiper.params.slideClass}`); const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length; let snapGrid = []; const slidesGrid = []; const slidesSizesGrid = []; function slidesForMargin(slideIndex) { if (!params.cssMode) return true; if (slideIndex === slides.length - 1) { return false; } return true; } let offsetBefore = params.slidesOffsetBefore; if (typeof offsetBefore === 'function') { offsetBefore = params.slidesOffsetBefore.call(swiper); } let offsetAfter = params.slidesOffsetAfter; if (typeof offsetAfter === 'function') { offsetAfter = params.slidesOffsetAfter.call(swiper); } const previousSnapGridLength = swiper.snapGrid.length; const previousSlidesGridLength = swiper.snapGrid.length; let spaceBetween = params.spaceBetween; let slidePosition = -offsetBefore; let prevSlideSize = 0; let index = 0; if (typeof swiperSize === 'undefined') { return; } if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) { spaceBetween = (parseFloat(spaceBetween.replace('%', '')) / 100) * swiperSize; } swiper.virtualSize = -spaceBetween; // reset margins if (rtl) slides.css({ marginLeft: '', marginTop: '' }); else slides.css({ marginRight: '', marginBottom: '' }); let slidesNumberEvenToRows; if (params.slidesPerColumn > 1) { if (Math.floor(slidesLength / params.slidesPerColumn) === slidesLength / swiper.params.slidesPerColumn) { slidesNumberEvenToRows = slidesLength; } else { slidesNumberEvenToRows = Math.ceil(slidesLength / params.slidesPerColumn) * params.slidesPerColumn; } if (params.slidesPerView !== 'auto' && params.slidesPerColumnFill === 'row') { slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, params.slidesPerView * params.slidesPerColumn); } } // Calc slides let slideSize; const slidesPerColumn = params.slidesPerColumn; const slidesPerRow = slidesNumberEvenToRows / slidesPerColumn; const numFullColumns = Math.floor(slidesLength / params.slidesPerColumn); for (let i = 0; i < slidesLength; i += 1) { slideSize = 0; const slide = slides.eq(i); if (params.slidesPerColumn > 1) { // Set slides order let newSlideOrderIndex; let column; let row; if (params.slidesPerColumnFill === 'row' && params.slidesPerGroup > 1) { const groupIndex = Math.floor(i / (params.slidesPerGroup * params.slidesPerColumn)); const slideIndexInGroup = i - params.slidesPerColumn * params.slidesPerGroup * groupIndex; const columnsInGroup = groupIndex === 0 ? params.slidesPerGroup : Math.min(Math.ceil((slidesLength - groupIndex * slidesPerColumn * params.slidesPerGroup) / slidesPerColumn), params.slidesPerGroup); row = Math.floor(slideIndexInGroup / columnsInGroup); column = (slideIndexInGroup - row * columnsInGroup) + groupIndex * params.slidesPerGroup; newSlideOrderIndex = column + ((row * slidesNumberEvenToRows) / slidesPerColumn); slide .css({ '-webkit-box-ordinal-group': newSlideOrderIndex, '-moz-box-ordinal-group': newSlideOrderIndex, '-ms-flex-order': newSlideOrderIndex, '-webkit-order': newSlideOrderIndex, order: newSlideOrderIndex, }); } else if (params.slidesPerColumnFill === 'column') { column = Math.floor(i / slidesPerColumn); row = i - (column * slidesPerColumn); if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn - 1)) { row += 1; if (row >= slidesPerColumn) { row = 0; column += 1; } } } else { row = Math.floor(i / slidesPerRow); column = i - (row * slidesPerRow); } slide.css( `margin-${swiper.isHorizontal() ? 'top' : 'left'}`, (row !== 0 && params.spaceBetween) && (`${params.spaceBetween}px`) ); } if (slide.css('display') === 'none') continue; // eslint-disable-line if (params.slidesPerView === 'auto') { const slideStyles = window.getComputedStyle(slide[0], null); const currentTransform = slide[0].style.transform; const currentWebKitTransform = slide[0].style.webkitTransform; if (currentTransform) { slide[0].style.transform = 'none'; } if (currentWebKitTransform) { slide[0].style.webkitTransform = 'none'; } if (params.roundLengths) { slideSize = swiper.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true); } else { // eslint-disable-next-line if (swiper.isHorizontal()) { const width = parseFloat(slideStyles.getPropertyValue('width')); const paddingLeft = parseFloat(slideStyles.getPropertyValue('padding-left')); const paddingRight = parseFloat(slideStyles.getPropertyValue('padding-right')); const marginLeft = parseFloat(slideStyles.getPropertyValue('margin-left')); const marginRight = parseFloat(slideStyles.getPropertyValue('margin-right')); const boxSizing = slideStyles.getPropertyValue('box-sizing'); if (boxSizing && boxSizing === 'border-box') { slideSize = width + marginLeft + marginRight; } else { slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight; } } else { const height = parseFloat(slideStyles.getPropertyValue('height')); const paddingTop = parseFloat(slideStyles.getPropertyValue('padding-top')); const paddingBottom = parseFloat(slideStyles.getPropertyValue('padding-bottom')); const marginTop = parseFloat(slideStyles.getPropertyValue('margin-top')); const marginBottom = parseFloat(slideStyles.getPropertyValue('margin-bottom')); const boxSizing = slideStyles.getPropertyValue('box-sizing'); if (boxSizing && boxSizing === 'border-box') { slideSize = height + marginTop + marginBottom; } else { slideSize = height + paddingTop + paddingBottom + marginTop + marginBottom; } } } if (currentTransform) { slide[0].style.transform = currentTransform; } if (currentWebKitTransform) { slide[0].style.webkitTransform = currentWebKitTransform; } if (params.roundLengths) slideSize = Math.floor(slideSize); } else { slideSize = (swiperSize - ((params.slidesPerView - 1) * spaceBetween)) / params.slidesPerView; if (params.roundLengths) slideSize = Math.floor(slideSize); if (slides[i]) { if (swiper.isHorizontal()) { slides[i].style.width = `${slideSize}px`; } else { slides[i].style.height = `${slideSize}px`; } } } if (slides[i]) { slides[i].swiperSlideSize = slideSize; } slidesSizesGrid.push(slideSize); if (params.centeredSlides) { slidePosition = slidePosition + (slideSize / 2) + (prevSlideSize / 2) + spaceBetween; if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - (swiperSize / 2) - spaceBetween; if (i === 0) slidePosition = slidePosition - (swiperSize / 2) - spaceBetween; if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0; if (params.roundLengths) slidePosition = Math.floor(slidePosition); if ((index) % params.slidesPerGroup === 0) snapGrid.push(slidePosition); slidesGrid.push(slidePosition); } else { if (params.roundLengths) slidePosition = Math.floor(slidePosition); if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) snapGrid.push(slidePosition); slidesGrid.push(slidePosition); slidePosition = slidePosition + slideSize + spaceBetween; } swiper.virtualSize += slideSize + spaceBetween; prevSlideSize = slideSize; index += 1; } swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter; let newSlidesGrid; if ( rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) { $wrapperEl.css({ width: `${swiper.virtualSize + params.spaceBetween}px` }); } if (params.setWrapperSize) { if (swiper.isHorizontal()) $wrapperEl.css({ width: `${swiper.virtualSize + params.spaceBetween}px` }); else $wrapperEl.css({ height: `${swiper.virtualSize + params.spaceBetween}px` }); } if (params.slidesPerColumn > 1) { swiper.virtualSize = (slideSize + params.spaceBetween) * slidesNumberEvenToRows; swiper.virtualSize = Math.ceil(swiper.virtualSize / params.slidesPerColumn) - params.spaceBetween; if (swiper.isHorizontal()) $wrapperEl.css({ width: `${swiper.virtualSize + params.spaceBetween}px` }); else $wrapperEl.css({ height: `${swiper.virtualSize + params.spaceBetween}px` }); if (params.centeredSlides) { newSlidesGrid = []; for (let i = 0; i < snapGrid.length; i += 1) { let slidesGridItem = snapGrid[i]; if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem); if (snapGrid[i] < swiper.virtualSize + snapGrid[0]) newSlidesGrid.push(slidesGridItem); } snapGrid = newSlidesGrid; } } // Remove last grid elements depending on width if (!params.centeredSlides) { newSlidesGrid = []; for (let i = 0; i < snapGrid.length; i += 1) { let slidesGridItem = snapGrid[i]; if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem); if (snapGrid[i] <= swiper.virtualSize - swiperSize) { newSlidesGrid.push(slidesGridItem); } } snapGrid = newSlidesGrid; if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) { snapGrid.push(swiper.virtualSize - swiperSize); } } if (snapGrid.length === 0) snapGrid = [0]; if (params.spaceBetween !== 0) { if (swiper.isHorizontal()) { if (rtl) slides.filter(slidesForMargin).css({ marginLeft: `${spaceBetween}px` }); else slides.filter(slidesForMargin).css({ marginRight: `${spaceBetween}px` }); } else slides.filter(slidesForMargin).css({ marginBottom: `${spaceBetween}px` }); } if (params.centeredSlides && params.centeredSlidesBounds) { let allSlidesSize = 0; slidesSizesGrid.forEach((slideSizeValue) => { allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0); }); allSlidesSize -= params.spaceBetween; const maxSnap = allSlidesSize - swiperSize; snapGrid = snapGrid.map((snap) => { if (snap < 0) return -offsetBefore; if (snap > maxSnap) return maxSnap + offsetAfter; return snap; }); } if (params.centerInsufficientSlides) { let allSlidesSize = 0; slidesSizesGrid.forEach((slideSizeValue) => { allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0); }); allSlidesSize -= params.spaceBetween; if (allSlidesSize < swiperSize) { const allSlidesOffset = (swiperSize - allSlidesSize) / 2; snapGrid.forEach((snap, snapIndex) => { snapGrid[snapIndex] = snap - allSlidesOffset; }); slidesGrid.forEach((snap, snapIndex) => { slidesGrid[snapIndex] = snap + allSlidesOffset; }); } } Utils.extend(swiper, { slides, snapGrid, slidesGrid, slidesSizesGrid, }); if (slidesLength !== previousSlidesLength) { swiper.emit('slidesLengthChange'); } if (snapGrid.length !== previousSnapGridLength) { if (swiper.params.watchOverflow) swiper.checkOverflow(); swiper.emit('snapGridLengthChange'); } if (slidesGrid.length !== previousSlidesGridLength) { swiper.emit('slidesGridLengthChange'); } if (params.watchSlidesProgress || params.watchSlidesVisibility) { swiper.updateSlidesOffset(); } }