export default function Grid({ swiper, extendParams }) { extendParams({ grid: { rows: 1, fill: 'column' } }); let slidesNumberEvenToRows; let slidesPerRow; let numFullColumns; const getSpaceBetween = () => { let spaceBetween = swiper.params.spaceBetween; if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) { spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiper.size; } else if (typeof spaceBetween === 'string') { spaceBetween = parseFloat(spaceBetween); } return spaceBetween; }; const initSlides = slidesLength => { const { slidesPerView } = swiper.params; const { rows, fill } = swiper.params.grid; numFullColumns = Math.floor(slidesLength / rows); if (Math.floor(slidesLength / rows) === slidesLength / rows) { slidesNumberEvenToRows = slidesLength; } else { slidesNumberEvenToRows = Math.ceil(slidesLength / rows) * rows; } if (slidesPerView !== 'auto' && fill === 'row') { slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, slidesPerView * rows); } slidesPerRow = slidesNumberEvenToRows / rows; }; const updateSlide = (i, slide, slidesLength, getDirectionLabel) => { const { slidesPerGroup } = swiper.params; const spaceBetween = getSpaceBetween(); const { rows, fill } = swiper.params.grid; // Set slides order let newSlideOrderIndex; let column; let row; if (fill === 'row' && slidesPerGroup > 1) { const groupIndex = Math.floor(i / (slidesPerGroup * rows)); const slideIndexInGroup = i - rows * slidesPerGroup * groupIndex; const columnsInGroup = groupIndex === 0 ? slidesPerGroup : Math.min(Math.ceil((slidesLength - groupIndex * rows * slidesPerGroup) / rows), slidesPerGroup); row = Math.floor(slideIndexInGroup / columnsInGroup); column = slideIndexInGroup - row * columnsInGroup + groupIndex * slidesPerGroup; newSlideOrderIndex = column + row * slidesNumberEvenToRows / rows; slide.style.order = newSlideOrderIndex; } else if (fill === 'column') { column = Math.floor(i / rows); row = i - column * rows; if (column > numFullColumns || column === numFullColumns && row === rows - 1) { row += 1; if (row >= rows) { row = 0; column += 1; } } } else { row = Math.floor(i / slidesPerRow); column = i - row * slidesPerRow; } slide.row = row; slide.column = column; slide.style[getDirectionLabel('margin-top')] = row !== 0 ? spaceBetween && `${spaceBetween}px` : ''; }; const updateWrapperSize = (slideSize, snapGrid, getDirectionLabel) => { const { centeredSlides, roundLengths } = swiper.params; const spaceBetween = getSpaceBetween(); const { rows } = swiper.params.grid; swiper.virtualSize = (slideSize + spaceBetween) * slidesNumberEvenToRows; swiper.virtualSize = Math.ceil(swiper.virtualSize / rows) - spaceBetween; swiper.wrapperEl.style[getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`; if (centeredSlides) { const newSlidesGrid = []; for (let i = 0; i < snapGrid.length; i += 1) { let slidesGridItem = snapGrid[i]; if (roundLengths) slidesGridItem = Math.floor(slidesGridItem); if (snapGrid[i] < swiper.virtualSize + snapGrid[0]) newSlidesGrid.push(slidesGridItem); } snapGrid.splice(0, snapGrid.length); snapGrid.push(...newSlidesGrid); } }; swiper.grid = { initSlides, updateSlide, updateWrapperSize }; }