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 / morphing-text / frontend.js

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

168 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 var _typoKeys = {
5 family:'font-family', weight:'font-weight', style:'font-style',
6 transform:'text-transform', decoration:'text-decoration',
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 var _typoUnits = { size:'sizeUnit', lineHeight:'lineHeightUnit', letterSpacing:'letterSpacingUnit', wordSpacing:'wordSpacingUnit' };
13 var _typoUnitDefaults = { size:'px', lineHeight:'', letterSpacing:'px', wordSpacing:'px' };
14 function typoCssVarsForEl(el, obj, prefix) {
15 if (!obj || typeof obj !== 'object') return;
16 Object.keys(_typoKeys).forEach(function (k) {
17 var v = obj[k]; if (v === undefined || v === '') return;
18 var prop = _typoKeys[k];
19 var base = k.replace(/Desktop|Tablet|Mobile/, '');
20 var uKey = _typoUnits[base];
21 if (uKey && typeof v === 'number') v = v + (obj[uKey] || _typoUnitDefaults[base] || '');
22 el.style.setProperty(prefix + prop, v);
23 });
24 }
25
26 function initMorphingText(appEl) {
27 var raw = appEl.dataset.opts;
28 if (!raw) return;
29 var opts;
30 try { opts = JSON.parse(raw); } catch (e) { return; }
31
32 var words = (opts.words && opts.words.length) ? opts.words : ['animate'];
33 var mode = opts.morphMode || 'blur';
34 var totalDur = opts.duration || 2500;
35 var pause = opts.pauseDuration || 1500;
36 var loop = opts.loop !== false;
37 var useGrad = opts.useGradient !== false;
38
39 // ── Build outer ───────────────────────────────────────────────
40 var wrap = document.createElement('div');
41 wrap.className = 'bkbg-mt-wrap';
42 wrap.style.padding = (opts.paddingV || 32) + 'px ' + (opts.paddingH || 24) + 'px';
43 wrap.style.backgroundColor = opts.showBg ? (opts.bgColor || '#fff') : '';
44 wrap.style.borderRadius = (opts.borderRadius || 0) + 'px';
45 wrap.style.textAlign = opts.textAlign || 'center';
46
47 var heading = document.createElement(opts.tag || 'h2');
48 heading.className = 'bkbg-mt-heading';
49 heading.style.margin = '0';
50 heading.style.color = opts.staticColor || '#1e293b';
51
52 // Static before
53 if (opts.staticBefore) {
54 var before = document.createElement('span');
55 before.textContent = opts.staticBefore;
56 heading.appendChild(before);
57 }
58
59 // Morphing word
60 var morphSpan = document.createElement('span');
61 morphSpan.className = 'bkbg-mt-morph-word';
62 morphSpan.style.marginLeft = '0.3em';
63 if (useGrad) {
64 morphSpan.classList.add('bkbg-mt-gradient');
65 morphSpan.style.background = 'linear-gradient(90deg,' + (opts.morphColor || '#7c3aed') + ',' + (opts.morphColor2 || '#ec4899') + ')';
66 } else {
67 morphSpan.style.color = opts.morphColor || '#7c3aed';
68 }
69 morphSpan.textContent = words[0];
70 heading.appendChild(morphSpan);
71
72 // Static after
73 if (opts.staticAfter) {
74 var after = document.createElement('span');
75 after.textContent = ' ' + opts.staticAfter;
76 heading.appendChild(after);
77 }
78
79 // Cursor
80 if (opts.cursor) {
81 var effSize = (opts.headingTypo && opts.headingTypo.sizeDesktop) || opts.fontSize || 56;
82 var cursor = document.createElement('span');
83 cursor.className = 'bkbg-mt-cursor';
84 cursor.style.height = effSize * 0.8 + 'px';
85 cursor.style.marginLeft = '4px';
86 heading.appendChild(cursor);
87 }
88
89 wrap.appendChild(heading);
90 appEl.parentNode.replaceChild(wrap, appEl);
91
92 // Set typography CSS vars on the blockProps wrapper
93 typoCssVarsForEl(wrap.parentNode, opts.headingTypo, '--bkbg-mrt-hd-');
94
95 // ── Animation ─────────────────────────────────────────────────
96 var idx = 0;
97
98 function outClass() {
99 if (mode === 'crossfade') return 'bkbg-mt-out-fade';
100 if (mode === 'slide-up') return 'bkbg-mt-out-slideup';
101 if (mode === 'slide-down')return 'bkbg-mt-out-slidedown';
102 return 'bkbg-mt-out-blur';
103 }
104 function inClass() {
105 if (mode === 'crossfade') return 'bkbg-mt-in-fade';
106 if (mode === 'slide-up') return 'bkbg-mt-in-slideup';
107 if (mode === 'slide-down')return 'bkbg-mt-in-slidedown';
108 return 'bkbg-mt-in-blur';
109 }
110
111 function typeWriter(text, done) {
112 morphSpan.textContent = '';
113 var i = 0;
114 var interval = setInterval(function () {
115 morphSpan.textContent += text[i];
116 i++;
117 if (i >= text.length) { clearInterval(interval); setTimeout(done, pause); }
118 }, totalDur / (text.length + 1));
119 }
120
121 function next() {
122 idx = (idx + 1) % words.length;
123 if (!loop && idx === 0) return;
124
125 if (mode === 'typewriter') {
126 // erase then type
127 var current = morphSpan.textContent;
128 var j = current.length;
129 var erase = setInterval(function () {
130 morphSpan.textContent = current.slice(0, j--);
131 if (j < 0) { clearInterval(erase); typeWriter(words[idx], next); }
132 }, Math.max(30, totalDur / (current.length + 1) * 0.5));
133 return;
134 }
135
136 // transition out
137 var oc = outClass();
138 morphSpan.classList.remove(inClass());
139 morphSpan.classList.add(oc);
140
141 var transitionDur = 380;
142 setTimeout(function () {
143 morphSpan.textContent = words[idx];
144 morphSpan.classList.remove(oc);
145 // Force reflow
146 void morphSpan.offsetWidth;
147 morphSpan.classList.add(inClass());
148 setTimeout(next, pause + totalDur);
149 }, transitionDur);
150 }
151
152 if (mode === 'typewriter') {
153 morphSpan.classList.add(inClass());
154 setTimeout(next, pause);
155 } else {
156 morphSpan.classList.add(inClass());
157 setTimeout(next, pause + totalDur);
158 }
159 }
160
161 document.addEventListener('DOMContentLoaded', function () {
162 document.querySelectorAll('.bkbg-mt-app').forEach(initMorphingText);
163 });
164 if (document.readyState === 'complete' || document.readyState === 'interactive') {
165 document.querySelectorAll('.bkbg-mt-app').forEach(initMorphingText);
166 }
167 })();
168