1 | import $ from '../../shared/dom.js';
|
2 | import effectInit from '../../shared/effect-init.js';
|
3 | export 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 |
|
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 |