swiper
swiper copied to clipboard
Jumping to slide 3 glitch from wrong progress calculation when changing slidesPerView (with virtual slides)
Check that this is really a bug
- [X] I confirm
Reproduction link
https://codesandbox.io/s/swiper-virtual-slides-vue-forked-yn6m2u?file=/src/App.vue
Bug description
Please see reproduction codesandbox.
Lets say you have 20 Slides and 1 slidesPerView. Then you go to any slide greater than 10, lets say 12. If you then add one slidePerView it jumps back to slide 3.
I did some debugging and found out why slide 3 and why jump at all. But still haven't found the root cause and how to fix it (update order of translate and maxTranslate()? Or some deeper probem?).
Why do we jump?
I found a wrong progress calculation in updateProgress.js
progress = (translate - swiper.minTranslate()) / translatesDiff;
isBeginning = progress <= 0;
isEnd = progress >= 1;
The problem is that progress should be between 0.0 and 1.0 (last slide). But in the reproduction scenario it glitches to values greater 1.0 like 1.75. Which leads to isEnd = true (but we are still at slide 12 not 20!)
With translatesDiff which is practically maxTranslate() and minTranslate() as 0 we can simplify for clarity as:
progress = translate / maxTranslate()
Both of these values change when we change slidesPerView. More slides = smaller slides, smaller translation and maxTranslation and vice versa.
While debugging I noticed that in the reproduction scenario maxTranslate() is already updated to two-slides-width while translate still has the one-slide-width. Which leads to values larger than 1.0
Why slide 3?
Now that isEnd = true we get to core.js
if ((swiper.params.slidesPerView === 'auto' || swiper.params.slidesPerView > 1) && swiper.isEnd && !swiper.params.centeredSlides) {
translated = swiper.slideTo(swiper.slides.length - 1, 0, false, true);
} else {
translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
}
with swiper.params.slidesPerView > 1) && swiper.isEnd true we execute swiper.slideTo(swiper.slides.length - 1, 0, false, true);. As you can see in the reproduction scenario slides.length is always 3 (virtual slides). So we always jump to slide 3 not the end.
There is one more bug sometimes the jump is to slide 2 and one slide gets missing (19 remaining).
Expected Behavior
No jumping glitches when using a reactive slidesPerView property (and virtual slides)
Actual Behavior
When the user adds one slidePerView while viewing any slide > 50% progress (slide 11 if you have 20), it glitches back to slide 3.
Swiper version
8.3.1
Platform/Target and Browser Versions
Chrome
Validations
- [X] Follow our Code of Conduct
- [X] Read the docs.
- [X] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
- [X] Make sure this is a Swiper issue and not a framework-specific issue
Would you like to open a PR for this bug?
- [ ] I'm willing to open a PR
Some debug logs showing the values:
1 Slide perView updateProgress.js:27 progress: 0.5576923076923077 translate: -17139 maxTranslate: -30732 translateDiff: -30732 updateProgress.js:27 progress: 0.5576923076923077 translate: -17139 maxTranslate: -30732 translateDiff: -30732 updateProgress.js:27 progress: 0.5769230769230769 translate: -17730 maxTranslate: -30732 translateDiff: -30732 updateProgress.js:27 progress: 0.5769230769230769 translate: -17730 maxTranslate: -30732 translateDiff: -30732 updateProgress.js:27 progress: 0.5961538461538461 translate: -18321 maxTranslate: -30732 translateDiff: -30732 updateProgress.js:27 progress: 0.5961538461538461 translate: -18321 maxTranslate: -30732 translateDiff: -30732
2 Slides perView updateProgress.js:27 progress: 0.4117647058823529 translate: -6205.5 maxTranslate: -15070.5 translateDiff: -15070.5 updateProgress.js:27 progress: 0.4117647058823529 translate: -6205.5 maxTranslate: -15070.5 translateDiff: -15070.5 updateProgress.js:27 progress: 0.43137254901960786 translate: -6501 maxTranslate: -15070.5 translateDiff: -15070.5 updateProgress.js:27 progress: 0.43137254901960786 translate: -6501 maxTranslate: -15070.5 translateDiff: -15070.5 updateProgress.js:27 progress: 0.45098039215686275 translate: -6796.5 maxTranslate: -15070.5 translateDiff: -15070.5 updateProgress.js:27 progress: 0.45098039215686275 translate: -6796.5 maxTranslate: -15070.5 translateDiff: -15070.5
3 Slides perView updateProgress.js:27 progress: 0.6 translate: -5910 maxTranslate: -9850 translateDiff: -9850 updateProgress.js:27 progress: 0.6 translate: -5910 maxTranslate: -9850 translateDiff: -9850 updateProgress.js:27 progress: 0.62 translate: -6107 maxTranslate: -9850 translateDiff: -9850 updateProgress.js:27 progress: 0.62 translate: -6107 maxTranslate: -9850 translateDiff: -9850 updateProgress.js:27 progress: 0.64 translate: -6304 maxTranslate: -9850 translateDiff: -9850 updateProgress.js:27 progress: 0.64 translate: -6304 maxTranslate: -9850 translateDiff: -9850
Switch 1 to 2 Slides: updateProgress.js:27 progress: 0.6730769230769231 translate: -20685 maxTranslate: -30732 translateDiff: -30732 updateProgress.js:27 progress: 1.3725490196078431 translate: -20685 maxTranslate: -15070.5 translateDiff: -15070.5 translate has old value for 1 Slide, but maxTranslate is already updated for 2 Slides => Jump to Slide 3 updateProgress.js:27 progress: 0.6862745098039216 translate: -10342.5 maxTranslate: -15070.5 translateDiff: -15070.5 translate fixed to -10342.5 updateProgress.js:27 progress: 0.6862745098039216 translate: -10342.5 maxTranslate: -15070.5 translateDiff: -15070.5
Facing this problem as well. How's that PR coming along?
any news?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Issue still here, any workaround?
Issue is closed because of outdated/irrelevant/not actual/needed more information/inactivity.
If this issue is still actual and reproducible for latest version of Swiper, please create new issue and fill the issue template correctly:
- Clearly describe the issue including steps to reproduce when it is a bug.
- Make sure you fill in the earliest version that you know has the issue.
- Provide live link or JSFiddle/Codepen or website with issue