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);
 | 
						|
  });
 | 
						|
} |