# blockenberg/2.0.7/blocks/cursor-spotlight/frontend.js

Blockenberg — 600+ Advanced Gutenberg Blocks &amp; AI Agent for WordPress Block Editor, version 2.0.7. 187 lines.

- Page: https://pluginprobe.com/plugins/blockenberg/2.0.7/code/blocks/cursor-spotlight/frontend.js
- Raw: https://pluginprobe.com/plugins/blockenberg/2.0.7/raw/blocks/cursor-spotlight/frontend.js
- Modified: 2026-03-06T12:32:40+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/blockenberg/2.0.7/code/blocks/cursor-spotlight/frontend.js#L10-L20`.

```javascript
(function () {
    'use strict';

    function hexToRgbStr(hex) {
        hex = (hex || '#000').replace(/^#/, '');
        if (hex.length === 3) hex = hex.split('').map(function (c) { return c + c; }).join('');
        var n = parseInt(hex, 16) || 0;
        return [(n >> 16) & 255, (n >> 8) & 255, n & 255].join(',');
    }

    /* ── Typography CSS-var helper ─────────────────────────────────────── */
    function typoCssVarsForEl(typo, prefix, el) {
        if (!typo || typeof typo !== 'object') return;
        var map = {
            family:'font-family', weight:'font-weight', style:'font-style',
            transform:'text-transform', decoration:'text-decoration',
            sizeDesktop:'font-size-d', sizeTablet:'font-size-t', sizeMobile:'font-size-m', sizeUnit:'font-size-unit',
            lineHeightDesktop:'line-height-d', lineHeightTablet:'line-height-t', lineHeightMobile:'line-height-m', lineHeightUnit:'line-height-unit',
            letterSpacingDesktop:'letter-spacing-d', letterSpacingTablet:'letter-spacing-t', letterSpacingMobile:'letter-spacing-m', letterSpacingUnit:'letter-spacing-unit',
            wordSpacingDesktop:'word-spacing-d', wordSpacingTablet:'word-spacing-t', wordSpacingMobile:'word-spacing-m', wordSpacingUnit:'word-spacing-unit'
        };
        Object.keys(map).forEach(function(k) {
            if (typo[k] !== undefined && typo[k] !== '') {
                var v = typo[k];
                var css = map[k];
                if (css.indexOf('size-d') !== -1 || css.indexOf('size-t') !== -1 || css.indexOf('size-m') !== -1 ||
                    css.indexOf('height-d') !== -1 || css.indexOf('height-t') !== -1 || css.indexOf('height-m') !== -1 ||
                    css.indexOf('spacing-d') !== -1 || css.indexOf('spacing-t') !== -1 || css.indexOf('spacing-m') !== -1) {
                    var unitKey = css.replace(/-[dtm]$/, '-unit');
                    var unit = '';
                    Object.keys(map).forEach(function(k2) { if (map[k2] === unitKey && typo[k2]) unit = typo[k2]; });
                    if (!unit) unit = css.indexOf('size') !== -1 ? 'px' : '';
                    v = v + unit;
                }
                el.style.setProperty(prefix + css, v);
            }
        });
    }

    function initCursorSpotlight(appEl) {
        var raw = appEl.dataset.opts;
        if (!raw) return;
        var opts;
        try { opts = JSON.parse(raw); } catch (e) { return; }

        var spotR   = opts.spotlightSize  || 280;
        var blur    = opts.spotlightBlur  || 40;
        var dimRgb  = hexToRgbStr(opts.dimColor  || '#000000');
        var dimA    = opts.dimOpacity      || 0.92;
        var bgColor = opts.bgColor         || '#0c0a1e';
        var smooth  = opts.followSmooth !== false;
        var idleMode = opts.idleMode || 'center';

        // ── Build section ─────────────────────────────────────────────
        var section = document.createElement('div');
        section.className = 'bkbg-cs-section';
        section.style.height = (opts.sectionHeight || 500) + 'px';
        section.style.borderRadius = (opts.borderRadius || 16) + 'px';
        section.style.backgroundColor = bgColor;
        section.style.overflow = 'hidden';
        section.style.position = 'relative';

        // BG image
        if (opts.bgImage) {
            var bgImg = document.createElement('img');
            bgImg.src = opts.bgImage;
            bgImg.className = 'bkbg-cs-bg';
            bgImg.alt = '';
            bgImg.style.opacity = opts.bgImageOpacity || 0.5;
            section.appendChild(bgImg);
        }

        // Dim overlay
        var dim = document.createElement('div');
        dim.className = 'bkbg-cs-dim';
        section.appendChild(dim);

        // Content
        var content = document.createElement('div');
        content.className = 'bkbg-cs-content';
        content.style.textAlign = opts.textAlign || 'center';
        content.style.color = opts.textColor || '#ffffff';

        var heading = document.createElement(opts.tag || 'h2');
        heading.className = 'bkbg-cs-heading';
        heading.style.color = opts.textColor || '#ffffff';
        heading.textContent = opts.heading || 'Move your cursor to reveal';
        content.appendChild(heading);

        if (opts.subtext) {
            var sub = document.createElement('p');
            sub.className = 'bkbg-cs-subtext';
            sub.textContent = opts.subtext;
            sub.style.color = opts.textColor || '#ffffff';
            content.appendChild(sub);
        }

        section.appendChild(content);

        if (opts.showHint) {
            var hint = document.createElement('div');
            hint.className = 'bkbg-cs-hint';
            hint.style.color = opts.accentColor || '#a78bfa';
            hint.textContent = opts.hintText || 'Move cursor to reveal';
            section.appendChild(hint);
        }

        // Custom cursor dot
        var dot = document.createElement('div');
        dot.className = 'bkbg-cs-cursor-dot';
        dot.style.display = 'none';
        section.appendChild(dot);

        appEl.parentNode.replaceChild(section, appEl);

        /* Apply typography CSS vars on section */
        section.style.setProperty('--bkbg-cs-hdg-fs', (opts.fontSize || 48) + 'px');
        section.style.setProperty('--bkbg-cs-hdg-fw', opts.fontWeight || '800');
        section.style.setProperty('--bkbg-cs-sub-fs', (opts.subtextSize || 18) + 'px');
        typoCssVarsForEl(opts.typoHeading, '--bkbg-cs-hdg-', section);
        typoCssVarsForEl(opts.typoSubtext, '--bkbg-cs-sub-', section);

        // ── Spotlight position ────────────────────────────────────────
        var mx = -9999, my = -9999;
        var cx = -9999, cy = -9999;

        function buildMask(x, y) {
            if (idleMode === 'full' && x < 0) {
                return 'none';
            }
            if (idleMode === 'dark' && x < 0) {
                return 'radial-gradient(circle 0px at 50% 50%, transparent 0%, rgba(' + dimRgb + ',' + dimA + ') 1px)';
            }
            var px = x < 0 ? '50%' : x + 'px';
            var py = y < 0 ? '50%' : y + 'px';
            return 'radial-gradient(circle ' + spotR + 'px at ' + px + ' ' + py + ', transparent 0%, rgba(' + dimRgb + ',' + dimA + ') ' + (spotR + blur) + 'px)';
        }

        function applyDim(x, y) {
            dim.style.background = buildMask(x, y);
            dot.style.left = x + 'px';
            dot.style.top  = y + 'px';
        }

        // Initial idle state
        applyDim(-1, -1);

        var raf;
        if (smooth) {
            function lerp(a, b, t) { return a + (b - a) * t; }
            function loop() {
                cx = lerp(cx < -1000 ? mx : cx, mx, 0.15);
                cy = lerp(cy < -1000 ? my : cy, my, 0.15);
                applyDim(cx, cy);
                raf = requestAnimationFrame(loop);
            }
            raf = requestAnimationFrame(loop);
        }

        section.addEventListener('mouseenter', function () {
            section.classList.add('bkbg-cs-active');
            dot.style.display = 'block';
        });

        section.addEventListener('mouseleave', function () {
            section.classList.remove('bkbg-cs-active');
            dot.style.display = 'none';
            mx = -1; my = -1;
            if (!smooth) applyDim(-1, -1);
        });

        section.addEventListener('mousemove', function (e) {
            var rect = section.getBoundingClientRect();
            mx = e.clientX - rect.left;
            my = e.clientY - rect.top;
            if (!smooth) applyDim(mx, my);
        });
    }

    document.addEventListener('DOMContentLoaded', function () {
        document.querySelectorAll('.bkbg-cs-app').forEach(initCursorSpotlight);
    });
    if (document.readyState === 'complete' || document.readyState === 'interactive') {
        document.querySelectorAll('.bkbg-cs-app').forEach(initCursorSpotlight);
    }
})();

```
