parallax.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import $ from '../../shared/dom.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 $el = $(el);
  17. const rtlFactor = rtl ? -1 : 1;
  18. const p = $el.attr('data-swiper-parallax') || '0';
  19. let x = $el.attr('data-swiper-parallax-x');
  20. let y = $el.attr('data-swiper-parallax-y');
  21. const scale = $el.attr('data-swiper-parallax-scale');
  22. const opacity = $el.attr('data-swiper-parallax-opacity');
  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[0].style.opacity = currentOpacity;
  46. }
  47. if (typeof scale === 'undefined' || scale === null) {
  48. $el.transform(`translate3d(${x}, ${y}, 0px)`);
  49. } else {
  50. const currentScale = scale - (scale - 1) * (1 - Math.abs(progress));
  51. $el.transform(`translate3d(${x}, ${y}, 0px) scale(${currentScale})`);
  52. }
  53. };
  54. const setTranslate = () => {
  55. const {
  56. $el,
  57. slides,
  58. progress,
  59. snapGrid
  60. } = swiper;
  61. $el.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').each(el => {
  62. setTransform(el, progress);
  63. });
  64. slides.each((slideEl, slideIndex) => {
  65. let slideProgress = slideEl.progress;
  66. if (swiper.params.slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') {
  67. slideProgress += Math.ceil(slideIndex / 2) - progress * (snapGrid.length - 1);
  68. }
  69. slideProgress = Math.min(Math.max(slideProgress, -1), 1);
  70. $(slideEl).find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').each(el => {
  71. setTransform(el, slideProgress);
  72. });
  73. });
  74. };
  75. const setTransition = (duration = swiper.params.speed) => {
  76. const {
  77. $el
  78. } = swiper;
  79. $el.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').each(parallaxEl => {
  80. const $parallaxEl = $(parallaxEl);
  81. let parallaxDuration = parseInt($parallaxEl.attr('data-swiper-parallax-duration'), 10) || duration;
  82. if (duration === 0) parallaxDuration = 0;
  83. $parallaxEl.transition(parallaxDuration);
  84. });
  85. };
  86. on('beforeInit', () => {
  87. if (!swiper.params.parallax.enabled) return;
  88. swiper.params.watchSlidesProgress = true;
  89. swiper.originalParams.watchSlidesProgress = true;
  90. });
  91. on('init', () => {
  92. if (!swiper.params.parallax.enabled) return;
  93. setTranslate();
  94. });
  95. on('setTranslate', () => {
  96. if (!swiper.params.parallax.enabled) return;
  97. setTranslate();
  98. });
  99. on('setTransition', (_swiper, duration) => {
  100. if (!swiper.params.parallax.enabled) return;
  101. setTransition(duration);
  102. });
  103. }