kelompok06-2048/Animation_Login.js
Jevinca Marvella 677ad4ab06 Comment section
2025-12-16 02:06:46 +07:00

150 lines
5.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* ==========================================
ANIMATION LOGIN - PARTICLE BACKGROUND SYSTEM
==========================================
fungsi:
- Class Particle: Objek partikel dengan posisi & kecepatan
- Even Distribution: Distribusi partikel merata (15x10 grid)
- Animate Loop: Pergerakan smooth dengan requestAnimationFrame
========================================== */
/* ==========================================
SETUP CONTAINER & CONFIG
========================================== */
const particlesContainer = document.getElementById('particles');
const particleCount = 150; // Total partikel yang dibuat
const particles = []; // Array untuk simpan semua partikel
/* ==========================================
CLASS PARTICLE - Blueprint untuk setiap partikel
==========================================
Properties:
- x, y: Posisi partikel
- vx, vy: Kecepatan horizontal & vertikal (velocity)
- size: Ukuran partikel (2-5px)
- color: Warna neon random
========================================== */
class Particle {
constructor() {
// Buat element DOM untuk partikel
this.element = document.createElement('div');
this.element.className = 'particle';
this.reset(); // Initialize posisi & properti
particlesContainer.appendChild(this.element);
}
/* ==========================================
RESET - Set/reset properti partikel
========================================== */
reset() {
// Posisi random di seluruh layar
this.x = Math.random() * window.innerWidth;
this.y = Math.random() * window.innerHeight;
// Kecepatan random (-0.6 sampai +0.6 pixel/frame)
this.vx = (Math.random() - 0.5) * 1.2;
this.vy = (Math.random() - 0.5) * 1.2;
// Ukuran random (2-5px)
this.size = Math.random() * 3 + 2;
// Array warna neon untuk partikel
const colors = [
'#00d9ff', // Cyan
'#ff00ff', // Magenta
'#00ffff', // Cyan bright
'#ff0080', // Pink
'#9d00ff', // Purple
'#00ff88' // Green
];
// Pilih warna random dari array
const color = colors[Math.floor(Math.random() * colors.length)];
this.element.style.background = color;
this.element.style.boxShadow = `0 0 15px ${color}`; // Glow effect
this.element.style.width = `${this.size}px`;
this.element.style.height = `${this.size}px`;
this.updatePosition(); // Update posisi di DOM
}
/* ==========================================
UPDATE POSITION - Sync posisi ke DOM
========================================== */
updatePosition() {
this.element.style.left = `${this.x}px`;
this.element.style.top = `${this.y}px`;
}
/* ==========================================
MOVE - Update posisi berdasarkan velocity
==========================================
Fitur: Wrap-around screen (partikel keluar = muncul sisi lain)
========================================== */
move() {
// Update posisi berdasarkan kecepatan
this.x += this.vx;
this.y += this.vy;
// ♻️ WRAP-AROUND LOGIC
// Kalau keluar dari kiri → muncul dari kanan
if (this.x < -10) this.x = window.innerWidth + 10;
// Kalau keluar dari kanan → muncul dari kiri
if (this.x > window.innerWidth + 10) this.x = -10;
// Kalau keluar dari atas → muncul dari bawah
if (this.y < -10) this.y = window.innerHeight + 10;
// Kalau keluar dari bawah → muncul dari atas
if (this.y > window.innerHeight + 10) this.y = -10;
this.updatePosition(); // Sync ke DOM
}
}
/* ==========================================
EVEN DISTRIBUTION - Distribusi Partikel Merata
==========================================
Konsep: Grid 15 kolom x 10 baris (total 150 partikel)
Biar nggak menumpuk di satu area
========================================== */
const cols = 15; // Jumlah kolom
const rows = 10; // Jumlah baris
let particleIndex = 0; // Counter partikel yang sudah dibuat
// Loop baris
for (let i = 0; i < rows; i++) {
// Loop kolom
for (let j = 0; j < cols; j++) {
// Guard: stop kalau sudah 150 partikel
if (particleIndex >= particleCount) break;
const particle = new Particle();
// ⚙️ DISTRIBUSI MERATA + RANDOM OFFSET
// Formula: (index / total) × lebar/tinggi layar
particle.x = (j / cols) * window.innerWidth + (Math.random() - 0.5) * 100;
particle.y = (i / rows) * window.innerHeight + (Math.random() - 0.5) * 100;
particle.updatePosition();
particles.push(particle); // Simpan ke array
particleIndex++;
}
if (particleIndex >= particleCount) break;
}
/* ==========================================
ANIMATE - Main Animation Loop
==========================================
Menggunakan requestAnimationFrame untuk performa optimal
(60 FPS, smooth, GPU-accelerated)
========================================== */
function animate() {
// Loop semua partikel dan gerakkan
particles.forEach(p => p.move());
// Request next frame (recursive call)
// Browser otomatis sync dengan refresh rate monitor
requestAnimationFrame(animate);
}
// Start animation loop
animate();