/* ========================================== 2048 FLOATING PARTICLES - BACKGROUND DECORATION ========================================== fungsi - createParticle() - Buat partikel yang naik dari bawah - Self-recycling system (partikel hilang → buat baru) - Efek drift horizontal untuk gerakan natural ========================================== */ // Floating Particles System - Particles rising from bottom (function() { // Ambil container untuk partikel const container = document.getElementById('floating-particles'); if (!container) return; // Guard: kalau container nggak ada, skip // Config warna partikel (5 warna neon) const particleColors = ['cyan', 'pink', 'purple', 'green', 'orange']; const particleCount = 25; // Total partikel yang muncul /* ========================================== CREATE PARTICLE - Buat 1 partikel ========================================== */ function createParticle() { // Buat element div untuk partikel const particle = document.createElement('div'); // Pilih warna random dari array const randomColor = particleColors[Math.floor(Math.random() * particleColors.length)]; particle.className = `floating-particle ${randomColor}`; // POSISI HORIZONTAL RANDOM (0-100%) const leftPos = Math.random() * 100; particle.style.left = leftPos + '%'; // DRIFT HORIZONTAL (gerakan ke kiri/kanan saat naik) // Range: -75px sampai +75px const drift = (Math.random() - 0.5) * 150; particle.style.setProperty('--drift', drift + 'px'); // DURASI ANIMASI RANDOM (8-18 detik) // Semakin lama = semakin smooth & dramatis const duration = 8 + Math.random() * 10; particle.style.animationDuration = duration + 's'; // DELAY RANDOM (0-5 detik) // Biar nggak semua partikel muncul bareng (staggered) const delay = Math.random() * 5; particle.style.animationDelay = delay + 's'; // UKURAN RANDOM (6-14px) const size = 6 + Math.random() * 8; particle.style.width = size + 'px'; particle.style.height = size + 'px'; // Append ke container container.appendChild(particle); // ♻️ SELF-RECYCLING SYSTEM // Setelah animasi selesai → hapus & buat baru setTimeout(() => { particle.remove(); // Hapus partikel lama createParticle(); // Buat partikel baru (infinite loop) }, (duration + delay) * 1000); // Total waktu = duration + delay } /* ========================================== INITIALIZE - Buat semua partikel awal ========================================== */ // Loop buat 25 partikel for (let i = 0; i < particleCount; i++) { // Stagger creation: jeda 200ms per partikel // Biar nggak semua muncul sekaligus (smooth) setTimeout(() => createParticle(), i * 200); } })(); // IIFE (Immediately Invoked Function Expression) - langsung jalan