grid.mjs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. function Grid(_ref) {
  2. let {
  3. swiper,
  4. extendParams,
  5. on
  6. } = _ref;
  7. extendParams({
  8. grid: {
  9. rows: 1,
  10. fill: 'column'
  11. }
  12. });
  13. let slidesNumberEvenToRows;
  14. let slidesPerRow;
  15. let numFullColumns;
  16. let wasMultiRow;
  17. const getSpaceBetween = () => {
  18. let spaceBetween = swiper.params.spaceBetween;
  19. if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
  20. spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiper.size;
  21. } else if (typeof spaceBetween === 'string') {
  22. spaceBetween = parseFloat(spaceBetween);
  23. }
  24. return spaceBetween;
  25. };
  26. const initSlides = slides => {
  27. const {
  28. slidesPerView
  29. } = swiper.params;
  30. const {
  31. rows,
  32. fill
  33. } = swiper.params.grid;
  34. const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : slides.length;
  35. numFullColumns = Math.floor(slidesLength / rows);
  36. if (Math.floor(slidesLength / rows) === slidesLength / rows) {
  37. slidesNumberEvenToRows = slidesLength;
  38. } else {
  39. slidesNumberEvenToRows = Math.ceil(slidesLength / rows) * rows;
  40. }
  41. if (slidesPerView !== 'auto' && fill === 'row') {
  42. slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, slidesPerView * rows);
  43. }
  44. slidesPerRow = slidesNumberEvenToRows / rows;
  45. };
  46. const unsetSlides = () => {
  47. if (swiper.slides) {
  48. swiper.slides.forEach(slide => {
  49. if (slide.swiperSlideGridSet) {
  50. slide.style.height = '';
  51. slide.style[swiper.getDirectionLabel('margin-top')] = '';
  52. }
  53. });
  54. }
  55. };
  56. const updateSlide = (i, slide, slides) => {
  57. const {
  58. slidesPerGroup
  59. } = swiper.params;
  60. const spaceBetween = getSpaceBetween();
  61. const {
  62. rows,
  63. fill
  64. } = swiper.params.grid;
  65. const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : slides.length;
  66. // Set slides order
  67. let newSlideOrderIndex;
  68. let column;
  69. let row;
  70. if (fill === 'row' && slidesPerGroup > 1) {
  71. const groupIndex = Math.floor(i / (slidesPerGroup * rows));
  72. const slideIndexInGroup = i - rows * slidesPerGroup * groupIndex;
  73. const columnsInGroup = groupIndex === 0 ? slidesPerGroup : Math.min(Math.ceil((slidesLength - groupIndex * rows * slidesPerGroup) / rows), slidesPerGroup);
  74. row = Math.floor(slideIndexInGroup / columnsInGroup);
  75. column = slideIndexInGroup - row * columnsInGroup + groupIndex * slidesPerGroup;
  76. newSlideOrderIndex = column + row * slidesNumberEvenToRows / rows;
  77. slide.style.order = newSlideOrderIndex;
  78. } else if (fill === 'column') {
  79. column = Math.floor(i / rows);
  80. row = i - column * rows;
  81. if (column > numFullColumns || column === numFullColumns && row === rows - 1) {
  82. row += 1;
  83. if (row >= rows) {
  84. row = 0;
  85. column += 1;
  86. }
  87. }
  88. } else {
  89. row = Math.floor(i / slidesPerRow);
  90. column = i - row * slidesPerRow;
  91. }
  92. slide.row = row;
  93. slide.column = column;
  94. slide.style.height = `calc((100% - ${(rows - 1) * spaceBetween}px) / ${rows})`;
  95. slide.style[swiper.getDirectionLabel('margin-top')] = row !== 0 ? spaceBetween && `${spaceBetween}px` : '';
  96. slide.swiperSlideGridSet = true;
  97. };
  98. const updateWrapperSize = (slideSize, snapGrid) => {
  99. const {
  100. centeredSlides,
  101. roundLengths
  102. } = swiper.params;
  103. const spaceBetween = getSpaceBetween();
  104. const {
  105. rows
  106. } = swiper.params.grid;
  107. swiper.virtualSize = (slideSize + spaceBetween) * slidesNumberEvenToRows;
  108. swiper.virtualSize = Math.ceil(swiper.virtualSize / rows) - spaceBetween;
  109. if (!swiper.params.cssMode) {
  110. swiper.wrapperEl.style[swiper.getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`;
  111. }
  112. if (centeredSlides) {
  113. const newSlidesGrid = [];
  114. for (let i = 0; i < snapGrid.length; i += 1) {
  115. let slidesGridItem = snapGrid[i];
  116. if (roundLengths) slidesGridItem = Math.floor(slidesGridItem);
  117. if (snapGrid[i] < swiper.virtualSize + snapGrid[0]) newSlidesGrid.push(slidesGridItem);
  118. }
  119. snapGrid.splice(0, snapGrid.length);
  120. snapGrid.push(...newSlidesGrid);
  121. }
  122. };
  123. const onInit = () => {
  124. wasMultiRow = swiper.params.grid && swiper.params.grid.rows > 1;
  125. };
  126. const onUpdate = () => {
  127. const {
  128. params,
  129. el
  130. } = swiper;
  131. const isMultiRow = params.grid && params.grid.rows > 1;
  132. if (wasMultiRow && !isMultiRow) {
  133. el.classList.remove(`${params.containerModifierClass}grid`, `${params.containerModifierClass}grid-column`);
  134. numFullColumns = 1;
  135. swiper.emitContainerClasses();
  136. } else if (!wasMultiRow && isMultiRow) {
  137. el.classList.add(`${params.containerModifierClass}grid`);
  138. if (params.grid.fill === 'column') {
  139. el.classList.add(`${params.containerModifierClass}grid-column`);
  140. }
  141. swiper.emitContainerClasses();
  142. }
  143. wasMultiRow = isMultiRow;
  144. };
  145. on('init', onInit);
  146. on('update', onUpdate);
  147. swiper.grid = {
  148. initSlides,
  149. unsetSlides,
  150. updateSlide,
  151. updateWrapperSize
  152. };
  153. }
  154. export { Grid as default };