PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.14
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.14
2.0.14 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 / holographic-card / frontend.js

frontend.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.14, at blocks/holographic-card/frontend.js

181 lines 7.9 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 function typoCssVarsForEl(typo, prefix, el) {
5 if (!typo || typeof typo !== 'object') return;
6 var map = {
7 family:'font-family', weight:'font-weight', style:'font-style',
8 decoration:'text-decoration', transform:'text-transform',
9 sizeDesktop:'font-size-d', sizeTablet:'font-size-t', sizeMobile:'font-size-m',
10 lineHeightDesktop:'line-height-d', lineHeightTablet:'line-height-t', lineHeightMobile:'line-height-m',
11 letterSpacingDesktop:'letter-spacing-d', letterSpacingTablet:'letter-spacing-t', letterSpacingMobile:'letter-spacing-m',
12 wordSpacingDesktop:'word-spacing-d', wordSpacingTablet:'word-spacing-t', wordSpacingMobile:'word-spacing-m'
13 };
14 Object.keys(map).forEach(function(k) {
15 if (typo[k] !== undefined && typo[k] !== '') {
16 var v = typo[k];
17 if (['sizeDesktop','sizeTablet','sizeMobile'].indexOf(k) !== -1) v = v + (typo.sizeUnit || 'px');
18 else if (['lineHeightDesktop','lineHeightTablet','lineHeightMobile'].indexOf(k) !== -1) v = v + (typo.lineHeightUnit || '');
19 else if (['letterSpacingDesktop','letterSpacingTablet','letterSpacingMobile'].indexOf(k) !== -1) v = v + (typo.letterSpacingUnit || 'px');
20 else if (['wordSpacingDesktop','wordSpacingTablet','wordSpacingMobile'].indexOf(k) !== -1) v = v + (typo.wordSpacingUnit || 'px');
21 el.style.setProperty(prefix + map[k], String(v));
22 }
23 });
24 }
25
26 function initBlock(root) {
27 var card = root.querySelector('.bkbg-hgc-app');
28 if (!card) return;
29
30 var raw = card.getAttribute('data-opts') || '{}';
31 var o;
32 try { o = JSON.parse(raw); } catch (e) { o = {}; }
33
34 var tiltStrength = Number(o.tiltStrength) || 15;
35 var shineOpacity = Number(o.shineOpacity) || 60;
36 var glareOpacity = Number(o.glareOpacity) || 40;
37 var foilHue = Number(o.foilHue) || 0;
38 var foilSat = Number(o.foilSaturation) || 80;
39 var cardRadius = Number(o.cardRadius) || 20;
40 var cardBg = o.cardBg || '#1a1035';
41 var titleColor = o.titleColor || '#ffffff';
42 var subtitleColor = o.subtitleColor || 'rgba(255,255,255,0.7)';
43 var badgeBg = o.badgeBg || 'rgba(255,255,255,0.15)';
44 var badgeColor = o.badgeColor || '#ffffff';
45 var linkBg = o.linkBg || 'rgba(255,255,255,0.15)';
46 var linkColor = o.linkColor || '#ffffff';
47
48 // Apply colour tokens
49 card.style.background = cardBg;
50 card.style.borderRadius = cardRadius + 'px';
51
52 /* typo CSS vars on card */
53 typoCssVarsForEl(o.titleTypo, '--bkbg-hgc-tt-', card);
54 typoCssVarsForEl(o.subtitleTypo, '--bkbg-hgc-st-', card);
55
56 var shineEl = card.querySelector('.bkbg-hgc-shine');
57 var glareEl = card.querySelector('.bkbg-hgc-glare');
58 var badgeEl = card.querySelector('.bkbg-hgc-badge');
59 var titleEl = card.querySelector('.bkbg-hgc-title');
60 var subtitleEl = card.querySelector('.bkbg-hgc-subtitle');
61 var linkEl = card.querySelector('.bkbg-hgc-link');
62
63 if (shineEl) shineEl.style.opacity = shineOpacity / 100;
64 if (glareEl) glareEl.style.setProperty('--bkbg-hgc-glare-opacity', glareOpacity / 100);
65 if (badgeEl) { badgeEl.style.background = badgeBg; badgeEl.style.color = badgeColor; }
66 if (titleEl) titleEl.style.color = titleColor;
67 if (subtitleEl) subtitleEl.style.color = subtitleColor;
68 if (linkEl) { linkEl.style.background = linkBg; linkEl.style.color = linkColor; }
69
70 // Build shine gradient function
71 function shineGradient(hueShift) {
72 var h = foilHue + hueShift;
73 return 'linear-gradient(135deg,' +
74 'hsl(' + (h + 0) + ',' + foilSat + '%,60%) 0%,' +
75 'hsl(' + (h + 60) + ',' + foilSat + '%,70%) 16%,' +
76 'hsl(' + (h + 120) + ',' + foilSat + '%,65%) 33%,' +
77 'hsl(' + (h + 180) + ',' + foilSat + '%,65%) 50%,' +
78 'hsl(' + (h + 240) + ',' + foilSat + '%,65%) 66%,' +
79 'hsl(' + (h + 300) + ',' + foilSat + '%,65%) 83%,' +
80 'hsl(' + (h + 360) + ',' + foilSat + '%,60%) 100%)';
81 }
82
83 var raf = null;
84 var targetRX = 0, targetRY = 0, currentRX = 0, currentRY = 0;
85 var targetBX = 50, targetBY = 50, currentBX = 50, currentBY = 50;
86 var hueShift = 0;
87 var inside = false;
88
89 function lerp(a, b, t) { return a + (b - a) * t; }
90
91 function animate() {
92 currentRX = lerp(currentRX, targetRX, 0.12);
93 currentRY = lerp(currentRY, targetRY, 0.12);
94 currentBX = lerp(currentBX, targetBX, 0.1);
95 currentBY = lerp(currentBY, targetBY, 0.1);
96
97 card.style.transform = 'perspective(800px) rotateX(' + currentRX + 'deg) rotateY(' + currentRY + 'deg) scale3d(1.02,1.02,1.02)';
98
99 if (shineEl) {
100 hueShift = currentBX * 0.8;
101 shineEl.style.background = shineGradient(hueShift);
102 shineEl.style.backgroundPosition = currentBX + '% ' + currentBY + '%';
103 }
104 if (glareEl) {
105 glareEl.style.background = 'radial-gradient(circle at ' + currentBX + '% ' + currentBY + '%, rgba(255,255,255,0.55) 0%, transparent 55%)';
106 glareEl.style.opacity = inside ? (glareOpacity / 100) * (Math.abs(currentRX) + Math.abs(currentRY)) / tiltStrength : 0;
107 }
108
109 if (inside ||
110 Math.abs(currentRX) > 0.05 ||
111 Math.abs(currentRY) > 0.05) {
112 raf = requestAnimationFrame(animate);
113 } else {
114 card.style.transform = '';
115 raf = null;
116 }
117 }
118
119 card.addEventListener('mousemove', function (e) {
120 var rect = card.getBoundingClientRect();
121 var x = (e.clientX - rect.left) / rect.width;
122 var y = (e.clientY - rect.top) / rect.height;
123
124 targetRY = (x - 0.5) * 2 * tiltStrength;
125 targetRX = -(y - 0.5) * 2 * tiltStrength;
126 targetBX = x * 100;
127 targetBY = y * 100;
128
129 if (!raf) {
130 inside = true;
131 raf = requestAnimationFrame(animate);
132 }
133 });
134
135 card.addEventListener('mouseenter', function () {
136 inside = true;
137 });
138
139 card.addEventListener('mouseleave', function () {
140 inside = false;
141 targetRX = 0;
142 targetRY = 0;
143 targetBX = 50;
144 targetBY = 50;
145 if (!raf) raf = requestAnimationFrame(animate);
146 });
147
148 // Touch tilt (passive)
149 card.addEventListener('touchmove', function (e) {
150 var t = e.touches[0];
151 var rect = card.getBoundingClientRect();
152 var x = (t.clientX - rect.left) / rect.width;
153 var y = (t.clientY - rect.top) / rect.height;
154 targetRY = (x - 0.5) * 2 * (tiltStrength * 0.6);
155 targetRX = -(y - 0.5) * 2 * (tiltStrength * 0.6);
156 if (!raf) { inside = true; raf = requestAnimationFrame(animate); }
157 }, { passive: true });
158
159 card.addEventListener('touchend', function () {
160 inside = false;
161 targetRX = 0; targetRY = 0;
162 if (!raf) raf = requestAnimationFrame(animate);
163 });
164
165 // Respect reduced-motion
166 if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
167 card.style.removeProperty('transform');
168 }
169 }
170
171 function init() {
172 document.querySelectorAll('.wp-block-blockenberg-holographic-card').forEach(initBlock);
173 }
174
175 if (document.readyState === 'loading') {
176 document.addEventListener('DOMContentLoaded', init);
177 } else {
178 init();
179 }
180 })();
181