| 1 |
(function () { |
| 2 |
'use strict'; |
| 3 |
|
| 4 |
function buildGradient(opts) { |
| 5 |
var colors = [opts.color1 || '#f59e0b', opts.color2 || '#ec4899']; |
| 6 |
var stop = opts.stopCount || 4; |
| 7 |
if (stop >= 3) colors.push(opts.color3 || '#8b5cf6'); |
| 8 |
if (stop >= 4) colors.push(opts.color4 || '#06b6d4'); |
| 9 |
|
| 10 |
var dir = opts.direction; |
| 11 |
if (dir === 'radial') { |
| 12 |
return 'radial-gradient(circle, ' + colors.join(', ') + ')'; |
| 13 |
} |
| 14 |
var angle = dir === 'diagonal' ? '135deg' : '90deg'; |
| 15 |
return 'linear-gradient(' + angle + ', ' + colors.join(', ') + ')'; |
| 16 |
} |
| 17 |
|
| 18 |
function initGTA(appEl) { |
| 19 |
var raw = appEl.dataset.opts; |
| 20 |
if (!raw) return; |
| 21 |
var opts; |
| 22 |
try { opts = JSON.parse(raw); } catch (e) { return; } |
| 23 |
|
| 24 |
var animType = opts.animationType || 'shift'; |
| 25 |
var speed = (opts.animationSpeed || 4) + 's'; |
| 26 |
var gradCss = buildGradient(opts); |
| 27 |
var bgSize = (animType === 'shift' || animType === 'rainbow' || animType === 'reveal') ? '300% 300%' : '200% 200%'; |
| 28 |
|
| 29 |
// Outer wrapper |
| 30 |
var outer = document.createElement('div'); |
| 31 |
outer.style.padding = (opts.paddingV || 24) + 'px ' + (opts.paddingH || 24) + 'px'; |
| 32 |
outer.style.backgroundColor = opts.showBg ? (opts.bgColor || '#0f172a') : ''; |
| 33 |
outer.style.borderRadius = (opts.borderRadius || 0) + 'px'; |
| 34 |
outer.style.textAlign = opts.textAlign || 'center'; |
| 35 |
outer.style.overflow = 'hidden'; |
| 36 |
|
| 37 |
/* typography CSS vars */ |
| 38 |
if (window.typoCssVarsForEl) window.typoCssVarsForEl(opts.typoText, '--bkbg-gta-tt-', outer); |
| 39 |
outer.classList.add('bkbg-gta-app'); |
| 40 |
|
| 41 |
// Hover class helpers |
| 42 |
if (opts.pauseOnHover) outer.classList.add('bkbg-gta-pause-hover'); |
| 43 |
if (opts.reverseOnHover) outer.classList.add('bkbg-gta-reverse-hover'); |
| 44 |
|
| 45 |
// Build text element |
| 46 |
var tag = opts.tag || 'h2'; |
| 47 |
var textEl = document.createElement(tag); |
| 48 |
textEl.className = 'bkbg-gta-el'; |
| 49 |
textEl.style.margin = '0'; |
| 50 |
textEl.style.padding = '0'; |
| 51 |
textEl.style.display = 'block'; |
| 52 |
|
| 53 |
if (animType === 'wave') { |
| 54 |
// Per-character wave with staggered delay |
| 55 |
var words = (opts.text || '').split(''); |
| 56 |
var charIdx = 0; |
| 57 |
words.forEach(function (ch) { |
| 58 |
if (ch === ' ') { |
| 59 |
textEl.appendChild(document.createTextNode('\u00a0')); |
| 60 |
charIdx++; |
| 61 |
return; |
| 62 |
} |
| 63 |
var span = document.createElement('span'); |
| 64 |
span.className = 'bkbg-gta-char'; |
| 65 |
span.textContent = ch; |
| 66 |
span.style.background = gradCss; |
| 67 |
span.style.backgroundSize = bgSize; |
| 68 |
span.style.animationDuration = speed; |
| 69 |
span.style.animationDelay = (charIdx * 0.06) + 's'; |
| 70 |
textEl.appendChild(span); |
| 71 |
charIdx++; |
| 72 |
}); |
| 73 |
} else { |
| 74 |
// Single animated text node wrapped in span |
| 75 |
var inner = document.createElement('span'); |
| 76 |
inner.className = 'bkbg-gta-text bkbg-gta-anim-' + animType; |
| 77 |
inner.textContent = opts.text || 'Animated Gradient Text'; |
| 78 |
inner.style.background = gradCss; |
| 79 |
inner.style.backgroundSize = bgSize; |
| 80 |
inner.style.backgroundClip = 'text'; |
| 81 |
inner.style.webkitBackgroundClip = 'text'; |
| 82 |
inner.style.webkitTextFillColor = 'transparent'; |
| 83 |
inner.style.color = 'transparent'; |
| 84 |
inner.style.animationDuration = speed; |
| 85 |
inner.style.display = 'inline-block'; |
| 86 |
inner.style.width = '100%'; |
| 87 |
|
| 88 |
if (opts.glowEffect) { |
| 89 |
var blur = opts.glowBlur || 20; |
| 90 |
var opacity = opts.glowOpacity || 0.6; |
| 91 |
// Use a text-shadow-like drop-shadow on the outer element |
| 92 |
inner.style.filter = 'drop-shadow(0 0 ' + blur + 'px rgba(' + hexToRgb(opts.color1 || '#f59e0b') + ',' + opacity + '))'; |
| 93 |
} |
| 94 |
|
| 95 |
textEl.appendChild(inner); |
| 96 |
} |
| 97 |
|
| 98 |
outer.appendChild(textEl); |
| 99 |
appEl.parentNode.replaceChild(outer, appEl); |
| 100 |
} |
| 101 |
|
| 102 |
function hexToRgb(hex) { |
| 103 |
hex = hex.replace(/^#/, ''); |
| 104 |
if (hex.length === 3) hex = hex.split('').map(function (c) { return c + c; }).join(''); |
| 105 |
var n = parseInt(hex, 16); |
| 106 |
return [(n >> 16) & 255, (n >> 8) & 255, n & 255].join(','); |
| 107 |
} |
| 108 |
|
| 109 |
document.addEventListener('DOMContentLoaded', function () { |
| 110 |
document.querySelectorAll('.bkbg-gta-app').forEach(initGTA); |
| 111 |
}); |
| 112 |
|
| 113 |
if (document.readyState === 'complete' || document.readyState === 'interactive') { |
| 114 |
document.querySelectorAll('.bkbg-gta-app').forEach(initGTA); |
| 115 |
} |
| 116 |
})(); |
| 117 |
|