PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.7
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.7
2.0.13 2.0.12 2.0.11 2.0.10 2.0.9 trunk 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8
blockenberg / blocks / video-section / frontend.js

frontend.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.7, at blocks/video-section/frontend.js

129 lines 5.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () {
2 'use strict';
3
4 document.addEventListener('DOMContentLoaded', function () {
5 initVideoSections();
6 initStatCounters();
7 });
8
9 /* ── Poster → Play ─────────────────────────────────────────────────
10 Clicking the poster/play-button area swaps in the actual iframe or
11 <video> element so the page loads fast (no eager iframe load).
12 ──────────────────────────────────────────────────────────────── */
13 function initVideoSections() {
14 document.querySelectorAll('.bkbg-vs-poster-wrap').forEach(function (posterWrap) {
15 posterWrap.addEventListener('click', function () {
16 var aspect = posterWrap.closest('.bkbg-vs-aspect');
17 var wrapper = posterWrap.closest('.bkbg-vs-wrapper');
18 if (!aspect || !wrapper) return;
19
20 var videoType = wrapper.dataset.videoType || 'youtube';
21 var youtubeId = wrapper.dataset.youtubeId;
22 var vimeoId = wrapper.dataset.vimeoId;
23 var selfUrl = wrapper.dataset.videoUrl;
24
25 /* Mark poster as playing (CSS fades it out) */
26 posterWrap.classList.add('is-playing');
27
28 var player;
29
30 if (videoType === 'self' && selfUrl) {
31 player = document.createElement('video');
32 player.src = selfUrl;
33 player.autoplay = true;
34 player.controls = true;
35 player.className = 'bkbg-vs-video';
36 player.playsInline = true;
37 } else {
38 /* Embed iframe */
39 player = document.createElement('iframe');
40 player.className = 'bkbg-vs-iframe';
41 player.allowFullscreen = true;
42 player.allow = 'autoplay; encrypted-media; picture-in-picture';
43
44 if (videoType === 'vimeo' && vimeoId) {
45 player.src = 'https://player.vimeo.com/video/' + vimeoId + '?autoplay=1&color=6c3fb5';
46 } else if (youtubeId) {
47 player.src = 'https://www.youtube.com/embed/' + youtubeId + '?autoplay=1&rel=0';
48 } else {
49 return; /* no ID configured */
50 }
51 }
52
53 aspect.appendChild(player);
54
55 /* Fade out poster after player is appended */
56 setTimeout(function () {
57 posterWrap.style.display = 'none';
58 }, 400);
59 });
60 });
61 }
62
63 /* ── Stat counter animation ────────────────────────────────────────
64 Detects numeric parts in stat-value text and animates count-up
65 when the stat strip scrolls into view.
66 ──────────────────────────────────────────────────────────────── */
67 function initStatCounters() {
68 if (!('IntersectionObserver' in window)) return;
69
70 document.querySelectorAll('.bkbg-vs-stats').forEach(function (strip) {
71 var stats = strip.querySelectorAll('.bkbg-vs-stat');
72 if (!stats.length) return;
73
74 var animated = false;
75
76 var observer = new IntersectionObserver(function (entries) {
77 entries.forEach(function (entry) {
78 if (entry.isIntersecting && !animated) {
79 animated = true;
80 animateStats(stats);
81 observer.disconnect();
82 }
83 });
84 }, { threshold: 0.3 });
85
86 observer.observe(strip);
87 });
88 }
89
90 function animateStats(statEls) {
91 statEls.forEach(function (stat, i) {
92 var valueEl = stat.querySelector('.bkbg-vs-stat-value');
93 if (!valueEl) return;
94
95 stat.classList.add('bkbg-vs-animate');
96
97 var original = valueEl.textContent;
98 /* Extract leading/trailing non-numeric parts and the numeric part */
99 var match = original.match(/^([^0-9]*)(\d+(?:[.,]\d+)?)(.*)$/);
100 if (!match) return;
101
102 var prefix = match[1];
103 var numStr = match[2].replace(',', '.');
104 var suffix = match[3];
105 var target = parseFloat(numStr);
106 var isFloat = numStr.indexOf('.') !== -1;
107 var decimals = isFloat ? (numStr.split('.')[1] || '').length : 0;
108 var duration = 1200;
109 var start = null;
110 var delay = i * 100;
111
112 setTimeout(function () {
113 requestAnimationFrame(function step(ts) {
114 if (!start) start = ts;
115 var progress = Math.min((ts - start) / duration, 1);
116 var ease = 1 - Math.pow(1 - progress, 3); /* ease-out cubic */
117 var current = target * ease;
118 valueEl.textContent = prefix + (isFloat ? current.toFixed(decimals) : Math.round(current)) + suffix;
119 if (progress < 1) {
120 requestAnimationFrame(step);
121 } else {
122 valueEl.textContent = original; /* restore exact original */
123 }
124 });
125 }, delay);
126 });
127 }
128 })();
129