diff --git a/assets/js/logo-sparks.js b/assets/js/logo-sparks.js index 1533442..0830bbf 100644 --- a/assets/js/logo-sparks.js +++ b/assets/js/logo-sparks.js @@ -15,17 +15,26 @@ staggerAnimations: true }; + function getViewportScale() { + const width = window.innerWidth; + if (width < 768) { + return width < 480 ? 0.25 : 0.4; + } + return width < 1024 ? 0.7 : 1.0; + } + function random(min, max) { return Math.random() * (max - min) + min; } - function generatePath(radius, complexity) { + function generatePath(radius, complexity, scale) { const points = []; + const jitter = 50 * scale; for (let i = 0; i <= complexity; i++) { const angle = (i / complexity) * Math.PI * 2; const r = random(radius * 0.8, radius * 1.2); - const x = Math.cos(angle) * r + random(-50, 50); - const y = Math.sin(angle) * r + random(-50, 50); + const x = Math.cos(angle) * r + random(-jitter, jitter); + const y = Math.sin(angle) * r + random(-jitter, jitter); points.push({ x, y, scale: random(0.7, 1.3) }); } return points; @@ -62,6 +71,9 @@ const logoFigure = document.querySelector('body:has(.background-container) article.glass figure:first-of-type'); if (!logoFigure) return; + const scale = getViewportScale(); + if (scale < 0.3 && window.innerWidth < 400) return; + let allKeyframes = ''; const sparks = []; @@ -70,9 +82,9 @@ spark.className = 'logo-spark'; spark.dataset.sparkId = i; - const size = random(config.minSize, config.maxSize); + const size = random(config.minSize, config.maxSize) * scale; const duration = random(config.minDuration, config.maxDuration); - const radius = random(config.minRadius, config.maxRadius); + const radius = random(config.minRadius, config.maxRadius) * scale; const isBehind = Math.random() < config.behindLogoFraction; const delay = config.staggerAnimations @@ -85,7 +97,7 @@ height: ${size}px; border-radius: 50%; background: radial-gradient(circle, rgba(255, 255, 255, 0.9), rgba(74, 158, 255, 0.6), transparent); - box-shadow: 0 0 8px rgba(74, 158, 255, 0.8), 0 0 4px rgba(255, 255, 255, 0.6); + box-shadow: 0 0 ${8 * scale}px rgba(74, 158, 255, 0.8), 0 0 ${4 * scale}px rgba(255, 255, 255, 0.6); top: 50%; left: 50%; pointer-events: none; @@ -94,7 +106,7 @@ animation-delay: -${delay.toFixed(2)}s; `; - const path = generatePath(radius, config.pathComplexity); + const path = generatePath(radius, config.pathComplexity, scale); allKeyframes += createKeyframes(i, path, isBehind); sparks.push(spark); @@ -103,16 +115,36 @@ // Inject keyframes const style = document.createElement('style'); style.textContent = allKeyframes; + style.id = 'logo-sparks-keyframes'; document.head.appendChild(style); // Inject sparks sparks.forEach(spark => logoFigure.appendChild(spark)); } + function cleanupSparks() { + const existingStyle = document.getElementById('logo-sparks-keyframes'); + if (existingStyle) existingStyle.remove(); + + const sparks = document.querySelectorAll('.logo-spark'); + sparks.forEach(spark => spark.remove()); + } + + let resizeTimeout; + function handleResize() { + clearTimeout(resizeTimeout); + resizeTimeout = setTimeout(() => { + cleanupSparks(); + initSparks(); + }, 250); + } + if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initSparks); } else { initSparks(); } + + window.addEventListener('resize', handleResize); })();