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 / video / frontend.js

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

352 lines 8.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Block Video
3 */
4
5 const {
6 GHOSTKIT: { events },
7 Motion: { animate },
8 } = window;
9
10 const animationDuration = 0.2;
11
12 function animationFullscreenOpen(element) {
13 animate(
14 element,
15 {
16 opacity: [0, 1],
17 display: 'flex',
18 },
19 {
20 duration: animationDuration,
21 display: { duration: 0 },
22 }
23 );
24 }
25
26 /**
27 * Prepare Videos.
28 */
29 events.on(document, 'init.blocks.gkt', () => {
30 if (typeof window.VideoWorker === 'undefined') {
31 return;
32 }
33
34 document
35 .querySelectorAll('.ghostkit-video:not(.ghostkit-video-ready)')
36 .forEach(($this) => {
37 $this.classList.add('ghostkit-video-ready');
38
39 events.trigger($this, 'prepare.video.gkt');
40
41 const url = $this.getAttribute('data-video');
42 const clickAction = $this.getAttribute('data-click-action');
43
44 const videoAutoplay =
45 $this.getAttribute('data-video-autoplay') === 'true';
46 const videoAutopause =
47 $this.getAttribute('data-video-autopause') === 'true';
48 const videoLoop = $this.getAttribute('data-video-loop') === 'true';
49
50 const fullscreenCloseIcon =
51 $this.querySelector('.ghostkit-video-fullscreen-close-icon')
52 ?.innerHTML || '';
53
54 const fullscreenVideoBackgroundColor = $this.getAttribute(
55 'data-fullscreen-video-background-color'
56 );
57 const fullscreenVideoBackgroundGradient = $this.getAttribute(
58 'data-fullscreen-video-background-gradient'
59 );
60 const fullscreenBackgroundColor = $this.getAttribute(
61 'data-fullscreen-background-color'
62 );
63 const fullscreenBackgroundGradient = $this.getAttribute(
64 'data-fullscreen-background-gradient'
65 );
66
67 let $poster = $this.querySelector('.ghostkit-video-poster');
68 let $fullscreenWrapper = false;
69 let mute = 0;
70
71 let aspectRatio = $this.getAttribute('data-video-aspect-ratio');
72 const aspectRatioWidth = aspectRatio.split(':')[0];
73 const aspectRatioHeight = aspectRatio.split(':')[1];
74 if (aspectRatio && aspectRatioWidth && aspectRatioHeight) {
75 aspectRatio = aspectRatioWidth / aspectRatioHeight;
76 } else {
77 aspectRatio = 16 / 9;
78 }
79
80 // Mute if volume 0.
81 if (!parseFloat($this.getAttribute('data-video-volume'))) {
82 mute = 1;
83 }
84
85 // Mute if autoplay.
86 if (videoAutoplay) {
87 mute = 1;
88 }
89
90 const options = {
91 autoplay: 0,
92 loop: videoLoop,
93 mute,
94 volume:
95 parseFloat($this.getAttribute('data-video-volume')) || 0,
96 showContols: 1,
97 };
98
99 events.trigger($this, 'prepare.videoWorker.gkt', { options });
100
101 const api = new window.VideoWorker(url, options);
102
103 events.trigger($this, 'prepared.videoWorker.gkt', { api });
104
105 if (api && api.isValid()) {
106 let loaded = 0;
107 let clicked = 0;
108 let isPlaying = false;
109
110 // Add play event.
111 const handlerOpen = () => {
112 if (clicked) {
113 return;
114 }
115 clicked = 1;
116
117 // Fullscreen video.
118 if (clickAction === 'fullscreen') {
119 // Add loading button.
120 if (!loaded) {
121 $this.classList.add('ghostkit-video-loading');
122
123 api.getVideo(($iframe) => {
124 // Add iframe.
125 const $parent = $iframe.parentNode;
126
127 // Create fullscreen frame wrapper.
128 const $fullscreenFrameWrapper =
129 document.createElement('div');
130 $fullscreenFrameWrapper.classList.add(
131 'ghostkit-video-fullscreen-frame'
132 );
133 $fullscreenFrameWrapper.append($iframe);
134
135 // Create close wrapper.
136 const $fullscreenClose =
137 document.createElement('div');
138 $fullscreenClose.classList.add(
139 'ghostkit-video-fullscreen-close'
140 );
141 $fullscreenClose.innerHTML =
142 fullscreenCloseIcon;
143
144 // Create fullscreen wrapper.
145 $fullscreenWrapper =
146 document.createElement('div');
147 $fullscreenWrapper.classList.add(
148 'ghostkit-video-fullscreen'
149 );
150 $fullscreenWrapper.style.backgroundColor =
151 fullscreenBackgroundColor;
152 $fullscreenWrapper.style.backgroundImage =
153 fullscreenBackgroundGradient;
154 $fullscreenWrapper.style.setProperty(
155 '--gkt-fullscreen-video--video__background',
156 fullscreenVideoBackgroundColor ||
157 fullscreenVideoBackgroundGradient
158 );
159 $fullscreenWrapper.style.setProperty(
160 '--gkt-fullscreen-video__aspect-ratio-width',
161 aspectRatioWidth
162 );
163 $fullscreenWrapper.style.setProperty(
164 '--gkt-fullscreen-video__aspect-ratio-height',
165 aspectRatioHeight
166 );
167
168 // Add close and frame in the fullscreen wrapper.
169 $fullscreenWrapper.append($fullscreenClose);
170 $fullscreenWrapper.append(
171 $fullscreenFrameWrapper
172 );
173
174 // Add fullscreen in the body.
175 document.body.append($fullscreenWrapper);
176
177 $parent.remove();
178
179 animationFullscreenOpen($fullscreenWrapper);
180
181 events.on($fullscreenWrapper, 'click', (e) => {
182 const $target = e.target;
183
184 if (
185 $target.classList.contains(
186 'ghostkit-video-fullscreen'
187 ) ||
188 $target.classList.contains(
189 'ghostkit-video-fullscreen-close'
190 ) ||
191 $target.closest(
192 '.ghostkit-video-fullscreen-close'
193 )
194 ) {
195 api.pause();
196 $this.classList.add(
197 'ghostkit-video-fullscreen-closed'
198 );
199 animate(
200 $fullscreenWrapper,
201 {
202 opacity: [1, 0],
203 display: 'none',
204 },
205 { duration: animationDuration }
206 );
207 }
208 });
209 });
210
211 loaded = 1;
212 } else if ($fullscreenWrapper) {
213 $this.classList.remove(
214 'ghostkit-video-fullscreen-closed'
215 );
216
217 animationFullscreenOpen($fullscreenWrapper);
218 api.play();
219 }
220
221 // Plain video.
222 } else if (!loaded) {
223 $this.classList.add('ghostkit-video-loading');
224
225 api.getVideo(($iframe) => {
226 const $parent = $iframe.parentNode;
227
228 // Add iframe.
229 const $wrapper = document.createElement('div');
230 $wrapper.classList.add('ghostkit-video-frame');
231 $wrapper.append($iframe);
232
233 $this.append($wrapper);
234
235 $parent.remove();
236 });
237
238 loaded = 1;
239 } else {
240 api.play();
241 }
242 };
243 events.on($this, 'click', handlerOpen);
244
245 // Set thumb.
246 if (
247 !$poster &&
248 !$this.classList.contains('is-style-icon-only')
249 ) {
250 api.getImageURL((imgSrc) => {
251 const $image = document.createElement('img');
252 $image.setAttribute('src', imgSrc);
253 $image.setAttribute('alt', '');
254
255 $poster = document.createElement('div');
256 $poster.classList.add('ghostkit-video-poster');
257 $poster.append($image);
258
259 $this.append($poster);
260 });
261 }
262
263 let autoplayOnce = false;
264
265 api.on('ready', () => {
266 $this.classList.remove('ghostkit-video-loading');
267
268 if (clickAction === 'fullscreen') {
269 if (
270 !$this.classList.contains(
271 'ghostkit-video-fullscreen-closed'
272 )
273 ) {
274 api.play();
275 }
276 } else {
277 $this.classList.add('ghostkit-video-playing');
278 api.play();
279 }
280 });
281 api.on('play', () => {
282 isPlaying = true;
283 });
284 api.on('pause', () => {
285 isPlaying = false;
286 autoplayOnce = true;
287 if (clickAction === 'fullscreen') {
288 clicked = 0;
289 }
290 });
291
292 if (
293 clickAction !== 'fullscreen' &&
294 (videoAutoplay || videoAutopause)
295 ) {
296 if (!('IntersectionObserver' in window)) {
297 return;
298 }
299
300 const videoObserverData = {
301 callback: (entries) => {
302 entries.forEach((entry) => {
303 if ($this !== entry.target) {
304 return;
305 }
306
307 // Autoplay.
308 if (
309 !autoplayOnce &&
310 !isPlaying &&
311 videoAutoplay &&
312 entry.isIntersecting
313 ) {
314 if (clicked) {
315 api.play();
316 } else {
317 $this.click();
318 }
319 }
320
321 // Autopause.
322 if (
323 isPlaying &&
324 videoAutopause &&
325 !entry.isIntersecting
326 ) {
327 api.pause();
328 }
329 });
330 },
331 options: {
332 threshold: 0.6,
333 },
334 };
335
336 events.trigger($this, 'prepare.videoObserver.gkt', {
337 config: videoObserverData,
338 });
339
340 const videoObserver = new window.IntersectionObserver(
341 videoObserverData.callback,
342 videoObserverData.options
343 );
344
345 videoObserver.observe($this);
346 }
347 }
348
349 events.trigger($this, 'prepared.video.gkt');
350 });
351 });
352