Skip to content

Commit

Permalink
feat: reworked loop mode
Browse files Browse the repository at this point in the history
  • Loading branch information
nolimits4web committed Sep 29, 2023
1 parent 703ede6 commit 2a99dbd
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 38 deletions.
10 changes: 8 additions & 2 deletions playground/core/index.html
Expand Up @@ -57,6 +57,11 @@
justify-content: center;
font-size: 22px;
background: #fff;
width: 100px;
}

.swiper-slide:not(.swiper-slide-active) {
opacity: 0.75;
}
</style>
<script type="module">
Expand All @@ -68,8 +73,9 @@

window.swiper = new Swiper(".swiper", {
spaceBetween: 20,
slidesPerView: 3,
centeredSlides: true,
slidesPerView: 2,
slidesPerGroup: 2,
// centeredSlides: true,
loop: true,
createElements: true,
pagination: {
Expand Down
6 changes: 5 additions & 1 deletion src/core/events/onTouchEnd.mjs
Expand Up @@ -25,6 +25,7 @@ export default function onTouchEnd(event) {
return;
}
}

data.pointerId = null;
data.touchId = null;
const { params, touches, rtlTranslate: rtl, slidesGrid, enabled } = swiper;
Expand All @@ -43,6 +44,7 @@ export default function onTouchEnd(event) {
data.startMoving = false;
return;
}

// Return Grab Cursor
if (
params.grabCursor &&
Expand Down Expand Up @@ -71,18 +73,20 @@ export default function onTouchEnd(event) {
nextTick(() => {
if (!swiper.destroyed) swiper.allowClick = true;
});

if (
!data.isTouched ||
!data.isMoved ||
!swiper.swipeDirection ||
touches.diff === 0 ||
(touches.diff === 0 && !data.loopSwapReset) ||
(data.currentTranslate === data.startTranslate && !data.loopSwapReset)
) {
data.isTouched = false;
data.isMoved = false;
data.startMoving = false;
return;
}

data.isTouched = false;
data.isMoved = false;
data.startMoving = false;
Expand Down
1 change: 1 addition & 0 deletions src/core/events/onTouchMove.mjs
Expand Up @@ -182,6 +182,7 @@ export default function onTouchMove(event) {
}
let loopFixed;
let time = new Date().getTime();

if (
data.isMoved &&
data.allowThresholdMove &&
Expand Down
10 changes: 10 additions & 0 deletions src/core/loop/loopCreate.mjs
Expand Up @@ -11,5 +11,15 @@ export default function loopCreate(slideRealIndex) {
el.setAttribute('data-swiper-slide-index', index);
});

if (swiper.slides.length % params.slidesPerGroup !== 0) {
try {
console.warn(
'Swiper Loop Warning: The number of slides is not even to slidesPerGroup, loop mode may not function properly. You need to add more slides (or make duplicates, or empty slides)',
);
} catch (err) {
// err
}
}

swiper.loopFix({ slideRealIndex, direction: params.centeredSlides ? undefined : 'next' });
}
11 changes: 7 additions & 4 deletions src/core/loop/loopFix.mjs
Expand Up @@ -48,7 +48,10 @@ export default function loopFix({

if (swiper.slides.length < slidesPerView + loopedSlides) {
try {
console.warn('Swiper: amount of slides is insufficient for loop mode, it will be disabled');
console.warn(
'Swiper Loop Warning: The number of slides is not enough for loop mode, it will be disabled and not function properly. You need to add more slides (or make duplicates) or lower the values of slidesPerView and slidesPerGroup parameters',
);
return;
} catch (err) {
// err
}
Expand Down Expand Up @@ -96,6 +99,7 @@ export default function loopFix({
if (isPrev) {
prependSlidesIndexes.forEach((index) => {
swiper.slides[index].swiperLoopMoveDOM = true;

slidesEl.prepend(swiper.slides[index]);
swiper.slides[index].swiperLoopMoveDOM = false;
});
Expand All @@ -115,7 +119,6 @@ export default function loopFix({
if (params.watchSlidesProgress) {
swiper.updateSlidesOffset();
}

if (slideTo) {
if (prependSlidesIndexes.length > 0 && isPrev) {
if (typeof slideRealIndex === 'undefined') {
Expand All @@ -134,7 +137,7 @@ export default function loopFix({
}
} else {
if (setTranslate) {
swiper.slideToLoop(slideRealIndex, 0, false, true);
swiper.slideTo(swiper.activeIndex + prependSlidesIndexes.length, 0, false, true);
swiper.touchEventsData.currentTranslate = swiper.translate;
}
}
Expand All @@ -154,7 +157,7 @@ export default function loopFix({
}
}
} else {
swiper.slideToLoop(slideRealIndex, 0, false, true);
swiper.slideTo(swiper.activeIndex - appendSlidesIndexes.length, 0, false, true);
}
}
}
Expand Down
34 changes: 34 additions & 0 deletions src/core/slide/slideToLoop.mjs
Expand Up @@ -17,6 +17,40 @@ export default function slideToLoop(
// eslint-disable-next-line
newIndex = newIndex + swiper.virtual.slidesBefore;
} else {
const targetSlideIndex = swiper.getSlideIndexByData(newIndex);
const slides = swiper.slides.length;
const { centeredSlides } = swiper.params;
let slidesPerView = swiper.params.slidesPerView;
if (slidesPerView === 'auto') {
slidesPerView = swiper.slidesPerViewDynamic();
} else {
slidesPerView = Math.ceil(parseFloat(swiper.params.slidesPerView, 10));
if (centeredSlides && slidesPerView % 2 === 0) {
slidesPerView = slidesPerView + 1;
}
}
let needLoopFix = slides - targetSlideIndex < slidesPerView;
if (centeredSlides) {
needLoopFix = needLoopFix || targetSlideIndex < Math.ceil(slidesPerView / 2);
}
if (needLoopFix) {
const direction = centeredSlides
? targetSlideIndex < swiper.activeIndex
? 'prev'
: 'next'
: targetSlideIndex - swiper.activeIndex - 1 < swiper.params.slidesPerView
? 'next'
: 'prev';

swiper.loopFix({
direction,
slideTo: true,
activeSlideIndex:
direction === 'next' ? targetSlideIndex + 1 : targetSlideIndex - slides + 1,
slideRealIndex: direction === 'next' ? swiper.realIndex : undefined,
});
}

newIndex = swiper.getSlideIndexByData(newIndex);
}
}
Expand Down
15 changes: 11 additions & 4 deletions src/core/update/updateActiveIndex.mjs
Expand Up @@ -57,16 +57,23 @@ export default function updateActiveIndex(newActiveIndex) {
snapIndex = skip + Math.floor((activeIndex - skip) / params.slidesPerGroup);
}
if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
if (activeIndex === previousIndex) {
if (activeIndex === previousIndex && !swiper.params.loop) {
if (snapIndex !== previousSnapIndex) {
swiper.snapIndex = snapIndex;
swiper.emit('snapIndexChange');
}
if (swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
swiper.realIndex = getVirtualRealIndex(activeIndex);
}
return;
}
if (
activeIndex === previousIndex &&
swiper.params.loop &&
swiper.virtual &&
swiper.params.virtual.enabled
) {
swiper.realIndex = getVirtualRealIndex(activeIndex);
return;
}

// Get real index
let realIndex;
if (swiper.virtual && params.virtual.enabled && params.loop) {
Expand Down
27 changes: 0 additions & 27 deletions src/modules/pagination/pagination.mjs
Expand Up @@ -76,33 +76,6 @@ export default function Pagination({ swiper, extendParams, on, emit }) {
const index = elementIndex(bulletEl) * swiper.params.slidesPerGroup;
if (swiper.params.loop) {
if (swiper.realIndex === index) return;
const realIndex = swiper.realIndex;
const newSlideIndex = swiper.getSlideIndexByData(index);
const currentSlideIndex = swiper.getSlideIndexByData(swiper.realIndex);
const loopFix = (dir) => {
const indexBeforeLoopFix = swiper.activeIndex;
swiper.loopFix({
direction: dir,
activeSlideIndex: newSlideIndex,
slideTo: false,
});
const indexAfterFix = swiper.activeIndex;
if (indexBeforeLoopFix === indexAfterFix) {
swiper.slideToLoop(realIndex, 0, false, true);
}
};
if (newSlideIndex > swiper.slides.length - swiper.loopedSlides) {
loopFix(newSlideIndex > currentSlideIndex ? 'next' : 'prev');
} else if (swiper.params.centeredSlides) {
const slidesPerView =
swiper.params.slidesPerView === 'auto'
? swiper.slidesPerViewDynamic()
: Math.ceil(parseFloat(swiper.params.slidesPerView, 10));
if (newSlideIndex < Math.floor(slidesPerView / 2)) {
loopFix('prev');
}
}

swiper.slideToLoop(index);
} else {
swiper.slideTo(index);
Expand Down

0 comments on commit 2a99dbd

Please sign in to comment.