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 / interactive-image-sheen / frontend.js

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

169 lines 6.5 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 var typoMap = [
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(typo, prefix, el) {
13 if (!typo || typeof typo !== 'object') return;
14 for (var i = 0; i < typoMap.length; i++) {
15 var v = typo[typoMap[i][0]];
16 if (v !== undefined && v !== '' && v !== null) el.style.setProperty(prefix + typoMap[i][1], String(v));
17 }
18 }
19
20 function lerp(a, b, t) { return a + (b - a) * t; }
21
22 document.querySelectorAll('.bkbg-iis-app').forEach(function (app) {
23 var o;
24 try { o = JSON.parse(app.dataset.opts || '{}'); } catch (e) { return; }
25
26 var imageUrl = o.imageUrl || '';
27 var imageAlt = o.imageAlt || '';
28 var imageWidth = o.imageWidth || 480;
29 var imageHeight = o.imageHeight || 320;
30 var imageRadius = o.imageRadius || 20;
31 var sheenColor = o.sheenColor || 'rgba(255,255,255,0.35)';
32 var sheenSize = o.sheenSize || 60;
33 var sheenBlur = o.sheenBlur || 40;
34 var tiltStrength = o.tiltStrength || 12;
35 var tiltShadow = !!o.tiltShadow;
36 var shadowColor = o.shadowColor || 'rgba(99,102,241,0.4)';
37 var showCaption = !!o.showCaption;
38 var caption = o.caption || '';
39 var captionSize = o.captionSize || 14;
40 var captionColor = o.captionColor || '#64748b';
41 var align2 = o.align2 || 'center';
42 var bgColor = o.bgColor || '';
43
44 var reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
45
46 var justifyMap = { left: 'flex-start', center: 'center', right: 'flex-end' };
47
48 if (bgColor) app.style.background = bgColor;
49 typoCssVarsForEl(o.captionTypo, '--bkbg-iis-cp-', app);
50
51 /* ── Scene wrapper ── */
52 var scene = document.createElement('div');
53 scene.className = 'bkbg-iis-scene';
54 scene.style.justifyContent = justifyMap[align2] || 'center';
55 if (bgColor) scene.style.padding = '32px';
56
57 var wrap = document.createElement('div');
58 wrap.style.maxWidth = imageWidth + 'px';
59 wrap.style.width = '100%';
60
61 /* ── Card ── */
62 var card = document.createElement('div');
63 card.className = 'bkbg-iis-card';
64 card.style.width = '100%';
65 card.style.height = imageHeight + 'px';
66 card.style.borderRadius = imageRadius + 'px';
67 card.style.perspective = '900px';
68
69 /* Image or placeholder */
70 if (imageUrl) {
71 var img = document.createElement('img');
72 img.className = 'bkbg-iis-img';
73 img.src = imageUrl;
74 img.alt = imageAlt;
75 img.style.borderRadius = imageRadius + 'px';
76 card.appendChild(img);
77 } else {
78 var ph = document.createElement('div');
79 ph.className = 'bkbg-iis-placeholder';
80 ph.style.width = '100%';
81 ph.style.height = imageHeight + 'px';
82 ph.style.borderRadius = imageRadius + 'px';
83 ph.textContent = 'No image selected';
84 card.appendChild(ph);
85 }
86
87 /* Sheen overlay */
88 var sheen = document.createElement('div');
89 sheen.className = 'bkbg-iis-sheen';
90 var sheenPx = Math.round(Math.min(imageWidth, imageHeight) * sheenSize / 100);
91 sheen.style.width = sheenPx + 'px';
92 sheen.style.height = sheenPx + 'px';
93 sheen.style.background = 'radial-gradient(circle, ' + sheenColor + ' 0%, transparent 70%)';
94 sheen.style.filter = 'blur(' + sheenBlur + 'px)';
95 card.appendChild(sheen);
96
97 wrap.appendChild(card);
98
99 /* Caption */
100 if (showCaption && caption) {
101 var cap = document.createElement('p');
102 cap.className = 'bkbg-iis-caption';
103 cap.style.color = captionColor;
104 cap.textContent = caption;
105 wrap.appendChild(cap);
106 }
107
108 scene.appendChild(wrap);
109 app.appendChild(scene);
110
111 if (reducedMotion) return;
112
113 /* ── Interaction ── */
114 var targetRX = 0, targetRY = 0;
115 var currentRX = 0, currentRY = 0;
116 var sheenX = 50, sheenY = 50;
117 var rafId = null;
118
119 function tick() {
120 currentRX = lerp(currentRX, targetRX, 0.1);
121 currentRY = lerp(currentRY, targetRY, 0.1);
122
123 card.style.transform = 'perspective(900px) rotateX(' + currentRX + 'deg) rotateY(' + currentRY + 'deg)';
124
125 if (tiltShadow) {
126 var sdx = -currentRY * 0.5;
127 var sdy = currentRX * 0.5;
128 card.style.boxShadow = sdx + 'px ' + (sdy + 16) + 'px 40px ' + shadowColor;
129 }
130
131 sheen.style.left = sheenX + '%';
132 sheen.style.top = sheenY + '%';
133
134 if (Math.abs(currentRX - targetRX) > 0.01 || Math.abs(currentRY - targetRY) > 0.01) {
135 rafId = requestAnimationFrame(tick);
136 } else {
137 rafId = null;
138 }
139 }
140
141 function startTick() {
142 if (!rafId) rafId = requestAnimationFrame(tick);
143 }
144
145 card.addEventListener('mousemove', function (e) {
146 var rect = card.getBoundingClientRect();
147 var nx = (e.clientX - rect.left) / rect.width - 0.5; /* -0.5 to 0.5 */
148 var ny = (e.clientY - rect.top) / rect.height - 0.5;
149
150 targetRY = nx * tiltStrength;
151 targetRX = -ny * tiltStrength;
152 sheenX = (e.clientX - rect.left) / rect.width * 100;
153 sheenY = (e.clientY - rect.top) / rect.height * 100;
154
155 card.classList.add('bkbg-iis-active');
156 startTick();
157 });
158
159 card.addEventListener('mouseleave', function () {
160 targetRX = 0;
161 targetRY = 0;
162 sheenX = 50;
163 sheenY = 50;
164 card.classList.remove('bkbg-iis-active');
165 startTick();
166 });
167 });
168 }());
169