effect-coverflow.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import createShadow from '../../shared/create-shadow.js';
  2. import effectInit from '../../shared/effect-init.js';
  3. import effectTarget from '../../shared/effect-target.js';
  4. export default function EffectCoverflow({
  5. swiper,
  6. extendParams,
  7. on
  8. }) {
  9. extendParams({
  10. coverflowEffect: {
  11. rotate: 50,
  12. stretch: 0,
  13. depth: 100,
  14. scale: 1,
  15. modifier: 1,
  16. slideShadows: true,
  17. transformEl: null
  18. }
  19. });
  20. const setTranslate = () => {
  21. const {
  22. width: swiperWidth,
  23. height: swiperHeight,
  24. slides,
  25. slidesSizesGrid
  26. } = swiper;
  27. const params = swiper.params.coverflowEffect;
  28. const isHorizontal = swiper.isHorizontal();
  29. const transform = swiper.translate;
  30. const center = isHorizontal ? -transform + swiperWidth / 2 : -transform + swiperHeight / 2;
  31. const rotate = isHorizontal ? params.rotate : -params.rotate;
  32. const translate = params.depth; // Each slide offset from center
  33. for (let i = 0, length = slides.length; i < length; i += 1) {
  34. const $slideEl = slides.eq(i);
  35. const slideSize = slidesSizesGrid[i];
  36. const slideOffset = $slideEl[0].swiperSlideOffset;
  37. const offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * params.modifier;
  38. let rotateY = isHorizontal ? rotate * offsetMultiplier : 0;
  39. let rotateX = isHorizontal ? 0 : rotate * offsetMultiplier; // var rotateZ = 0
  40. let translateZ = -translate * Math.abs(offsetMultiplier);
  41. let stretch = params.stretch; // Allow percentage to make a relative stretch for responsive sliders
  42. if (typeof stretch === 'string' && stretch.indexOf('%') !== -1) {
  43. stretch = parseFloat(params.stretch) / 100 * slideSize;
  44. }
  45. let translateY = isHorizontal ? 0 : stretch * offsetMultiplier;
  46. let translateX = isHorizontal ? stretch * offsetMultiplier : 0;
  47. let scale = 1 - (1 - params.scale) * Math.abs(offsetMultiplier); // Fix for ultra small values
  48. if (Math.abs(translateX) < 0.001) translateX = 0;
  49. if (Math.abs(translateY) < 0.001) translateY = 0;
  50. if (Math.abs(translateZ) < 0.001) translateZ = 0;
  51. if (Math.abs(rotateY) < 0.001) rotateY = 0;
  52. if (Math.abs(rotateX) < 0.001) rotateX = 0;
  53. if (Math.abs(scale) < 0.001) scale = 0;
  54. const slideTransform = `translate3d(${translateX}px,${translateY}px,${translateZ}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(${scale})`;
  55. const $targetEl = effectTarget(params, $slideEl);
  56. $targetEl.transform(slideTransform);
  57. $slideEl[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;
  58. if (params.slideShadows) {
  59. // Set shadows
  60. let $shadowBeforeEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');
  61. let $shadowAfterEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');
  62. if ($shadowBeforeEl.length === 0) {
  63. $shadowBeforeEl = createShadow(params, $slideEl, isHorizontal ? 'left' : 'top');
  64. }
  65. if ($shadowAfterEl.length === 0) {
  66. $shadowAfterEl = createShadow(params, $slideEl, isHorizontal ? 'right' : 'bottom');
  67. }
  68. if ($shadowBeforeEl.length) $shadowBeforeEl[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
  69. if ($shadowAfterEl.length) $shadowAfterEl[0].style.opacity = -offsetMultiplier > 0 ? -offsetMultiplier : 0;
  70. }
  71. }
  72. };
  73. const setTransition = duration => {
  74. const {
  75. transformEl
  76. } = swiper.params.coverflowEffect;
  77. const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
  78. $transitionElements.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
  79. };
  80. effectInit({
  81. effect: 'coverflow',
  82. swiper,
  83. on,
  84. setTranslate,
  85. setTransition,
  86. perspective: () => true,
  87. overwriteParams: () => ({
  88. watchSlidesProgress: true
  89. })
  90. });
  91. }