PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.11
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.11
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 / icon-cloud / frontend.js

frontend.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.11, at blocks/icon-cloud/frontend.js

192 lines 8.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () {
2
3 var typoMap = [
4 ['family','font-family'],['weight','font-weight'],['style','font-style'],
5 ['decoration','text-decoration'],['transform','text-transform'],
6 ['sizeDesktop','font-size-d'],['sizeTablet','font-size-t'],['sizeMobile','font-size-m'],
7 ['lineHeightDesktop','line-height-d'],['lineHeightTablet','line-height-t'],['lineHeightMobile','line-height-m'],
8 ['letterSpacingDesktop','letter-spacing-d'],['letterSpacingTablet','letter-spacing-t'],['letterSpacingMobile','letter-spacing-m'],
9 ['wordSpacingDesktop','word-spacing-d'],['wordSpacingTablet','word-spacing-t'],['wordSpacingMobile','word-spacing-m']
10 ];
11 function typoCssVarsForEl(typo, prefix, el) {
12 if (!typo || typeof typo !== 'object') return;
13 for (var i = 0; i < typoMap.length; i++) {
14 var v = typo[typoMap[i][0]];
15 if (v !== undefined && v !== '' && v !== null) el.style.setProperty(prefix + typoMap[i][1], String(v));
16 }
17 }
18
19 function fibonacciSphere(n, r) {
20 var points = [];
21 var phi = Math.PI * (3 - Math.sqrt(5));
22 for (var i = 0; i < n; i++) {
23 var y = 1 - (i / Math.max(n - 1, 1)) * 2;
24 var radius = Math.sqrt(1 - y * y);
25 var theta = phi * i;
26 points.push([Math.cos(theta) * radius * r, y * r, Math.sin(theta) * radius * r]);
27 }
28 return points;
29 }
30
31 function rotateX(pts, a) {
32 var cos = Math.cos(a), sin = Math.sin(a);
33 return pts.map(function(p) { return [p[0], p[1]*cos - p[2]*sin, p[1]*sin + p[2]*cos]; });
34 }
35 function rotateY(pts, a) {
36 var cos = Math.cos(a), sin = Math.sin(a);
37 return pts.map(function(p) { return [p[0]*cos + p[2]*sin, p[1], -p[0]*sin + p[2]*cos]; });
38 }
39
40 function lerpColor(a, b, t) {
41 if (!a || !b) return a||b||'#fff';
42 function h(str, o) { return parseInt(str.replace('#','').substr(o,2),16); }
43 var rr=Math.round(h(a,0)+(h(b,0)-h(a,0))*t);
44 var rg=Math.round(h(a,2)+(h(b,2)-h(a,2))*t);
45 var rb=Math.round(h(a,4)+(h(b,4)-h(a,4))*t);
46 return 'rgb('+rr+','+rg+','+rb+')';
47 }
48
49 var MULTI_COLORS = ['#7c3aed','#ec4899','#06b6d4','#f59e0b','#10b981','#ef4444','#3b82f6'];
50
51 function initIconCloud(appEl) {
52 var opts;
53 try { opts = JSON.parse(appEl.getAttribute('data-opts') || '{}'); } catch(e){ opts = {}; }
54
55 var a = {
56 items: opts.items || [],
57 cloudRadius: opts.cloudRadius || 220,
58 autoRotateX: opts.autoRotateX === undefined ? 0.002 : opts.autoRotateX,
59 autoRotateY: opts.autoRotateY === undefined ? 0.004 : opts.autoRotateY,
60 mouseEffect: opts.mouseEffect !== false,
61 mouseStrength: opts.mouseStrength || 0.06,
62 perspective: opts.perspective || 900,
63 fontSize: (opts.itemTypo && opts.itemTypo.sizeDesktop) ? parseFloat(opts.itemTypo.sizeDesktop) : (opts.fontSize || 14),
64 fontWeight: opts.fontWeight || 600,
65 itemPadding: opts.itemPadding || 6,
66 itemBorderRadius:opts.itemBorderRadius||6,
67 bgColor: opts.bgColor || '',
68 cloudHeight: opts.cloudHeight || 500,
69 colorMode: opts.colorMode || 'gradient',
70 colorFrom: opts.colorFrom || '#7c3aed',
71 colorTo: opts.colorTo || '#ec4899',
72 itemBg: opts.itemBg || '#1e1b4b',
73 itemBorder: opts.itemBorder || '#7c3aed44',
74 textColor: opts.textColor || '#e2e8f0',
75 hoverBg: opts.hoverBg || '#7c3aed',
76 hoverColor: opts.hoverColor || '#ffffff',
77 showBackground: opts.showBackground|| false,
78 depthFade: opts.depthFade !== false
79 };
80
81 if (!a.items.length) {
82 appEl.remove();
83 return;
84 }
85
86 var wrap = document.createElement('div');
87 wrap.className = 'bkbg-ic-wrap';
88 var cs = wrap.style;
89 cs.setProperty('--bkbg-ic-height', a.cloudHeight + 'px');
90 cs.setProperty('--bkbg-ic-bg', a.showBackground && a.bgColor ? a.bgColor : 'transparent');
91 cs.setProperty('--bkbg-ic-item-bg', a.itemBg);
92 cs.setProperty('--bkbg-ic-item-border', a.itemBorder);
93 cs.setProperty('--bkbg-ic-fs', a.fontSize + 'px');
94 cs.setProperty('--bkbg-ic-fw', String(a.fontWeight));
95 cs.setProperty('--bkbg-ic-br', a.itemBorderRadius + 'px');
96 cs.setProperty('--bkbg-ic-pv', a.itemPadding + 'px');
97 cs.setProperty('--bkbg-ic-ph', (a.itemPadding + 6) + 'px');
98 cs.setProperty('--bkbg-ic-hover-bg', a.hoverBg);
99 cs.setProperty('--bkbg-ic-hover-color', a.hoverColor);
100 cs.setProperty('--bkbg-ic-fw', String(a.fontWeight));
101 cs.setProperty('--bkbg-ic-fs', a.fontSize + 'px');
102 typoCssVarsForEl(opts.itemTypo, '--bkbg-ic-it-', wrap);
103
104 var stage = document.createElement('div');
105 stage.className = 'bkbg-ic-stage';
106
107 /* Build DOM items */
108 var itemEls = a.items.map(function(txt, i) {
109 var div = document.createElement('div');
110 div.className = 'bkbg-ic-item';
111 div.textContent = txt;
112 if (a.colorMode === 'multi') {
113 div.style.color = MULTI_COLORS[i % MULTI_COLORS.length];
114 }
115 stage.appendChild(div);
116 return div;
117 });
118
119 wrap.appendChild(stage);
120 appEl.replaceWith(wrap);
121
122 var n = a.items.length;
123 var r = a.cloudRadius;
124 var pts = fibonacciSphere(n, r);
125
126 var rotX = 0, rotY = 0;
127 var mouseX = 0, mouseY = 0;
128 var rafId = null;
129
130 function render() {
131 var rotated = rotateX(rotateY(pts, rotY), rotX);
132 var persp = a.perspective;
133
134 for (var i = 0; i < n; i++) {
135 var p = rotated[i];
136 var scale = persp / (persp - p[2]);
137 var x2d = p[0] * scale;
138 var y2d = p[1] * scale;
139 var depth = (p[2] + r) / (2 * r); /* 0=back, 1=front */
140 var opacity = a.depthFade ? (0.25 + depth * 0.75) : 1;
141 var el = itemEls[i];
142
143 var color;
144 if (a.colorMode === 'gradient') {
145 color = lerpColor(a.colorTo, a.colorFrom, depth);
146 } else if (a.colorMode === 'multi') {
147 color = MULTI_COLORS[i % MULTI_COLORS.length];
148 } else {
149 color = a.textColor;
150 }
151
152 el.style.transform = 'translate(-50%,-50%) translate(' + x2d + 'px,' + y2d + 'px)';
153 el.style.zIndex = Math.round(depth * 100);
154 el.style.opacity = opacity;
155 el.style.color = color;
156 el.style.fontSize = (a.fontSize * (0.7 + depth * 0.5)) + 'px';
157 }
158 }
159
160 function loop() {
161 rotY += a.autoRotateY + mouseX * a.mouseStrength;
162 rotX += a.autoRotateX + mouseY * a.mouseStrength;
163 mouseX *= 0.9;
164 mouseY *= 0.9;
165 render();
166 rafId = requestAnimationFrame(loop);
167 }
168
169 if (a.mouseEffect) {
170 stage.addEventListener('mousemove', function(e) {
171 var rect = stage.getBoundingClientRect();
172 mouseX = (e.clientX - rect.left - rect.width / 2) / rect.width * 0.08;
173 mouseY = (e.clientY - rect.top - rect.height / 2) / rect.height * 0.08;
174 });
175 stage.addEventListener('mouseleave', function() { mouseX = 0; mouseY = 0; });
176 }
177
178 /* Pause when off-screen */
179 if ('IntersectionObserver' in window) {
180 var obs = new IntersectionObserver(function(entries) {
181 if (entries[0].isIntersecting) { if (!rafId) loop(); }
182 else { if (rafId) { cancelAnimationFrame(rafId); rafId = null; } }
183 }, { threshold: 0 });
184 obs.observe(wrap);
185 } else {
186 loop();
187 }
188 }
189
190 document.querySelectorAll('.bkbg-ic-app').forEach(initIconCloud);
191 })();
192