106 lines
3.7 KiB
JavaScript
106 lines
3.7 KiB
JavaScript
import { elementChildren } from '../../shared/utils.js';
|
|
export default function Parallax({
|
|
swiper,
|
|
extendParams,
|
|
on
|
|
}) {
|
|
extendParams({
|
|
parallax: {
|
|
enabled: false
|
|
}
|
|
});
|
|
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 = `${x * progress * rtlFactor}px`;
|
|
}
|
|
if (y.indexOf('%') >= 0) {
|
|
y = `${parseInt(y, 10) * progress}%`;
|
|
} else {
|
|
y = `${y * progress}px`;
|
|
}
|
|
if (typeof opacity !== 'undefined' && opacity !== null) {
|
|
const currentOpacity = opacity - (opacity - 1) * (1 - Math.abs(progress));
|
|
el.style.opacity = currentOpacity;
|
|
}
|
|
let transform = `translate3d(${x}, ${y}, 0px)`;
|
|
if (typeof scale !== 'undefined' && scale !== null) {
|
|
const currentScale = scale - (scale - 1) * (1 - Math.abs(progress));
|
|
transform += ` scale(${currentScale})`;
|
|
}
|
|
if (rotate && typeof rotate !== 'undefined' && rotate !== null) {
|
|
const currentRotate = rotate * progress * -1;
|
|
transform += ` rotate(${currentRotate}deg)`;
|
|
}
|
|
el.style.transform = transform;
|
|
};
|
|
const setTranslate = () => {
|
|
const {
|
|
el,
|
|
slides,
|
|
progress,
|
|
snapGrid
|
|
} = swiper;
|
|
elementChildren(el, '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').forEach(subEl => {
|
|
setTransform(subEl, progress);
|
|
});
|
|
slides.forEach((slideEl, slideIndex) => {
|
|
let slideProgress = slideEl.progress;
|
|
if (swiper.params.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('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale], [data-swiper-parallax-rotate]').forEach(subEl => {
|
|
setTransform(subEl, slideProgress);
|
|
});
|
|
});
|
|
};
|
|
const setTransition = (duration = swiper.params.speed) => {
|
|
const {
|
|
el
|
|
} = swiper;
|
|
el.querySelectorAll('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').forEach(parallaxEl => {
|
|
let parallaxDuration = parseInt(parallaxEl.getAttribute('data-swiper-parallax-duration'), 10) || duration;
|
|
if (duration === 0) parallaxDuration = 0;
|
|
parallaxEl.style.transitionDuration = `${parallaxDuration}ms`;
|
|
});
|
|
};
|
|
on('beforeInit', () => {
|
|
if (!swiper.params.parallax.enabled) return;
|
|
swiper.params.watchSlidesProgress = true;
|
|
swiper.originalParams.watchSlidesProgress = true;
|
|
});
|
|
on('init', () => {
|
|
if (!swiper.params.parallax.enabled) return;
|
|
setTranslate();
|
|
});
|
|
on('setTranslate', () => {
|
|
if (!swiper.params.parallax.enabled) return;
|
|
setTranslate();
|
|
});
|
|
on('setTransition', (_swiper, duration) => {
|
|
if (!swiper.params.parallax.enabled) return;
|
|
setTransition(duration);
|
|
});
|
|
} |