PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.13
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.13
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 / hovering-image-stack / frontend.js

frontend.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.13, at blocks/hovering-image-stack/frontend.js

153 lines 7.1 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 var reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
27
28 /* ── Compute transform per card ──────────────────────────────────── */
29 function getTransform(idx, total, spreadAngle, spreadDist, hovered) {
30 var mid = (total - 1) / 2;
31 var diff = idx - mid;
32 var angle = diff * spreadAngle;
33 var tx = diff * 18;
34 var ty = Math.abs(diff) * 4;
35 var scale = 1 - Math.abs(diff) * 0.03;
36 if (hovered) {
37 tx = diff * spreadDist;
38 angle = 0;
39 ty = 0;
40 scale = 1;
41 }
42 return 'translateX(' + tx + 'px) translateY(' + ty + 'px) rotate(' + angle + 'deg) scale(' + scale + ')';
43 }
44
45 function initBlock(root) {
46 var app = root.querySelector('.bkbg-his-app');
47 if (!app) return;
48
49 var raw = app.getAttribute('data-opts') || '{}';
50 var o;
51 try { o = JSON.parse(raw); } catch (e) { o = {}; }
52
53 var images = Array.isArray(o.images) ? o.images : [];
54 var imageWidth = Number(o.imageWidth) || 200;
55 var imageHeight = Number(o.imageHeight) || 280;
56 var imageRadius = Number(o.imageRadius) || 16;
57 var spreadAngle = Number(o.spreadAngle) || 15;
58 var spreadDist = Number(o.spreadDist) || 60;
59 var borderWidth = Number(o.borderWidth) || 3;
60 var borderColor = o.borderColor || '#ffffff';
61 var shadowAlpha = (Number(o.shadowStrength) / 100 || 0.3).toFixed(2);
62 var showCaption = !!o.showCaption;
63 var captionSize = Number(o.captionSize) || 13;
64 var captionColor = o.captionColor || '#0f172a';
65 var captionBg = o.captionBg || '#ffffff';
66 var bgColor = o.bgColor || 'transparent';
67
68 if (images.length === 0) return;
69
70 /* typography CSS vars */
71 typoCssVarsForEl(o.captionTypo, '--bkbg-his-cap-', root);
72 if (captionSize && captionSize !== 13) root.style.setProperty('--bkbg-his-cap-sz', captionSize + 'px');
73
74 /* ── Outer wrapper ─────────────────────────────────────────── */
75 var outer = document.createElement('div');
76 outer.className = 'bkbg-his-outer';
77 outer.style.background = bgColor;
78
79 /* ── Stack ──────────────────────────────────────────────────── */
80 var stack = document.createElement('div');
81 stack.className = 'bkbg-his-stack';
82 var total = images.length;
83 var mid = (total - 1) / 2;
84 stack.style.height = imageHeight + 'px';
85 stack.style.minWidth = (imageWidth + total * Math.max(spreadDist, 30)) + 'px';
86
87 var cards = images.map(function (img, i) {
88 var card = document.createElement('div');
89 card.className = 'bkbg-his-card';
90 card.style.cssText = [
91 'width:' + imageWidth + 'px',
92 'height:' + imageHeight + 'px',
93 'border-radius:' + imageRadius + 'px',
94 'border:' + borderWidth + 'px solid ' + borderColor,
95 'box-shadow:0 8px 32px rgba(0,0,0,' + shadowAlpha + ')',
96 'z-index:' + i,
97 'transform:' + getTransform(i, total, spreadAngle, 0, false)
98 ].join(';');
99
100 var imgEl = document.createElement('img');
101 imgEl.src = img.url || '';
102 imgEl.alt = img.alt || '';
103 imgEl.loading = 'lazy';
104 imgEl.style.cssText = 'width:100%;height:100%;object-fit:cover;display:block;pointer-events:none';
105 card.appendChild(imgEl);
106
107 if (showCaption && img.caption) {
108 var cap = document.createElement('div');
109 cap.className = 'bkbg-his-caption';
110 cap.textContent = img.caption;
111 cap.style.color = captionColor;
112 cap.style.background = captionBg;
113 card.appendChild(cap);
114 }
115
116 stack.appendChild(card);
117 return card;
118 });
119
120 outer.appendChild(stack);
121 app.appendChild(outer);
122
123 if (reduced) return;
124
125 /* ── Hover interaction ──────────────────────────────────────── */
126 stack.addEventListener('mouseenter', function () {
127 cards.forEach(function (card, i) {
128 card.style.transform = getTransform(i, total, spreadAngle, spreadDist, true);
129 card.style.zIndex = total - i;
130 card.style.boxShadow = '0 12px 40px rgba(0,0,0,' + Math.min(parseFloat(shadowAlpha) * 1.5, 0.6) + ')';
131 });
132 });
133
134 stack.addEventListener('mouseleave', function () {
135 cards.forEach(function (card, i) {
136 card.style.transform = getTransform(i, total, spreadAngle, 0, false);
137 card.style.zIndex = i;
138 card.style.boxShadow = '0 8px 32px rgba(0,0,0,' + shadowAlpha + ')';
139 });
140 });
141 }
142
143 function init() {
144 document.querySelectorAll('.wp-block-blockenberg-hovering-image-stack').forEach(initBlock);
145 }
146
147 if (document.readyState === 'loading') {
148 document.addEventListener('DOMContentLoaded', init);
149 } else {
150 init();
151 }
152 })();
153