effect-flip.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. import effectVirtualTransitionEnd from '../../shared/effect-virtual-transition-end.js';
  5. import { getSlideTransformEl } from '../../shared/utils.js';
  6. export default function EffectFlip({
  7. swiper,
  8. extendParams,
  9. on
  10. }) {
  11. extendParams({
  12. flipEffect: {
  13. slideShadows: true,
  14. limitRotation: true
  15. }
  16. });
  17. const createSlideShadows = (slideEl, progress, params) => {
  18. let shadowBefore = swiper.isHorizontal() ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top');
  19. let shadowAfter = swiper.isHorizontal() ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom');
  20. if (!shadowBefore) {
  21. shadowBefore = createShadow(params, slideEl, swiper.isHorizontal() ? 'left' : 'top');
  22. }
  23. if (!shadowAfter) {
  24. shadowAfter = createShadow(params, slideEl, swiper.isHorizontal() ? 'right' : 'bottom');
  25. }
  26. if (shadowBefore) shadowBefore.style.opacity = Math.max(-progress, 0);
  27. if (shadowAfter) shadowAfter.style.opacity = Math.max(progress, 0);
  28. };
  29. const recreateShadows = () => {
  30. // Set shadows
  31. const params = swiper.params.flipEffect;
  32. swiper.slides.forEach(slideEl => {
  33. let progress = slideEl.progress;
  34. if (swiper.params.flipEffect.limitRotation) {
  35. progress = Math.max(Math.min(slideEl.progress, 1), -1);
  36. }
  37. createSlideShadows(slideEl, progress, params);
  38. });
  39. };
  40. const setTranslate = () => {
  41. const {
  42. slides,
  43. rtlTranslate: rtl
  44. } = swiper;
  45. const params = swiper.params.flipEffect;
  46. for (let i = 0; i < slides.length; i += 1) {
  47. const slideEl = slides[i];
  48. let progress = slideEl.progress;
  49. if (swiper.params.flipEffect.limitRotation) {
  50. progress = Math.max(Math.min(slideEl.progress, 1), -1);
  51. }
  52. const offset = slideEl.swiperSlideOffset;
  53. const rotate = -180 * progress;
  54. let rotateY = rotate;
  55. let rotateX = 0;
  56. let tx = swiper.params.cssMode ? -offset - swiper.translate : -offset;
  57. let ty = 0;
  58. if (!swiper.isHorizontal()) {
  59. ty = tx;
  60. tx = 0;
  61. rotateX = -rotateY;
  62. rotateY = 0;
  63. } else if (rtl) {
  64. rotateY = -rotateY;
  65. }
  66. slideEl.style.zIndex = -Math.abs(Math.round(progress)) + slides.length;
  67. if (params.slideShadows) {
  68. createSlideShadows(slideEl, progress, params);
  69. }
  70. const transform = `translate3d(${tx}px, ${ty}px, 0px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
  71. const targetEl = effectTarget(params, slideEl);
  72. targetEl.style.transform = transform;
  73. }
  74. };
  75. const setTransition = duration => {
  76. const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
  77. transformElements.forEach(el => {
  78. el.style.transitionDuration = `${duration}ms`;
  79. el.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => {
  80. shadowEl.style.transitionDuration = `${duration}ms`;
  81. });
  82. });
  83. effectVirtualTransitionEnd({
  84. swiper,
  85. duration,
  86. transformElements
  87. });
  88. };
  89. effectInit({
  90. effect: 'flip',
  91. swiper,
  92. on,
  93. setTranslate,
  94. setTransition,
  95. recreateShadows,
  96. getEffectParams: () => swiper.params.flipEffect,
  97. perspective: () => true,
  98. overwriteParams: () => ({
  99. slidesPerView: 1,
  100. slidesPerGroup: 1,
  101. watchSlidesProgress: true,
  102. spaceBetween: 0,
  103. virtualTranslate: !swiper.params.cssMode
  104. })
  105. });
  106. }