swiper
Version:
Most modern mobile touch slider and framework with hardware accelerated transitions
123 lines (120 loc) • 5.41 kB
JavaScript
import { c as createShadow } from '../shared/create-shadow.mjs';
import { e as effectInit } from '../shared/effect-init.mjs';
import { e as effectTarget } from '../shared/effect-target.mjs';
import { e as effectVirtualTransitionEnd } from '../shared/effect-virtual-transition-end.mjs';
import { p as getSlideTransformEl } from '../shared/utils.mjs';
const EffectCards = ({ swiper, extendParams, on }) => {
extendParams({
cardsEffect: {
slideShadows: true,
rotate: true,
perSlideRotate: 2,
perSlideOffset: 8,
},
});
function getParams() {
return swiper.params.cardsEffect;
}
const setTranslate = () => {
const { slides, activeIndex, rtlTranslate: rtl } = swiper;
const params = getParams();
const { startTranslate, isTouched } = swiper.touchEventsData;
const currentTranslate = rtl ? -swiper.translate : swiper.translate;
for (let i = 0; i < slides.length; i += 1) {
const slideEl = slides[i];
const slideProgress = slideEl.progress ?? 0;
const progress = Math.min(Math.max(slideProgress, -4), 4);
let offset = slideEl.swiperSlideOffset ?? 0;
if (swiper.params.centeredSlides && !swiper.params.cssMode) {
swiper.wrapperEl.style.transform = `translateX(${swiper.minTranslate()}px)`;
}
if (swiper.params.centeredSlides && swiper.params.cssMode) {
offset -= slides[0].swiperSlideOffset ?? 0;
}
let tX = swiper.params.cssMode ? -offset - swiper.translate : -offset;
let tY = 0;
const tZ = -100 * Math.abs(progress);
let scale = 1;
let rotate = -params.perSlideRotate * progress;
let tXAdd = params.perSlideOffset - Math.abs(progress) * 0.75;
const slideIndex = swiper.virtual && swiper.params.virtual?.enabled ? swiper.virtual.from + i : i;
const isSwipeToNext = (slideIndex === activeIndex || slideIndex === activeIndex - 1) &&
progress > 0 &&
progress < 1 &&
(isTouched || swiper.params.cssMode) &&
(currentTranslate ?? 0) < (startTranslate ?? 0);
const isSwipeToPrev = (slideIndex === activeIndex || slideIndex === activeIndex + 1) &&
progress < 0 &&
progress > -1 &&
(isTouched || swiper.params.cssMode) &&
(currentTranslate ?? 0) > (startTranslate ?? 0);
if (isSwipeToNext || isSwipeToPrev) {
const subProgress = (1 - Math.abs((Math.abs(progress) - 0.5) / 0.5)) ** 0.5;
rotate += -28 * progress * subProgress;
scale += -0.5 * subProgress;
tXAdd += 96 * subProgress;
tY = `${(params.rotate || swiper.isHorizontal() ? -25 : 0) * subProgress * Math.abs(progress)}%`;
}
if (progress < 0) {
// next
tX = `calc(${tX}px ${rtl ? '-' : '+'} (${tXAdd * Math.abs(progress)}%))`;
}
else if (progress > 0) {
// prev
tX = `calc(${tX}px ${rtl ? '-' : '+'} (-${tXAdd * Math.abs(progress)}%))`;
}
else {
tX = `${tX}px`;
}
if (!swiper.isHorizontal()) {
const prevY = tY;
tY = tX;
tX = prevY;
}
const scaleString = progress < 0 ? `${1 + (1 - scale) * progress}` : `${1 - (1 - scale) * progress}`;
const transform = `
translate3d(${tX}, ${tY}, ${tZ}px)
rotateZ(${params.rotate ? (rtl ? -rotate : rotate) : 0}deg)
scale(${scaleString})
`;
if (params.slideShadows) {
// Set shadows
let shadowEl = slideEl.querySelector('.swiper-slide-shadow');
if (!shadowEl) {
shadowEl = createShadow('cards', slideEl);
}
if (shadowEl)
shadowEl.style.opacity = String(Math.min(Math.max((Math.abs(progress) - 0.5) / 0.5, 0), 1));
}
slideEl.style.zIndex = String(-Math.abs(Math.round(slideProgress)) + slides.length);
const targetEl = effectTarget(params, slideEl);
targetEl.style.transform = transform;
}
};
const setTransition = (duration) => {
const transformElements = swiper.slides.map((slideEl) => getSlideTransformEl(slideEl));
transformElements.forEach((el) => {
el.style.transitionDuration = `${duration}ms`;
el.querySelectorAll('.swiper-slide-shadow').forEach((shadowEl) => {
shadowEl.style.transitionDuration = `${duration}ms`;
});
});
effectVirtualTransitionEnd({ swiper, duration, transformElements });
};
effectInit({
effect: 'cards',
swiper,
on,
setTranslate,
setTransition,
perspective: () => true,
overwriteParams: () => ({
_loopSwapReset: false,
watchSlidesProgress: true,
loopAdditionalSlides: getParams().rotate ? 3 : 2,
centeredSlides: true,
virtualTranslate: !swiper.params.cssMode,
}),
});
};
export { EffectCards as default };