parallax.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import { elementChildren } from '../../shared/utils.js';
  2. export default function Parallax({
  3. swiper,
  4. extendParams,
  5. on
  6. }) {
  7. extendParams({
  8. parallax: {
  9. enabled: false
  10. }
  11. });
  12. const setTransform = (el, progress) => {
  13. const {
  14. rtl
  15. } = swiper;
  16. const rtlFactor = rtl ? -1 : 1;
  17. const p = el.getAttribute('data-swiper-parallax') || '0';
  18. let x = el.getAttribute('data-swiper-parallax-x');
  19. let y = el.getAttribute('data-swiper-parallax-y');
  20. const scale = el.getAttribute('data-swiper-parallax-scale');
  21. const opacity = el.getAttribute('data-swiper-parallax-opacity');
  22. const rotate = el.getAttribute('data-swiper-parallax-rotate');
  23. if (x || y) {
  24. x = x || '0';
  25. y = y || '0';
  26. } else if (swiper.isHorizontal()) {
  27. x = p;
  28. y = '0';
  29. } else {
  30. y = p;
  31. x = '0';
  32. }
  33. if (x.indexOf('%') >= 0) {
  34. x = `${parseInt(x, 10) * progress * rtlFactor}%`;
  35. } else {
  36. x = `${x * progress * rtlFactor}px`;
  37. }
  38. if (y.indexOf('%') >= 0) {
  39. y = `${parseInt(y, 10) * progress}%`;
  40. } else {
  41. y = `${y * progress}px`;
  42. }
  43. if (typeof opacity !== 'undefined' && opacity !== null) {
  44. const currentOpacity = opacity - (opacity - 1) * (1 - Math.abs(progress));
  45. el.style.opacity = currentOpacity;
  46. }
  47. let transform = `translate3d(${x}, ${y}, 0px)`;
  48. if (typeof scale !== 'undefined' && scale !== null) {
  49. const currentScale = scale - (scale - 1) * (1 - Math.abs(progress));
  50. transform += ` scale(${currentScale})`;
  51. }
  52. if (rotate && typeof rotate !== 'undefined' && rotate !== null) {
  53. const currentRotate = rotate * progress * -1;
  54. transform += ` rotate(${currentRotate}deg)`;
  55. }
  56. el.style.transform = transform;
  57. };
  58. const setTranslate = () => {
  59. const {
  60. el,
  61. slides,
  62. progress,
  63. snapGrid
  64. } = swiper;
  65. elementChildren(el, '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').forEach(subEl => {
  66. setTransform(subEl, progress);
  67. });
  68. slides.forEach((slideEl, slideIndex) => {
  69. let slideProgress = slideEl.progress;
  70. if (swiper.params.slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') {
  71. slideProgress += Math.ceil(slideIndex / 2) - progress * (snapGrid.length - 1);
  72. }
  73. slideProgress = Math.min(Math.max(slideProgress, -1), 1);
  74. 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 => {
  75. setTransform(subEl, slideProgress);
  76. });
  77. });
  78. };
  79. const setTransition = (duration = swiper.params.speed) => {
  80. const {
  81. el
  82. } = swiper;
  83. el.querySelectorAll('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').forEach(parallaxEl => {
  84. let parallaxDuration = parseInt(parallaxEl.getAttribute('data-swiper-parallax-duration'), 10) || duration;
  85. if (duration === 0) parallaxDuration = 0;
  86. parallaxEl.style.transitionDuration = `${parallaxDuration}ms`;
  87. });
  88. };
  89. on('beforeInit', () => {
  90. if (!swiper.params.parallax.enabled) return;
  91. swiper.params.watchSlidesProgress = true;
  92. swiper.originalParams.watchSlidesProgress = true;
  93. });
  94. on('init', () => {
  95. if (!swiper.params.parallax.enabled) return;
  96. setTranslate();
  97. });
  98. on('setTranslate', () => {
  99. if (!swiper.params.parallax.enabled) return;
  100. setTranslate();
  101. });
  102. on('setTransition', (_swiper, duration) => {
  103. if (!swiper.params.parallax.enabled) return;
  104. setTransition(duration);
  105. });
  106. }