UNPKG

4.81 kBJavaScriptView Raw
1import createShadow from '../../shared/create-shadow.js';
2import effectInit from '../../shared/effect-init.js';
3import effectTarget from '../../shared/effect-target.js';
4import effectVirtualTransitionEnd from '../../shared/effect-virtual-transition-end.js';
5export default function EffectCreative(_ref) {
6 let {
7 swiper,
8 extendParams,
9 on
10 } = _ref;
11 extendParams({
12 creativeEffect: {
13 transformEl: null,
14 limitProgress: 1,
15 shadowPerProgress: false,
16 progressMultiplier: 1,
17 perspective: true,
18 prev: {
19 translate: [0, 0, 0],
20 rotate: [0, 0, 0],
21 opacity: 1,
22 scale: 1
23 },
24 next: {
25 translate: [0, 0, 0],
26 rotate: [0, 0, 0],
27 opacity: 1,
28 scale: 1
29 }
30 }
31 });
32
33 const getTranslateValue = value => {
34 if (typeof value === 'string') return value;
35 return `${value}px`;
36 };
37
38 const setTranslate = () => {
39 const {
40 slides,
41 $wrapperEl,
42 slidesSizesGrid
43 } = swiper;
44 const params = swiper.params.creativeEffect;
45 const {
46 progressMultiplier: multiplier
47 } = params;
48 const isCenteredSlides = swiper.params.centeredSlides;
49
50 if (isCenteredSlides) {
51 const margin = slidesSizesGrid[0] / 2 - swiper.params.slidesOffsetBefore || 0;
52 $wrapperEl.transform(`translateX(calc(50% - ${margin}px))`);
53 }
54
55 for (let i = 0; i < slides.length; i += 1) {
56 const $slideEl = slides.eq(i);
57 const slideProgress = $slideEl[0].progress;
58 const progress = Math.min(Math.max($slideEl[0].progress, -params.limitProgress), params.limitProgress);
59 let originalProgress = progress;
60
61 if (!isCenteredSlides) {
62 originalProgress = Math.min(Math.max($slideEl[0].originalProgress, -params.limitProgress), params.limitProgress);
63 }
64
65 const offset = $slideEl[0].swiperSlideOffset;
66 const t = [swiper.params.cssMode ? -offset - swiper.translate : -offset, 0, 0];
67 const r = [0, 0, 0];
68 let custom = false;
69
70 if (!swiper.isHorizontal()) {
71 t[1] = t[0];
72 t[0] = 0;
73 }
74
75 let data = {
76 translate: [0, 0, 0],
77 rotate: [0, 0, 0],
78 scale: 1,
79 opacity: 1
80 };
81
82 if (progress < 0) {
83 data = params.next;
84 custom = true;
85 } else if (progress > 0) {
86 data = params.prev;
87 custom = true;
88 } // set translate
89
90
91 t.forEach((value, index) => {
92 t[index] = `calc(${value}px + (${getTranslateValue(data.translate[index])} * ${Math.abs(progress * multiplier)}))`;
93 }); // set rotates
94
95 r.forEach((value, index) => {
96 r[index] = data.rotate[index] * Math.abs(progress * multiplier);
97 });
98 $slideEl[0].style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;
99 const translateString = t.join(', ');
100 const rotateString = `rotateX(${r[0]}deg) rotateY(${r[1]}deg) rotateZ(${r[2]}deg)`;
101 const scaleString = originalProgress < 0 ? `scale(${1 + (1 - data.scale) * originalProgress * multiplier})` : `scale(${1 - (1 - data.scale) * originalProgress * multiplier})`;
102 const opacityString = originalProgress < 0 ? 1 + (1 - data.opacity) * originalProgress * multiplier : 1 - (1 - data.opacity) * originalProgress * multiplier;
103 const transform = `translate3d(${translateString}) ${rotateString} ${scaleString}`; // Set shadows
104
105 if (custom && data.shadow || !custom) {
106 let $shadowEl = $slideEl.children('.swiper-slide-shadow');
107
108 if ($shadowEl.length === 0 && data.shadow) {
109 $shadowEl = createShadow(params, $slideEl);
110 }
111
112 if ($shadowEl.length) {
113 const shadowOpacity = params.shadowPerProgress ? progress * (1 / params.limitProgress) : progress;
114 $shadowEl[0].style.opacity = Math.min(Math.max(Math.abs(shadowOpacity), 0), 1);
115 }
116 }
117
118 const $targetEl = effectTarget(params, $slideEl);
119 $targetEl.transform(transform).css({
120 opacity: opacityString
121 });
122
123 if (data.origin) {
124 $targetEl.css('transform-origin', data.origin);
125 }
126 }
127 };
128
129 const setTransition = duration => {
130 const {
131 transformEl
132 } = swiper.params.creativeEffect;
133 const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
134 $transitionElements.transition(duration).find('.swiper-slide-shadow').transition(duration);
135 effectVirtualTransitionEnd({
136 swiper,
137 duration,
138 transformEl,
139 allSlides: true
140 });
141 };
142
143 effectInit({
144 effect: 'creative',
145 swiper,
146 on,
147 setTranslate,
148 setTransition,
149 perspective: () => swiper.params.creativeEffect.perspective,
150 overwriteParams: () => ({
151 watchSlidesProgress: true,
152 virtualTranslate: !swiper.params.cssMode
153 })
154 });
155}
\No newline at end of file