Skip to content

Commit

Permalink
feat(core): custom animation for CSS Mode where smooth scrolling is n…
Browse files Browse the repository at this point in the history
…ot supported
  • Loading branch information
nolimits4web committed Aug 6, 2021
1 parent a533958 commit a61da6a
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 10 deletions.
34 changes: 34 additions & 0 deletions src/core/slide/animateCSSModeScroll.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { getWindow } from 'ssr-window';

export default function animateCSSModeScroll({ swiper, targetPosition, side }) {
const window = getWindow();
const currentPosition = -swiper.translate;
const frameTime = 1000 / 60;
const frames = swiper.params.speed / frameTime;
const perFrame = (targetPosition - currentPosition) / frames;

let progressPosition = currentPosition;
swiper.wrapperEl.style.scrollSnapType = 'none';
window.cancelAnimationFrame(swiper.cssModeFrameID);

const dir = targetPosition > currentPosition ? 'next' : 'prev';

const isOutOfBound = (progress, target) => {
return (dir === 'next' && progress >= target) || (dir === 'prev' && progress <= target);
};

const animate = () => {
progressPosition += perFrame;
if (isOutOfBound(progressPosition, targetPosition)) progressPosition = targetPosition;
swiper.wrapperEl.scrollTo({
[side]: progressPosition,
});
if (isOutOfBound(progressPosition, targetPosition)) {
swiper.wrapperEl.style.scrollSnapType = '';
window.cancelAnimationFrame(swiper.cssModeFrameID);
return;
}
swiper.cssModeFrameID = window.requestAnimationFrame(animate);
};
animate();
}
12 changes: 10 additions & 2 deletions src/core/slide/slidePrev.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export default function slidePrev(speed = this.params.speed, runCallbacks = true
swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;
}
const translate = rtlTranslate ? swiper.translate : -swiper.translate;

function normalize(val) {
if (val < 0) return -Math.floor(Math.abs(val));
return Math.floor(val);
Expand All @@ -20,9 +21,16 @@ export default function slidePrev(speed = this.params.speed, runCallbacks = true

let prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];
if (typeof prevSnap === 'undefined' && params.cssMode) {
snapGrid.forEach((snap) => {
if (!prevSnap && normalizedTranslate >= snap) prevSnap = snap;
let prevSnapIndex;
snapGrid.forEach((snap, snapIndex) => {
if (normalizedTranslate >= snap) {
// prevSnap = snap;
prevSnapIndex = snapIndex;
}
});
if (typeof prevSnapIndex !== 'undefined') {
prevSnap = snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex];
}
}
let prevIndex;
if (typeof prevSnap !== 'undefined') {
Expand Down
17 changes: 9 additions & 8 deletions src/core/slide/slideTo.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import animateCSSModeScroll from './animateCSSModeScroll.js';

export default function slideTo(
index = 0,
speed = this.params.speed,
Expand Down Expand Up @@ -143,15 +145,14 @@ export default function slideTo(
if (speed === 0) {
wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
} else {
// eslint-disable-next-line
if (wrapperEl.scrollTo) {
wrapperEl.scrollTo({
[isH ? 'left' : 'top']: t,
behavior: 'smooth',
});
} else {
wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
if (swiper.support.smoothScroll) {
animateCSSModeScroll({ swiper, targetPosition: t, side: isH ? 'left' : 'top' });
return true;
}
wrapperEl.scrollTo({
[isH ? 'left' : 'top']: t,
behavior: 'smooth',
});
}
return true;
}
Expand Down
2 changes: 2 additions & 0 deletions src/shared/get-support.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ function calcSupport() {
const document = getDocument();

return {
smoothScroll: 'scrollBehavior' in document.documentElement.style,

touch: !!(
'ontouchstart' in window ||
(window.DocumentTouch && document instanceof window.DocumentTouch)
Expand Down

0 comments on commit a61da6a

Please sign in to comment.