UNPKG

6.21 kBJavaScriptView Raw
1import $ from '../../shared/dom.js';
2import effectInit from '../../shared/effect-init.js';
3export default function EffectCube({
4 swiper,
5 extendParams,
6 on
7}) {
8 extendParams({
9 cubeEffect: {
10 slideShadows: true,
11 shadow: true,
12 shadowOffset: 20,
13 shadowScale: 0.94
14 }
15 });
16
17 const createSlideShadows = ($slideEl, progress, isHorizontal) => {
18 let shadowBefore = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');
19 let shadowAfter = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');
20
21 if (shadowBefore.length === 0) {
22 shadowBefore = $(`<div class="swiper-slide-shadow-${isHorizontal ? 'left' : 'top'}"></div>`);
23 $slideEl.append(shadowBefore);
24 }
25
26 if (shadowAfter.length === 0) {
27 shadowAfter = $(`<div class="swiper-slide-shadow-${isHorizontal ? 'right' : 'bottom'}"></div>`);
28 $slideEl.append(shadowAfter);
29 }
30
31 if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);
32 if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);
33 };
34
35 const recreateShadows = () => {
36 // create new ones
37 const isHorizontal = swiper.isHorizontal();
38 swiper.slides.each(slideEl => {
39 const progress = Math.max(Math.min(slideEl.progress, 1), -1);
40 createSlideShadows($(slideEl), progress, isHorizontal);
41 });
42 };
43
44 const setTranslate = () => {
45 const {
46 $el,
47 $wrapperEl,
48 slides,
49 width: swiperWidth,
50 height: swiperHeight,
51 rtlTranslate: rtl,
52 size: swiperSize,
53 browser
54 } = swiper;
55 const params = swiper.params.cubeEffect;
56 const isHorizontal = swiper.isHorizontal();
57 const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
58 let wrapperRotate = 0;
59 let $cubeShadowEl;
60
61 if (params.shadow) {
62 if (isHorizontal) {
63 $cubeShadowEl = $wrapperEl.find('.swiper-cube-shadow');
64
65 if ($cubeShadowEl.length === 0) {
66 $cubeShadowEl = $('<div class="swiper-cube-shadow"></div>');
67 $wrapperEl.append($cubeShadowEl);
68 }
69
70 $cubeShadowEl.css({
71 height: `${swiperWidth}px`
72 });
73 } else {
74 $cubeShadowEl = $el.find('.swiper-cube-shadow');
75
76 if ($cubeShadowEl.length === 0) {
77 $cubeShadowEl = $('<div class="swiper-cube-shadow"></div>');
78 $el.append($cubeShadowEl);
79 }
80 }
81 }
82
83 for (let i = 0; i < slides.length; i += 1) {
84 const $slideEl = slides.eq(i);
85 let slideIndex = i;
86
87 if (isVirtual) {
88 slideIndex = parseInt($slideEl.attr('data-swiper-slide-index'), 10);
89 }
90
91 let slideAngle = slideIndex * 90;
92 let round = Math.floor(slideAngle / 360);
93
94 if (rtl) {
95 slideAngle = -slideAngle;
96 round = Math.floor(-slideAngle / 360);
97 }
98
99 const progress = Math.max(Math.min($slideEl[0].progress, 1), -1);
100 let tx = 0;
101 let ty = 0;
102 let tz = 0;
103
104 if (slideIndex % 4 === 0) {
105 tx = -round * 4 * swiperSize;
106 tz = 0;
107 } else if ((slideIndex - 1) % 4 === 0) {
108 tx = 0;
109 tz = -round * 4 * swiperSize;
110 } else if ((slideIndex - 2) % 4 === 0) {
111 tx = swiperSize + round * 4 * swiperSize;
112 tz = swiperSize;
113 } else if ((slideIndex - 3) % 4 === 0) {
114 tx = -swiperSize;
115 tz = 3 * swiperSize + swiperSize * 4 * round;
116 }
117
118 if (rtl) {
119 tx = -tx;
120 }
121
122 if (!isHorizontal) {
123 ty = tx;
124 tx = 0;
125 }
126
127 const transform = `rotateX(${isHorizontal ? 0 : -slideAngle}deg) rotateY(${isHorizontal ? slideAngle : 0}deg) translate3d(${tx}px, ${ty}px, ${tz}px)`;
128
129 if (progress <= 1 && progress > -1) {
130 wrapperRotate = slideIndex * 90 + progress * 90;
131 if (rtl) wrapperRotate = -slideIndex * 90 - progress * 90;
132 }
133
134 $slideEl.transform(transform);
135
136 if (params.slideShadows) {
137 createSlideShadows($slideEl, progress, isHorizontal);
138 }
139 }
140
141 $wrapperEl.css({
142 '-webkit-transform-origin': `50% 50% -${swiperSize / 2}px`,
143 'transform-origin': `50% 50% -${swiperSize / 2}px`
144 });
145
146 if (params.shadow) {
147 if (isHorizontal) {
148 $cubeShadowEl.transform(`translate3d(0px, ${swiperWidth / 2 + params.shadowOffset}px, ${-swiperWidth / 2}px) rotateX(90deg) rotateZ(0deg) scale(${params.shadowScale})`);
149 } else {
150 const shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
151 const multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);
152 const scale1 = params.shadowScale;
153 const scale2 = params.shadowScale / multiplier;
154 const offset = params.shadowOffset;
155 $cubeShadowEl.transform(`scale3d(${scale1}, 1, ${scale2}) translate3d(0px, ${swiperHeight / 2 + offset}px, ${-swiperHeight / 2 / scale2}px) rotateX(-90deg)`);
156 }
157 }
158
159 const zFactor = browser.isSafari || browser.isWebView ? -swiperSize / 2 : 0;
160 $wrapperEl.transform(`translate3d(0px,0,${zFactor}px) rotateX(${swiper.isHorizontal() ? 0 : wrapperRotate}deg) rotateY(${swiper.isHorizontal() ? -wrapperRotate : 0}deg)`);
161 $wrapperEl[0].style.setProperty('--swiper-cube-translate-z', `${zFactor}px`);
162 };
163
164 const setTransition = duration => {
165 const {
166 $el,
167 slides
168 } = swiper;
169 slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
170
171 if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) {
172 $el.find('.swiper-cube-shadow').transition(duration);
173 }
174 };
175
176 effectInit({
177 effect: 'cube',
178 swiper,
179 on,
180 setTranslate,
181 setTransition,
182 recreateShadows,
183 getEffectParams: () => swiper.params.cubeEffect,
184 perspective: () => true,
185 overwriteParams: () => ({
186 slidesPerView: 1,
187 slidesPerGroup: 1,
188 watchSlidesProgress: true,
189 resistanceRatio: 0,
190 spaceBetween: 0,
191 centeredSlides: false,
192 virtualTranslate: true
193 })
194 });
195}
\No newline at end of file