| 1 |
(function () { |
| 2 |
'use strict'; |
| 3 |
|
| 4 |
var _typoKeys = { |
| 5 |
family:'font-family', weight:'font-weight', style:'font-style', |
| 6 |
decoration:'text-decoration', transform:'text-transform', |
| 7 |
sizeDesktop:'font-size-d', sizeTablet:'font-size-t', sizeMobile:'font-size-m', |
| 8 |
lineHeightDesktop:'line-height-d', lineHeightTablet:'line-height-t', lineHeightMobile:'line-height-m', |
| 9 |
letterSpacingDesktop:'letter-spacing-d', letterSpacingTablet:'letter-spacing-t', letterSpacingMobile:'letter-spacing-m', |
| 10 |
wordSpacingDesktop:'word-spacing-d', wordSpacingTablet:'word-spacing-t', wordSpacingMobile:'word-spacing-m' |
| 11 |
}; |
| 12 |
function typoCssVarsForEl(el, obj, prefix) { |
| 13 |
if (!obj || typeof obj !== 'object') return; |
| 14 |
Object.keys(_typoKeys).forEach(function (k) { |
| 15 |
var v = obj[k]; |
| 16 |
if (v === undefined || v === '' || v === null) return; |
| 17 |
if (k === 'sizeDesktop' || k === 'sizeTablet' || k === 'sizeMobile') v = v + (obj.sizeUnit || 'px'); |
| 18 |
else if (k === 'lineHeightDesktop' || k === 'lineHeightTablet' || k === 'lineHeightMobile') v = v + (obj.lineHeightUnit || ''); |
| 19 |
else if (k === 'letterSpacingDesktop' || k === 'letterSpacingTablet' || k === 'letterSpacingMobile') v = v + (obj.letterSpacingUnit || 'px'); |
| 20 |
else if (k === 'wordSpacingDesktop' || k === 'wordSpacingTablet' || k === 'wordSpacingMobile') v = v + (obj.wordSpacingUnit || 'px'); |
| 21 |
el.style.setProperty(prefix + _typoKeys[k], String(v)); |
| 22 |
}); |
| 23 |
} |
| 24 |
|
| 25 |
var reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches; |
| 26 |
|
| 27 |
function lerp(a, b, t) { return a + (b - a) * t; } |
| 28 |
|
| 29 |
/* ── Build one card DOM ──────────────────────────────────────────── */ |
| 30 |
function buildCard(card, o) { |
| 31 |
var w = o.cardWidth || 320; |
| 32 |
var h = o.cardHeight || 420; |
| 33 |
var r = o.cardRadius || 24; |
| 34 |
|
| 35 |
var wrap = document.createElement('div'); |
| 36 |
wrap.className = 'bkbg-pdc-card'; |
| 37 |
wrap.style.cssText = [ |
| 38 |
'width:' + w + 'px', |
| 39 |
'height:' + h + 'px', |
| 40 |
'border-radius:' + r + 'px', |
| 41 |
'background:' + (card.bgImage |
| 42 |
? 'url(' + card.bgImage + ') center/cover no-repeat, ' + (card.bgColor || '#1a1035') |
| 43 |
: (card.bgColor || '#1a1035')) |
| 44 |
].join(';'); |
| 45 |
|
| 46 |
/* overlay */ |
| 47 |
var overlay = document.createElement('div'); |
| 48 |
overlay.className = 'bkbg-pdc-overlay'; |
| 49 |
overlay.style.background = o.overlayColor || 'rgba(0,0,0,0.25)'; |
| 50 |
wrap.appendChild(overlay); |
| 51 |
|
| 52 |
/* glow orb */ |
| 53 |
var glow = document.createElement('div'); |
| 54 |
glow.className = 'bkbg-pdc-layer bkbg-pdc-glow'; |
| 55 |
glow.dataset.depth = '1'; |
| 56 |
glow.style.cssText = 'position:absolute;width:180px;height:180px;border-radius:50%' + |
| 57 |
';background:' + (o.glowColor || 'rgba(99,102,241,0.5)') + |
| 58 |
';filter:blur(60px);top:10%;left:60%;pointer-events:none'; |
| 59 |
wrap.appendChild(glow); |
| 60 |
|
| 61 |
/* badge */ |
| 62 |
if (o.showBadge !== false && card.badge) { |
| 63 |
var badge = document.createElement('div'); |
| 64 |
badge.className = 'bkbg-pdc-layer bkbg-pdc-badge'; |
| 65 |
badge.dataset.depth = '2'; |
| 66 |
badge.style.cssText = [ |
| 67 |
'position:absolute', 'top:20px', 'left:20px', |
| 68 |
'background:' + (o.badgeBg || '#6366f1'), |
| 69 |
'color:' + (o.badgeColor || '#ffffff'), |
| 70 |
'font-size:' + (o.badgeFontSize || 11) + 'px', |
| 71 |
'font-weight:700', 'padding:4px 12px', |
| 72 |
'border-radius:99px', 'letter-spacing:0.08em', |
| 73 |
'text-transform:uppercase' |
| 74 |
].join(';'); |
| 75 |
badge.textContent = card.badge; |
| 76 |
wrap.appendChild(badge); |
| 77 |
} |
| 78 |
|
| 79 |
/* icon */ |
| 80 |
if (o.showIcon !== false && card.icon) { |
| 81 |
var icon = document.createElement('div'); |
| 82 |
icon.className = 'bkbg-pdc-layer bkbg-pdc-icon'; |
| 83 |
icon.dataset.depth = '3'; |
| 84 |
icon.style.cssText = 'position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)' + |
| 85 |
';font-size:' + (o.iconSize || 48) + 'px;line-height:1' + |
| 86 |
';filter:drop-shadow(0 8px 24px rgba(0,0,0,0.5))'; |
| 87 |
var _IP = window.bkbgIconPicker; |
| 88 |
var _iType = card.iconType || 'custom-char'; |
| 89 |
if (_IP && _iType !== 'custom-char') { |
| 90 |
var _in = _IP.buildFrontendIcon(_iType, card.icon, card.iconDashicon, card.iconImageUrl, card.iconDashiconColor); |
| 91 |
if (_in) icon.appendChild(_in); else icon.textContent = card.icon; |
| 92 |
} else { icon.textContent = card.icon; } |
| 93 |
wrap.appendChild(icon); |
| 94 |
} |
| 95 |
|
| 96 |
/* content */ |
| 97 |
var content = document.createElement('div'); |
| 98 |
content.className = 'bkbg-pdc-layer bkbg-pdc-content'; |
| 99 |
content.dataset.depth = '1.5'; |
| 100 |
content.style.cssText = 'position:absolute;bottom:0;left:0;right:0;padding:24px' + |
| 101 |
';background:linear-gradient(to top,rgba(0,0,0,0.7) 0%,transparent 100%)'; |
| 102 |
|
| 103 |
if (o.showTag !== false && card.tag) { |
| 104 |
var tag = document.createElement('div'); |
| 105 |
tag.style.cssText = 'display:inline-block;background:' + (o.tagBg || 'rgba(255,255,255,0.15)') + |
| 106 |
';color:' + (o.tagColor || '#ffffff') + |
| 107 |
';font-size:11px;font-weight:600;padding:2px 10px;border-radius:99px;margin-bottom:8px;backdrop-filter:blur(4px)'; |
| 108 |
tag.textContent = card.tag; |
| 109 |
content.appendChild(tag); |
| 110 |
} |
| 111 |
|
| 112 |
var title = document.createElement('div'); |
| 113 |
title.className = 'bkbg-pdc-title'; |
| 114 |
title.style.color = o.titleColor || '#ffffff'; |
| 115 |
title.style.marginBottom = '4px'; |
| 116 |
title.textContent = card.title || ''; |
| 117 |
content.appendChild(title); |
| 118 |
|
| 119 |
var sub = document.createElement('div'); |
| 120 |
sub.className = 'bkbg-pdc-subtitle'; |
| 121 |
sub.style.color = o.subtitleColor || 'rgba(255,255,255,0.7)'; |
| 122 |
sub.textContent = card.subtitle || ''; |
| 123 |
content.appendChild(sub); |
| 124 |
|
| 125 |
wrap.appendChild(content); |
| 126 |
|
| 127 |
return wrap; |
| 128 |
} |
| 129 |
|
| 130 |
/* ── Parallax logic for one card ─────────────────────────────────── */ |
| 131 |
function attachParallax(card, o) { |
| 132 |
if (reduced) return; |
| 133 |
|
| 134 |
var tilt = o.tiltStrength || 20; |
| 135 |
var depth = o.depthStrength || 30; |
| 136 |
|
| 137 |
var currX = 0, currY = 0; |
| 138 |
var targetX = 0, targetY = 0; |
| 139 |
var rafId; |
| 140 |
|
| 141 |
function tick() { |
| 142 |
currX = lerp(currX, targetX, 0.08); |
| 143 |
currY = lerp(currY, targetY, 0.08); |
| 144 |
|
| 145 |
card.style.transform = 'perspective(900px) rotateX(' + (-currY * tilt).toFixed(2) + 'deg) rotateY(' + (currX * tilt).toFixed(2) + 'deg)'; |
| 146 |
|
| 147 |
card.querySelectorAll('.bkbg-pdc-layer[data-depth]').forEach(function (layer) { |
| 148 |
var d = parseFloat(layer.dataset.depth) || 1; |
| 149 |
var tx = (currX * depth * d).toFixed(2); |
| 150 |
var ty = (currY * depth * d).toFixed(2); |
| 151 |
layer.style.transform = 'translate3d(' + tx + 'px,' + ty + 'px, ' + (d * 8) + 'px)'; |
| 152 |
}); |
| 153 |
|
| 154 |
if (Math.abs(currX - targetX) > 0.001 || Math.abs(currY - targetY) > 0.001) { |
| 155 |
rafId = requestAnimationFrame(tick); |
| 156 |
} |
| 157 |
} |
| 158 |
|
| 159 |
card.addEventListener('mousemove', function (e) { |
| 160 |
var rect = card.getBoundingClientRect(); |
| 161 |
targetX = (e.clientX - rect.left - rect.width / 2) / (rect.width / 2); |
| 162 |
targetY = (e.clientY - rect.top - rect.height / 2) / (rect.height / 2); |
| 163 |
cancelAnimationFrame(rafId); |
| 164 |
rafId = requestAnimationFrame(tick); |
| 165 |
}); |
| 166 |
|
| 167 |
card.addEventListener('mouseleave', function () { |
| 168 |
targetX = 0; targetY = 0; |
| 169 |
cancelAnimationFrame(rafId); |
| 170 |
rafId = requestAnimationFrame(tick); |
| 171 |
}); |
| 172 |
} |
| 173 |
|
| 174 |
/* ── Mount ─────────────────────────────────────────────────────── */ |
| 175 |
function initBlock(root) { |
| 176 |
var app = root.querySelector('.bkbg-pdc-app'); |
| 177 |
if (!app) return; |
| 178 |
|
| 179 |
var raw = app.getAttribute('data-opts') || '{}'; |
| 180 |
var o; |
| 181 |
try { o = JSON.parse(raw); } catch (e) { o = {}; } |
| 182 |
|
| 183 |
typoCssVarsForEl(app, o.titleTypo, '--bkbg-pdc-tt-'); |
| 184 |
typoCssVarsForEl(app, o.subtitleTypo, '--bkbg-pdc-st-'); |
| 185 |
|
| 186 |
var cards = Array.isArray(o.cards) ? o.cards : []; |
| 187 |
var cols = Number(o.columns) || 3; |
| 188 |
|
| 189 |
var grid = document.createElement('div'); |
| 190 |
grid.className = 'bkbg-pdc-grid'; |
| 191 |
grid.style.cssText = 'display:flex;flex-wrap:wrap;gap:24px;justify-content:center'; |
| 192 |
|
| 193 |
cards.forEach(function (card) { |
| 194 |
var cardEl = buildCard(card, o); |
| 195 |
attachParallax(cardEl, o); |
| 196 |
grid.appendChild(cardEl); |
| 197 |
}); |
| 198 |
|
| 199 |
app.appendChild(grid); |
| 200 |
} |
| 201 |
|
| 202 |
function init() { |
| 203 |
document.querySelectorAll('.wp-block-blockenberg-parallax-depth-cards').forEach(initBlock); |
| 204 |
} |
| 205 |
|
| 206 |
if (document.readyState === 'loading') { |
| 207 |
document.addEventListener('DOMContentLoaded', init); |
| 208 |
} else { |
| 209 |
init(); |
| 210 |
} |
| 211 |
})(); |
| 212 |
|