75 lines
3.1 KiB
JavaScript
75 lines
3.1 KiB
JavaScript
/* ==========================================
|
|
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
|