PluginProbe
Block Animations, Motion & Scroll Effects – Ghost Kit / 3.3.3
Block Animations, Motion & Scroll Effects – Ghost Kit v3.3.3
3.7.2 3.7.1 3.7.0 3.6.1 trunk 1.6.3 2.25.0 3.3.0 3.3.1 3.3.2 3.3.3 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6 3.5.0 3.5.1 3.6.0
ghostkit / gutenberg / blocks / carousel / frontend.js

frontend.js in Block Animations, Motion & Scroll Effects – Ghost Kit 3.3.3, at gutenberg/blocks/carousel/frontend.js

308 lines 7.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Block Carousel
3 */
4 import getParents from '../../utils/get-parents';
5 import getSiblings from '../../utils/get-siblings';
6
7 const {
8 GHOSTKIT: { screenSizes, events },
9 } = window;
10
11 function getSwiperVersion(Swiper) {
12 let ver = 8;
13
14 // in version 8 added new parameter `maxBackfaceHiddenSlides`.
15 if (typeof Swiper.defaults.maxBackfaceHiddenSlides === 'undefined') {
16 ver = 7;
17 }
18
19 // in version 7 added new parameter `rewind`.
20 if (typeof Swiper.defaults.rewind === 'undefined') {
21 ver = 6;
22 }
23
24 // in version 6 added new parameter `loopPreventsSlide`.
25 if (typeof Swiper.defaults.loopPreventsSlide === 'undefined') {
26 ver = 5;
27 }
28
29 return ver;
30 }
31
32 /**
33 * Prepare Carousels.
34 */
35 events.on(document, 'init.blocks.gkt', () => {
36 if (typeof window.Swiper === 'undefined') {
37 return;
38 }
39
40 document
41 .querySelectorAll('.ghostkit-carousel:not(.ghostkit-carousel-ready)')
42 .forEach(($carousel) => {
43 const $items = $carousel.querySelector(
44 ':scope > .ghostkit-carousel-items'
45 );
46 const effect = $carousel.getAttribute('data-effect') || 'slide';
47 const slidesPerView = parseInt(
48 $carousel.getAttribute('data-slides-per-view'),
49 10
50 );
51
52 const options = {
53 speed:
54 (parseFloat($carousel.getAttribute('data-speed')) || 0) *
55 1000,
56 effect,
57 fadeEffect: {
58 // fixed fade out for previous slider.
59 crossFade: true,
60 },
61 spaceBetween:
62 parseFloat($carousel.getAttribute('data-gap')) || 0,
63 centeredSlides:
64 $carousel.getAttribute('data-centered-slides') === 'true',
65 freeMode: {
66 enabled:
67 $carousel.getAttribute('data-free-scroll') === 'true',
68 },
69 loop: $carousel.getAttribute('data-loop') === 'true',
70 // This feature is cool, but not working properly when loop enabled
71 // and fast clicking on previous button is not working properly
72 // https://github.com/nolimits4web/swiper/issues/5945
73 // loopPreventsSlide: false,
74 autoplay: parseFloat($carousel.getAttribute('data-autoplay')) >
75 0 && {
76 delay:
77 parseFloat($carousel.getAttribute('data-autoplay')) *
78 1000,
79 disableOnInteraction: false,
80 },
81 navigation: $carousel.getAttribute('data-show-arrows') ===
82 'true' && {
83 nextEl: '.ghostkit-carousel-arrow-next',
84 prevEl: '.ghostkit-carousel-arrow-prev',
85 },
86 pagination: $carousel.getAttribute('data-show-bullets') ===
87 'true' && {
88 el: '.ghostkit-carousel-bullets',
89 clickable: true,
90 dynamicBullets:
91 $carousel.getAttribute('data-dynamic-bullets') ===
92 'true',
93 },
94 slidesPerView: 1,
95 keyboard: true,
96 grabCursor: true,
97 preloadImages: false,
98
99 // fixes text selection when swipe in the items gap.
100 touchEventsTarget: 'container',
101
102 // disable swiping on some elements.
103 noSwipingSelector: 'input, textarea, .ghostkit-image-compare',
104 };
105
106 $carousel.classList.add('ghostkit-carousel-ready', 'swiper');
107 $items.classList.add('swiper-wrapper');
108 $items
109 .querySelectorAll(':scope > .ghostkit-carousel-slide')
110 .forEach(($slide) => {
111 $slide.classList.add('swiper-slide');
112 });
113
114 // add arrows
115 if (options.navigation) {
116 const $prevArrowIcon = $carousel.querySelector(
117 '.ghostkit-carousel-arrow-prev-icon'
118 );
119 const $nextArrowIcon = $carousel.querySelector(
120 '.ghostkit-carousel-arrow-next-icon'
121 );
122
123 // Create and add arrow previous.
124 const $prevArrow = document.createElement('div');
125 $prevArrow.classList.add(
126 'ghostkit-carousel-arrow',
127 'ghostkit-carousel-arrow-prev'
128 );
129 $prevArrow.innerHTML = $prevArrowIcon.innerHTML;
130 $carousel.append($prevArrow);
131
132 // Create and add arrow next.
133 const $nextArrow = document.createElement('div');
134 $nextArrow.classList.add(
135 'ghostkit-carousel-arrow',
136 'ghostkit-carousel-arrow-next'
137 );
138 $nextArrow.innerHTML = $nextArrowIcon.innerHTML;
139 $carousel.append($nextArrow);
140 }
141
142 // Add bullets.
143 if (options.pagination) {
144 const $bullets = document.createElement('div');
145 $bullets.classList.add('ghostkit-carousel-bullets');
146 $carousel.append($bullets);
147 }
148
149 // Calculate responsive.
150 const breakPoints = {};
151 if (effect !== 'fade' && !Number.isNaN(slidesPerView)) {
152 let count = slidesPerView;
153 let currentPoint = Math.min(screenSizes.length - 1, count - 1);
154
155 for (; currentPoint >= 0; currentPoint -= 1) {
156 if (
157 count > 0 &&
158 typeof screenSizes[currentPoint] !== 'undefined'
159 ) {
160 breakPoints[screenSizes[currentPoint] + 1] = {
161 slidesPerView: count,
162 };
163 }
164 count -= 1;
165 }
166
167 options.slidesPerView = count || 1;
168 }
169 options.breakpoints = breakPoints;
170
171 // Events.
172 options.on = {
173 // These events used to add fixes for
174 // conflict with custom cursor movement.
175 touchStart(swiper, evt) {
176 events.trigger($carousel, 'touchStart.carousel.gkt', {
177 originalEvent: evt,
178 });
179 },
180 touchMove(swiper, evt) {
181 events.trigger($carousel, 'touchMove.carousel.gkt', {
182 originalEvent: evt,
183 });
184 },
185 touchEnd(swiper, evt) {
186 events.trigger($carousel, 'touchEnd.carousel.gkt', {
187 originalEvent: evt,
188 });
189 },
190 };
191
192 // Fallbacks for old Swiper versions.
193 (() => {
194 const swiperVersion = getSwiperVersion(window.Swiper);
195
196 // Since v7 used container class `swiper`, we should also add old `swiper-container` class.
197 if (swiperVersion < 7) {
198 $carousel.classList.add('swiper-container');
199 }
200
201 // Since v7 freeMode options moved under `freeMode` object.
202 if (swiperVersion < 7) {
203 options.freeMode = options.freeMode.enabled;
204 }
205
206 // Since v5 `breakpointsInverse` option is removed and it is now `true` by default, but in older versions it was `false`.
207 if (swiperVersion >= 5) {
208 options.breakpointsInverse = true;
209 }
210 })();
211
212 events.trigger($carousel, 'init.carousel.gkt', { options });
213
214 // init swiper
215 new window.Swiper($carousel, options);
216
217 events.trigger($carousel, 'inited.carousel.gkt', { options });
218 });
219 });
220
221 /**
222 * Autoplay pause/play on hover.
223 */
224 events.on(
225 document,
226 'mouseenter',
227 '.ghostkit-carousel-ready[data-autoplay-hover-pause="true"]',
228 (e) => {
229 const $slider = e.delegateTarget;
230
231 if (
232 !$slider?.swiper?.autoplay ||
233 !$slider?.swiper?.params?.autoplay?.enabled
234 ) {
235 return;
236 }
237
238 $slider.swiper.autoplay.stop();
239 }
240 );
241 events.on(
242 document,
243 'mouseleave',
244 '.ghostkit-carousel-ready[data-autoplay-hover-pause="true"]',
245 (e) => {
246 const $slider = e.delegateTarget;
247
248 if (
249 !$slider?.swiper?.autoplay ||
250 !$slider?.swiper?.params?.autoplay?.enabled
251 ) {
252 return;
253 }
254
255 $slider.swiper.autoplay.start();
256 }
257 );
258
259 /**
260 * Re-create slides duplicates.
261 * https://github.com/nolimits4web/swiper/issues/2629
262 */
263 events.on(
264 document,
265 'shown.tab.gkt shown.accordion.gkt move.image-compare.gkt closed.alert.gkt animated.counter.gkt',
266 (e) => {
267 const $el = e.delegateTarget;
268 const $carousels = getParents($el);
269
270 $carousels.forEach(($this) => {
271 if (
272 $this.classList.contains('ghostkit-carousel-ready') &&
273 $this.getAttribute('data-loop') === 'true' &&
274 $this.swiper
275 ) {
276 const $slide = $el.closest('.swiper-slide');
277
278 // Copy the content of duplicated slide to original when changed content inside duplicated slide.
279 if (
280 $slide &&
281 $slide.classList.contains('swiper-slide-duplicate')
282 ) {
283 getSiblings($slide).forEach(($slideSibling) => {
284 if (
285 $slideSibling.getAttribute(
286 'data-swiper-slide-index'
287 ) ===
288 $slide.getAttribute(
289 'data-swiper-slide-index'
290 ) &&
291 $slideSibling.classList.contains(
292 ':not(.swiper-slide-duplicate):first-child'
293 )
294 ) {
295 $slideSibling.innerHTML = $slide.innerHTML;
296 }
297 });
298
299 // Recreate loop when changed content inside original slide.
300 } else {
301 $this.swiper.loopDestroy();
302 $this.swiper.loopCreate();
303 }
304 }
305 });
306 }
307 );
308