swiper
Version:
Most modern mobile touch slider and framework with hardware accelerated transitions
124 lines (121 loc) • 4.69 kB
JavaScript
import { e as elementChildren } from '../shared/utils.mjs';
const Parallax = ({ swiper, extendParams, on }) => {
extendParams({
parallax: {
enabled: false,
},
});
function getParams() {
return swiper.params.parallax;
}
const elementsSelector = '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]';
const setTransform = (el, progress) => {
const { rtl } = swiper;
const rtlFactor = rtl ? -1 : 1;
const p = el.getAttribute('data-swiper-parallax') || '0';
let x = el.getAttribute('data-swiper-parallax-x');
let y = el.getAttribute('data-swiper-parallax-y');
const scale = el.getAttribute('data-swiper-parallax-scale');
const opacity = el.getAttribute('data-swiper-parallax-opacity');
const rotate = el.getAttribute('data-swiper-parallax-rotate');
if (x || y) {
x = x || '0';
y = y || '0';
}
else if (swiper.isHorizontal()) {
x = p;
y = '0';
}
else {
y = p;
x = '0';
}
if (x.indexOf('%') >= 0) {
x = `${parseInt(x, 10) * progress * rtlFactor}%`;
}
else {
x = `${Number(x) * progress * rtlFactor}px`;
}
if (y.indexOf('%') >= 0) {
y = `${parseInt(y, 10) * progress}%`;
}
else {
y = `${Number(y) * progress}px`;
}
if (typeof opacity !== 'undefined' && opacity !== null) {
const opacityNum = Number(opacity);
const currentOpacity = opacityNum - (opacityNum - 1) * (1 - Math.abs(progress));
el.style.opacity = String(currentOpacity);
}
let transform = `translate3d(${x}, ${y}, 0px)`;
if (typeof scale !== 'undefined' && scale !== null) {
const scaleNum = Number(scale);
const currentScale = scaleNum - (scaleNum - 1) * (1 - Math.abs(progress));
transform += ` scale(${currentScale})`;
}
if (rotate && typeof rotate !== 'undefined' && rotate !== null) {
const currentRotate = Number(rotate) * progress * -1;
transform += ` rotate(${currentRotate}deg)`;
}
el.style.transform = transform;
};
const setTranslate = () => {
const { el, slides, progress, snapGrid } = swiper;
const elements = elementChildren(el, elementsSelector);
if (swiper.isElement) {
elements.push(...elementChildren(swiper.hostEl, elementsSelector));
}
elements.forEach((subEl) => {
setTransform(subEl, progress);
});
slides.forEach((slideEl, slideIndex) => {
let slideProgress = slideEl.progress ?? 0;
const slidesPerGroup = swiper.params.slidesPerGroup ?? 1;
if (slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') {
slideProgress += Math.ceil(slideIndex / 2) - progress * (snapGrid.length - 1);
}
slideProgress = Math.min(Math.max(slideProgress, -1), 1);
slideEl
.querySelectorAll(`${elementsSelector}, [data-swiper-parallax-rotate]`)
.forEach((subEl) => {
setTransform(subEl, slideProgress);
});
});
};
const setTransition = (duration = swiper.params.speed ?? 300) => {
const { el, hostEl } = swiper;
const elements = [...el.querySelectorAll(elementsSelector)];
if (swiper.isElement) {
elements.push(...hostEl.querySelectorAll(elementsSelector));
}
elements.forEach((parallaxEl) => {
const attr = parallaxEl.getAttribute('data-swiper-parallax-duration');
let parallaxDuration = (attr ? parseInt(attr, 10) : 0) || duration;
if (duration === 0)
parallaxDuration = 0;
parallaxEl.style.transitionDuration = `${parallaxDuration}ms`;
});
};
on('beforeInit', () => {
if (!getParams().enabled)
return;
swiper.params.watchSlidesProgress = true;
swiper.originalParams.watchSlidesProgress = true;
});
on('init', () => {
if (!getParams().enabled)
return;
setTranslate();
});
on('setTranslate', () => {
if (!getParams().enabled)
return;
setTranslate();
});
on('setTransition', (_swiper, duration) => {
if (!getParams().enabled)
return;
setTransition(duration);
});
};
export { Parallax as default };