189 lines
5.3 KiB
JavaScript
189 lines
5.3 KiB
JavaScript
import {
|
|
animateCSSModeScroll
|
|
} from '../../shared/utils.js';
|
|
export default function slideTo(index = 0, speed = this.params.speed, runCallbacks = true, internal, initial) {
|
|
if (typeof index !== 'number' && typeof index !== 'string') {
|
|
throw new Error(
|
|
`The 'index' argument cannot have type other than 'number' or 'string'. [${typeof index}] given.`);
|
|
}
|
|
|
|
if (typeof index === 'string') {
|
|
/**
|
|
* The `index` argument converted from `string` to `number`.
|
|
* @type {number}
|
|
*/
|
|
const indexAsNumber = parseInt(index, 10);
|
|
/**
|
|
* Determines whether the `index` argument is a valid `number`
|
|
* after being converted from the `string` type.
|
|
* @type {boolean}
|
|
*/
|
|
|
|
const isValidNumber = isFinite(indexAsNumber);
|
|
|
|
if (!isValidNumber) {
|
|
throw new Error(`The passed-in 'index' (string) couldn't be converted to 'number'. [${index}] given.`);
|
|
} // Knowing that the converted `index` is a valid number,
|
|
// we can update the original argument's value.
|
|
|
|
|
|
index = indexAsNumber;
|
|
}
|
|
|
|
const swiper = this;
|
|
let slideIndex = index;
|
|
let timer;
|
|
if (slideIndex < 0) slideIndex = 0;
|
|
const {
|
|
params,
|
|
snapGrid,
|
|
slidesGrid,
|
|
previousIndex,
|
|
activeIndex,
|
|
rtlTranslate: rtl,
|
|
wrapperEl,
|
|
enabled
|
|
} = swiper;
|
|
|
|
if (swiper.animating && params.preventInteractionOnTransition || !enabled && !internal && !initial) {
|
|
return false;
|
|
}
|
|
|
|
const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);
|
|
let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
|
|
if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
|
|
|
|
if ((activeIndex || params.initialSlide || 0) === (previousIndex || 0) && runCallbacks) {
|
|
swiper.emit('beforeSlideChangeStart');
|
|
}
|
|
const translate = -snapGrid[snapIndex]; // Update progress
|
|
|
|
swiper.updateProgress(translate); // Normalize slideIndex
|
|
|
|
if (params.normalizeSlideIndex) {
|
|
for (let i = 0; i < slidesGrid.length; i += 1) {
|
|
const normalizedTranslate = -Math.floor(translate * 100);
|
|
const normalizedGrid = Math.floor(slidesGrid[i] * 100);
|
|
const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100);
|
|
if (typeof slidesGrid[i + 1] !== 'undefined') {
|
|
if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext - (
|
|
normalizedGridNext - normalizedGrid) / 2) {
|
|
slideIndex = i;
|
|
} else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) {
|
|
slideIndex = i + 1;
|
|
}
|
|
} else if (normalizedTranslate >= normalizedGrid) {
|
|
slideIndex = i;
|
|
}
|
|
|
|
}
|
|
} // Directions locks
|
|
|
|
|
|
if (swiper.initialized && slideIndex !== activeIndex) {
|
|
if (!swiper.allowSlideNext && translate < swiper.translate && translate < swiper.minTranslate()) {
|
|
return false;
|
|
}
|
|
|
|
if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
|
|
if ((activeIndex || 0) !== slideIndex) return false;
|
|
}
|
|
}
|
|
|
|
let direction;
|
|
if (slideIndex > activeIndex) direction = 'next';
|
|
else if (slideIndex < activeIndex) direction = 'prev';
|
|
else direction = 'reset'; // Update Index
|
|
|
|
if (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate) {
|
|
swiper.updateActiveIndex(slideIndex); // Update Height
|
|
|
|
if (params.autoHeight) {
|
|
setTimeout(() => {
|
|
swiper.updateAutoHeight();
|
|
}, 0)
|
|
}
|
|
|
|
swiper.updateSlidesClasses();
|
|
|
|
if (params.effect !== 'slide') {
|
|
swiper.setTranslate(translate);
|
|
}
|
|
|
|
if (direction !== 'reset') {
|
|
swiper.transitionStart(runCallbacks, direction);
|
|
swiper.transitionEnd(runCallbacks, direction);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
if (params.cssMode) {
|
|
const isH = swiper.isHorizontal();
|
|
const t = rtl ? translate : -translate;
|
|
|
|
if (speed === 0) {
|
|
const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
|
|
|
|
if (isVirtual) {
|
|
swiper.wrapperEl.style.scrollSnapType = 'none';
|
|
swiper._immediateVirtual = true;
|
|
}
|
|
|
|
wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
|
|
|
|
if (isVirtual) {
|
|
requestAnimationFrame(() => {
|
|
swiper.wrapperEl.style.scrollSnapType = '';
|
|
swiper._swiperImmediateVirtual = false;
|
|
});
|
|
}
|
|
} else {
|
|
if (!swiper.support.smoothScroll) {
|
|
animateCSSModeScroll({
|
|
swiper,
|
|
targetPosition: t,
|
|
side: isH ? 'left' : 'top'
|
|
});
|
|
return true;
|
|
}
|
|
|
|
wrapperEl.scrollTo({
|
|
[isH ? 'left' : 'top']: t,
|
|
behavior: 'smooth'
|
|
});
|
|
}
|
|
|
|
return true;
|
|
}
|
|
swiper.setTransition(speed);
|
|
swiper.setTranslate(translate);
|
|
swiper.updateActiveIndex(slideIndex);
|
|
swiper.updateSlidesClasses();
|
|
swiper.emit('beforeTransitionStart', speed, internal);
|
|
swiper.transitionStart(runCallbacks, direction);
|
|
|
|
if (speed === 0) {
|
|
swiper.transitionEnd(runCallbacks, direction);
|
|
} else if (!swiper.animating) {
|
|
swiper.animating = true;
|
|
|
|
if (!swiper.onSlideToWrapperTransitionEnd) {
|
|
swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {
|
|
if (!swiper || swiper.destroyed) return;
|
|
clearTimeout(timer)
|
|
swiper.onSlideToWrapperTransitionEnd = null;
|
|
delete swiper.onSlideToWrapperTransitionEnd;
|
|
swiper.transitionEnd(runCallbacks, direction);
|
|
};
|
|
}
|
|
timer = setTimeout(() => {
|
|
if (swiper.onSlideToWrapperTransitionEnd) {
|
|
swiper.onSlideToWrapperTransitionEnd();
|
|
}
|
|
}, speed)
|
|
}
|
|
|
|
return true;
|
|
}
|