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

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

187 lines 8.0 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 hexToRgbStr(hex) {
5 hex = (hex || '#000').replace(/^#/, '');
6 if (hex.length === 3) hex = hex.split('').map(function (c) { return c + c; }).join('');
7 var n = parseInt(hex, 16) || 0;
8 return [(n >> 16) & 255, (n >> 8) & 255, n & 255].join(',');
9 }
10
11 /* ── Typography CSS-var helper ─────────────────────────────────────── */
12 function typoCssVarsForEl(typo, prefix, el) {
13 if (!typo || typeof typo !== 'object') return;
14 var map = {
15 family:'font-family', weight:'font-weight', style:'font-style',
16 transform:'text-transform', decoration:'text-decoration',
17 sizeDesktop:'font-size-d', sizeTablet:'font-size-t', sizeMobile:'font-size-m', sizeUnit:'font-size-unit',
18 lineHeightDesktop:'line-height-d', lineHeightTablet:'line-height-t', lineHeightMobile:'line-height-m', lineHeightUnit:'line-height-unit',
19 letterSpacingDesktop:'letter-spacing-d', letterSpacingTablet:'letter-spacing-t', letterSpacingMobile:'letter-spacing-m', letterSpacingUnit:'letter-spacing-unit',
20 wordSpacingDesktop:'word-spacing-d', wordSpacingTablet:'word-spacing-t', wordSpacingMobile:'word-spacing-m', wordSpacingUnit:'word-spacing-unit'
21 };
22 Object.keys(map).forEach(function(k) {
23 if (typo[k] !== undefined && typo[k] !== '') {
24 var v = typo[k];
25 var css = map[k];
26 if (css.indexOf('size-d') !== -1 || css.indexOf('size-t') !== -1 || css.indexOf('size-m') !== -1 ||
27 css.indexOf('height-d') !== -1 || css.indexOf('height-t') !== -1 || css.indexOf('height-m') !== -1 ||
28 css.indexOf('spacing-d') !== -1 || css.indexOf('spacing-t') !== -1 || css.indexOf('spacing-m') !== -1) {
29 var unitKey = css.replace(/-[dtm]$/, '-unit');
30 var unit = '';
31 Object.keys(map).forEach(function(k2) { if (map[k2] === unitKey && typo[k2]) unit = typo[k2]; });
32 if (!unit) unit = css.indexOf('size') !== -1 ? 'px' : '';
33 v = v + unit;
34 }
35 el.style.setProperty(prefix + css, v);
36 }
37 });
38 }
39
40 function initCursorSpotlight(appEl) {
41 var raw = appEl.dataset.opts;
42 if (!raw) return;
43 var opts;
44 try { opts = JSON.parse(raw); } catch (e) { return; }
45
46 var spotR = opts.spotlightSize || 280;
47 var blur = opts.spotlightBlur || 40;
48 var dimRgb = hexToRgbStr(opts.dimColor || '#000000');
49 var dimA = opts.dimOpacity || 0.92;
50 var bgColor = opts.bgColor || '#0c0a1e';
51 var smooth = opts.followSmooth !== false;
52 var idleMode = opts.idleMode || 'center';
53
54 // ── Build section ─────────────────────────────────────────────
55 var section = document.createElement('div');
56 section.className = 'bkbg-cs-section';
57 section.style.height = (opts.sectionHeight || 500) + 'px';
58 section.style.borderRadius = (opts.borderRadius || 16) + 'px';
59 section.style.backgroundColor = bgColor;
60 section.style.overflow = 'hidden';
61 section.style.position = 'relative';
62
63 // BG image
64 if (opts.bgImage) {
65 var bgImg = document.createElement('img');
66 bgImg.src = opts.bgImage;
67 bgImg.className = 'bkbg-cs-bg';
68 bgImg.alt = '';
69 bgImg.style.opacity = opts.bgImageOpacity || 0.5;
70 section.appendChild(bgImg);
71 }
72
73 // Dim overlay
74 var dim = document.createElement('div');
75 dim.className = 'bkbg-cs-dim';
76 section.appendChild(dim);
77
78 // Content
79 var content = document.createElement('div');
80 content.className = 'bkbg-cs-content';
81 content.style.textAlign = opts.textAlign || 'center';
82 content.style.color = opts.textColor || '#ffffff';
83
84 var heading = document.createElement(opts.tag || 'h2');
85 heading.className = 'bkbg-cs-heading';
86 heading.style.color = opts.textColor || '#ffffff';
87 heading.textContent = opts.heading || 'Move your cursor to reveal';
88 content.appendChild(heading);
89
90 if (opts.subtext) {
91 var sub = document.createElement('p');
92 sub.className = 'bkbg-cs-subtext';
93 sub.textContent = opts.subtext;
94 sub.style.color = opts.textColor || '#ffffff';
95 content.appendChild(sub);
96 }
97
98 section.appendChild(content);
99
100 if (opts.showHint) {
101 var hint = document.createElement('div');
102 hint.className = 'bkbg-cs-hint';
103 hint.style.color = opts.accentColor || '#a78bfa';
104 hint.textContent = opts.hintText || 'Move cursor to reveal';
105 section.appendChild(hint);
106 }
107
108 // Custom cursor dot
109 var dot = document.createElement('div');
110 dot.className = 'bkbg-cs-cursor-dot';
111 dot.style.display = 'none';
112 section.appendChild(dot);
113
114 appEl.parentNode.replaceChild(section, appEl);
115
116 /* Apply typography CSS vars on section */
117 section.style.setProperty('--bkbg-cs-hdg-fs', (opts.fontSize || 48) + 'px');
118 section.style.setProperty('--bkbg-cs-hdg-fw', opts.fontWeight || '800');
119 section.style.setProperty('--bkbg-cs-sub-fs', (opts.subtextSize || 18) + 'px');
120 typoCssVarsForEl(opts.typoHeading, '--bkbg-cs-hdg-', section);
121 typoCssVarsForEl(opts.typoSubtext, '--bkbg-cs-sub-', section);
122
123 // ── Spotlight position ────────────────────────────────────────
124 var mx = -9999, my = -9999;
125 var cx = -9999, cy = -9999;
126
127 function buildMask(x, y) {
128 if (idleMode === 'full' && x < 0) {
129 return 'none';
130 }
131 if (idleMode === 'dark' && x < 0) {
132 return 'radial-gradient(circle 0px at 50% 50%, transparent 0%, rgba(' + dimRgb + ',' + dimA + ') 1px)';
133 }
134 var px = x < 0 ? '50%' : x + 'px';
135 var py = y < 0 ? '50%' : y + 'px';
136 return 'radial-gradient(circle ' + spotR + 'px at ' + px + ' ' + py + ', transparent 0%, rgba(' + dimRgb + ',' + dimA + ') ' + (spotR + blur) + 'px)';
137 }
138
139 function applyDim(x, y) {
140 dim.style.background = buildMask(x, y);
141 dot.style.left = x + 'px';
142 dot.style.top = y + 'px';
143 }
144
145 // Initial idle state
146 applyDim(-1, -1);
147
148 var raf;
149 if (smooth) {
150 function lerp(a, b, t) { return a + (b - a) * t; }
151 function loop() {
152 cx = lerp(cx < -1000 ? mx : cx, mx, 0.15);
153 cy = lerp(cy < -1000 ? my : cy, my, 0.15);
154 applyDim(cx, cy);
155 raf = requestAnimationFrame(loop);
156 }
157 raf = requestAnimationFrame(loop);
158 }
159
160 section.addEventListener('mouseenter', function () {
161 section.classList.add('bkbg-cs-active');
162 dot.style.display = 'block';
163 });
164
165 section.addEventListener('mouseleave', function () {
166 section.classList.remove('bkbg-cs-active');
167 dot.style.display = 'none';
168 mx = -1; my = -1;
169 if (!smooth) applyDim(-1, -1);
170 });
171
172 section.addEventListener('mousemove', function (e) {
173 var rect = section.getBoundingClientRect();
174 mx = e.clientX - rect.left;
175 my = e.clientY - rect.top;
176 if (!smooth) applyDim(mx, my);
177 });
178 }
179
180 document.addEventListener('DOMContentLoaded', function () {
181 document.querySelectorAll('.bkbg-cs-app').forEach(initCursorSpotlight);
182 });
183 if (document.readyState === 'complete' || document.readyState === 'interactive') {
184 document.querySelectorAll('.bkbg-cs-app').forEach(initCursorSpotlight);
185 }
186 })();
187