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

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

238 lines 9.8 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.querySelectorAll('.bkbg-p360-app').forEach(function (app) {
5 var o;
6 try { o = JSON.parse(app.dataset.opts || '{}'); } catch (e) { return; }
7
8 var frames = Array.isArray(o.frames) ? o.frames : [];
9 var viewerWidth = o.viewerWidth || 600;
10 var viewerHeight = o.viewerHeight || 400;
11 var viewerRadius = o.viewerRadius || 16;
12 var autoSpin = !!o.autoSpin;
13 var autoSpeed = o.autoSpeed || 60;
14 var dragSensitivity = o.dragSensitivity || 4;
15 var showProgress = !!o.showProgress;
16 var showHint = !!o.showHint;
17 var hintText = o.hintText || 'Drag to rotate';
18 var showControls = !!o.showControls;
19 var bgColor = o.bgColor || '#f1f5f9';
20 var progressColor = o.progressColor || '#6366f1';
21 var hintColor = o.hintColor || '#64748b';
22 var controlsBg = o.controlsBg || '#ffffff';
23 var controlsColor = o.controlsColor || '#0f172a';
24
25 var _typoKeys = { hintTypo: '--bkbg-p360-hn-' };
26 function typoCssVarsForEl(el) {
27 Object.keys(_typoKeys).forEach(function (attr) {
28 var t = o[attr]; if (!t || typeof t !== 'object') return;
29 var p = _typoKeys[attr];
30 if (t.family) el.style.setProperty(p + 'font-family', t.family);
31 if (t.weight) el.style.setProperty(p + 'font-weight', t.weight);
32 if (t.transform) el.style.setProperty(p + 'text-transform', t.transform);
33 if (t.style) el.style.setProperty(p + 'font-style', t.style);
34 if (t.decoration) el.style.setProperty(p + 'text-decoration', t.decoration);
35 if (t.sizeDesktop) el.style.setProperty(p + 'font-size-d', t.sizeDesktop + (t.sizeUnit || 'px'));
36 if (t.sizeTablet) el.style.setProperty(p + 'font-size-t', t.sizeTablet + (t.sizeUnit || 'px'));
37 if (t.sizeMobile) el.style.setProperty(p + 'font-size-m', t.sizeMobile + (t.sizeUnit || 'px'));
38 if (t.lineHeightDesktop) el.style.setProperty(p + 'line-height-d', t.lineHeightDesktop + (t.lineHeightUnit || ''));
39 if (t.lineHeightTablet) el.style.setProperty(p + 'line-height-t', t.lineHeightTablet + (t.lineHeightUnit || ''));
40 if (t.lineHeightMobile) el.style.setProperty(p + 'line-height-m', t.lineHeightMobile + (t.lineHeightUnit || ''));
41 if (t.letterSpacingDesktop) el.style.setProperty(p + 'letter-spacing-d', t.letterSpacingDesktop + (t.letterSpacingUnit || 'px'));
42 if (t.letterSpacingTablet) el.style.setProperty(p + 'letter-spacing-t', t.letterSpacingTablet + (t.letterSpacingUnit || 'px'));
43 if (t.letterSpacingMobile) el.style.setProperty(p + 'letter-spacing-m', t.letterSpacingMobile + (t.letterSpacingUnit || 'px'));
44 if (t.wordSpacingDesktop) el.style.setProperty(p + 'word-spacing-d', t.wordSpacingDesktop + (t.wordSpacingUnit || 'px'));
45 if (t.wordSpacingTablet) el.style.setProperty(p + 'word-spacing-t', t.wordSpacingTablet + (t.wordSpacingUnit || 'px'));
46 if (t.wordSpacingMobile) el.style.setProperty(p + 'word-spacing-m', t.wordSpacingMobile + (t.wordSpacingUnit || 'px'));
47 });
48 }
49
50 if (frames.length === 0) return;
51
52 typoCssVarsForEl(app);
53
54 var total = frames.length;
55 var current = 0;
56
57 /* ── Build DOM ── */
58 var viewer = document.createElement('div');
59 viewer.className = 'bkbg-p360-viewer';
60 viewer.style.width = '100%';
61 viewer.style.maxWidth = viewerWidth + 'px';
62 viewer.style.height = viewerHeight + 'px';
63 viewer.style.borderRadius = viewerRadius + 'px';
64 viewer.style.background = bgColor;
65 viewer.style.setProperty('--p360-progress', progressColor);
66
67 var img = document.createElement('img');
68 img.className = 'bkbg-p360-img';
69 img.alt = frames[0].alt || '';
70 img.src = frames[0].url;
71 viewer.appendChild(img);
72
73 /* Progress */
74 var progressEl = null;
75 if (showProgress) {
76 progressEl = document.createElement('div');
77 progressEl.className = 'bkbg-p360-progress';
78 progressEl.style.width = '0%';
79 viewer.appendChild(progressEl);
80 }
81
82 /* Hint */
83 var hintEl = null;
84 if (showHint) {
85 hintEl = document.createElement('div');
86 hintEl.className = 'bkbg-p360-hint';
87 hintEl.textContent = hintText;
88 hintEl.style.background = 'rgba(0,0,0,0.45)';
89 hintEl.style.color = '#ffffff';
90 viewer.appendChild(hintEl);
91 }
92
93 app.appendChild(viewer);
94
95 /* Controls */
96 var counterEl = null;
97 if (showControls) {
98 var controls = document.createElement('div');
99 controls.className = 'bkbg-p360-controls';
100
101 var btnPrev = document.createElement('button');
102 btnPrev.className = 'bkbg-p360-btn';
103 btnPrev.textContent = '';
104 btnPrev.style.background = controlsBg;
105 btnPrev.style.color = controlsColor;
106
107 counterEl = document.createElement('div');
108 counterEl.className = 'bkbg-p360-counter';
109 counterEl.style.color = controlsColor;
110
111 var btnNext = document.createElement('button');
112 btnNext.className = 'bkbg-p360-btn';
113 btnNext.textContent = '';
114 btnNext.style.background = controlsBg;
115 btnNext.style.color = controlsColor;
116
117 controls.appendChild(btnPrev);
118 controls.appendChild(counterEl);
119 controls.appendChild(btnNext);
120 app.appendChild(controls);
121
122 btnPrev.addEventListener('click', function () { goTo(current - 1); stopHint(); });
123 btnNext.addEventListener('click', function () { goTo(current + 1); stopHint(); });
124 }
125
126 function goTo(idx) {
127 current = ((idx % total) + total) % total;
128 img.src = frames[current].url;
129 img.alt = frames[current].alt || '';
130 if (progressEl) {
131 progressEl.style.width = ((current / (total - 1)) * 100) + '%';
132 }
133 if (counterEl) {
134 counterEl.textContent = (current + 1) + ' / ' + total;
135 }
136 }
137
138 goTo(0);
139
140 /* ── Drag interaction ── */
141 var dragging = false;
142 var startX = 0;
143 var accumulated = 0;
144
145 function stopHint() {
146 if (hintEl && !hintEl.classList.contains('bkbg-p360-fade')) {
147 hintEl.classList.add('bkbg-p360-fade');
148 setTimeout(function () { if (hintEl && hintEl.parentNode) hintEl.parentNode.removeChild(hintEl); hintEl = null; }, 400);
149 }
150 }
151
152 function getClientX(e) {
153 return e.touches ? e.touches[0].clientX : e.clientX;
154 }
155
156 viewer.addEventListener('mousedown', function (e) {
157 dragging = true;
158 startX = getClientX(e);
159 accumulated = 0;
160 viewer.classList.add('bkbg-p360-dragging');
161 stopHint();
162 });
163
164 viewer.addEventListener('touchstart', function (e) {
165 dragging = true;
166 startX = getClientX(e);
167 accumulated = 0;
168 stopHint();
169 }, { passive: true });
170
171 document.addEventListener('mousemove', function (e) {
172 if (!dragging) return;
173 var dx = getClientX(e) - startX;
174 accumulated += dx;
175 startX = getClientX(e);
176 var step = Math.round(accumulated / dragSensitivity);
177 if (step !== 0) {
178 goTo(current + step);
179 accumulated = 0;
180 }
181 });
182
183 document.addEventListener('touchmove', function (e) {
184 if (!dragging) return;
185 var dx = getClientX(e) - startX;
186 accumulated += dx;
187 startX = getClientX(e);
188 var step = Math.round(accumulated / dragSensitivity);
189 if (step !== 0) {
190 goTo(current - step);
191 accumulated = 0;
192 }
193 }, { passive: true });
194
195 function endDrag() {
196 dragging = false;
197 viewer.classList.remove('bkbg-p360-dragging');
198 }
199 document.addEventListener('mouseup', endDrag);
200 document.addEventListener('touchend', endDrag);
201
202 /* ── Auto spin ── */
203 if (autoSpin && total > 1) {
204 var interval = 1000 / autoSpeed;
205 var spinAcc = 0;
206 var lastTime = null;
207 var rafId = null;
208
209 function spin(ts) {
210 if (!lastTime) lastTime = ts;
211 var dt = ts - lastTime;
212 lastTime = ts;
213
214 if (!dragging) {
215 spinAcc += dt;
216 while (spinAcc >= interval) {
217 goTo(current + 1);
218 spinAcc -= interval;
219 }
220 }
221 rafId = requestAnimationFrame(spin);
222 }
223
224 var observer = new IntersectionObserver(function (entries) {
225 entries.forEach(function (entry) {
226 if (entry.isIntersecting) {
227 lastTime = null;
228 rafId = requestAnimationFrame(spin);
229 } else {
230 if (rafId) { cancelAnimationFrame(rafId); rafId = null; }
231 }
232 });
233 }, { threshold: 0.1 });
234 observer.observe(app);
235 }
236 });
237 }());
238