Cara Membuat Simulasi Partikel dengan HTML+Canvas

Jumat, 16 Mei 2025 edit

Berikut ini visual simulasi partikel yang bergerak acak dan memantul ketika mengenai dinding pembatas saja tanpa ada tumbukan dengan partikel lain. Ini relatif mudah dipahami karena setiap perbagian kode sudah diberi keterangan/komentar. Cocok buat pemula yang ingin mengawali pembuatan simulasi sederhana.

Contoh simulasi animasi seperti berikut kemudian diikuti dengan kode yang dapat disalin dan disimpan dalam format html di notepad++ sehingga dapat dibuka secara offline/luring. Unduh notepad++.

Simulasi Partikel dengan HTML+Canvas

Berikut ini kode yang dapat disalin ke format html, misal dengan menggunakan aplikasi notepad atau notepad++ atau yang lain di komputer kemudian disimpan sebagai file html (Hyper Text Markup Language) dengan nama tertentu. Bila sudah silakan buka file ini dengan menggunakan browser seperti Chrome, Edges, Opera, Safari, atau yang lain.

<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simulasi Partikel dengan Canvas</title>
    <style>
        /* Gaya dasar untuk halaman */
        body {
            margin: 0;
            padding: 20px;
            display: flex;
            flex-direction: column;
            align-items: center;
            font-family: Arial, sans-serif;
            background-color: mediumorchid;
        }
        
        /* Gaya untuk canvas */
        #particleCanvas {
            background-color: white;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
            margin-top: 20px;
        }
        
        h1 {
            color: #333;
        }
        
        .controls {
            margin: 15px 0;
        }
        
        button {
            padding: 8px 15px;
            margin: 0 5px;
            cursor: pointer;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
        }
    </style>
</head>
<body>
    <h1>Simulasi Partikel dengan HTML+Canvas</h1>
    <div class="controls">
        <button id="addParticle">Tambah Partikel</button>
        <button id="reset">Reset</button>
    </div>
    <canvas id="particleCanvas" width="600" height="400"></canvas>

    <script>
        // =============================================
        // INISIALISASI CANVAS DAN KONTEKS
        // =============================================
        
        // Mengambil elemen canvas dari DOM
        const canvas = document.getElementById('particleCanvas');
        
        // Mendapatkan konteks rendering 2D untuk canvas
        const ctx = canvas.getContext('2d');
        
        // =============================================
        // VARIABEL GLOBAL DAN KONFIGURASI
        // =============================================
        
        // Array untuk menyimpan semua partikel
        let particles = [];
        
        // Konfigurasi warna
        const colors = {
            background: '#f9f9f9',      // Warna latar belakang canvas
            particleColors: [           // Array warna untuk partikel
                '#FF5252', '#FF4081', '#E040FB', 
                '#7C4DFF', '#536DFE', '#448AFF',
                '#40C4FF', '#18FFFF', '#64FFDA',
                '#69F0AE', '#B2FF59', '#EEFF41'
            ],
            border: '#333'             // Warna border partikel
        };
        
        // Konfigurasi simulasi
        const config = {
            maxParticles: 50,          // Jumlah maksimal partikel
            minRadius: 5,              // Ukuran minimal partikel
            maxRadius: 15,             // Ukuran maksimal partikel
            minSpeed: 1,               // Kecepatan minimal
            maxSpeed: 3                // Kecepatan maksimal
        };
        
        // =============================================
        // KELAS PARTIKEL
        // =============================================
        
        // Membuat kelas Particle untuk mengelola properti dan perilaku partikel
        class Particle {
            constructor(x, y) {
                // Posisi awal partikel (jika tidak ditentukan, posisi acak)
                this.x = x || Math.random() * canvas.width;
                this.y = y || Math.random() * canvas.height;
                
                // Ukuran partikel (acak dalam range min-max)
                this.radius = config.minRadius + Math.random() * (config.maxRadius - config.minRadius);
                
                // Kecepatan partikel (acak dalam range min-max)
                this.speedX = (config.minSpeed + Math.random() * (config.maxSpeed - config.minSpeed)) * (Math.random() < 0.5 ? -1 : 1);
                this.speedY = (config.minSpeed + Math.random() * (config.maxSpeed - config.minSpeed)) * (Math.random() < 0.5 ? -1 : 1);
                
                // Warna partikel (dipilih acak dari array colors.particleColors)
                this.color = colors.particleColors[Math.floor(Math.random() * colors.particleColors.length)];
                
                // Sudut rotasi untuk efek visual (opsional)
                this.rotation = 0;
                this.rotationSpeed = Math.random() * 0.02 - 0.01;
            }
            
            // Method untuk mengupdate posisi partikel
            update() {
                // Update posisi berdasarkan kecepatan
                this.x += this.speedX;
                this.y += this.speedY;
                
                // Update rotasi
                this.rotation += this.rotationSpeed;
                
                // Deteksi tumbukan dengan tepi canvas
                // Tumbukan dengan tepi kiri/kanan
                if (this.x - this.radius <= 0 || this.x + this.radius >= canvas.width) {
                    this.speedX *= -1; // Membalik arah horizontal
                    
                    // Koreksi posisi agar tidak terjebak di tepi
                    if (this.x - this.radius <= 0) this.x = this.radius;
                    if (this.x + this.radius >= canvas.width) this.x = canvas.width - this.radius;
                }
                
                // Tumbukan dengan tepi atas/bawah
                if (this.y - this.radius <= 0 || this.y + this.radius >= canvas.height) {
                    this.speedY *= -1; // Membalik arah vertikal
                    
                    // Koreksi posisi
                    if (this.y - this.radius <= 0) this.y = this.radius;
                    if (this.y + this.radius >= canvas.height) this.y = canvas.height - this.radius;
                }
            }
            
            // Method untuk menggambar partikel
            draw() {
                ctx.save(); // Menyimpan state canvas sebelum melakukan transformasi
                ctx.translate(this.x, this.y); // Memindahkan origin ke posisi partikel
                ctx.rotate(this.rotation); // Rotasi partikel
                
                // Menggambar lingkaran partikel
                ctx.beginPath();
                ctx.arc(0, 0, this.radius, 0, Math.PI * 2);
                ctx.fillStyle = this.color;
                ctx.fill();
                
                // Menambahkan border pada partikel
                ctx.lineWidth = 2;
                ctx.strokeStyle = colors.border;
                ctx.stroke();
                
                ctx.restore(); // Mengembalikan state canvas ke semula
            }
        }
        
        // =============================================
        // FUNGSI UTAMA
        // =============================================
        
        // Fungsi untuk inisialisasi simulasi
        function init() {
            // Membuat partikel awal
            createParticles(10);
            
            // Memulai animasi
            animate();
        }
        
        // Fungsi untuk membuat beberapa partikel sekaligus
        function createParticles(count) {
            // Cek agar tidak melebihi maxParticles
            if (particles.length + count > config.maxParticles) {
                count = config.maxParticles - particles.length;
                if (count <= 0) return;
            }
            
            // Membuat partikel baru sebanyak count
            for (let i = 0; i < count; i++) {
                particles.push(new Particle());
            }
        }
        
        // Fungsi untuk mereset simulasi
        function resetSimulation() {
            particles = []; // Mengosongkan array partikel
            createParticles(5); // Membuat partikel baru
        }
        
        // Fungsi animasi utama (loop rendering)
        function animate() {
            // Membersihkan canvas setiap frame
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            // Menggambar background
            ctx.fillStyle = colors.background;
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            // Update dan gambar semua partikel
            particles.forEach(particle => {
                particle.update();
                particle.draw();
            });
            
            // Memanggil fungsi animate lagi pada frame berikutnya
            requestAnimationFrame(animate);
        }
        
        // =============================================
        // EVENT LISTENERS
        // =============================================
        
        // Menambahkan partikel baru saat tombol diklik
        document.getElementById('addParticle').addEventListener('click', () => {
            createParticles(3);
        });
        
        // Mereset simulasi saat tombol reset diklik
        document.getElementById('reset').addEventListener('click', resetSimulation);
        
        // Menambahkan partikel baru saat canvas diklik
        canvas.addEventListener('click', (e) => {
            // Mendapatkan posisi klik relatif terhadap canvas
            const rect = canvas.getBoundingClientRect();
            const x = e.clientX - rect.left;
            const y = e.clientY - rect.top;
            
            // Membuat partikel baru di posisi klik
            if (particles.length < config.maxParticles) {
                particles.push(new Particle(x, y));
            }
        });
        
        // =============================================
        // MEMULAI SIMULASI
        // =============================================
        
        // Memulai simulasi saat halaman siap
        window.addEventListener('load', init);
    </script>
</body>
</html>

Selamat mencoba, semoga berhasil.

Bagikan di

Tidak ada komentar:

Posting Komentar

 
Copyright © 2015-2025 Urip dot Info | Disain Template oleh Herdiansyah Dimodivikasi Urip.Info