XTaylorSpenceX

Canvas Particle System

Aug 20th, 2025
35
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 5.92 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>Canvas Particle Game</title>
  7.     <!-- Tailwind CSS for a modern, responsive design -->
  8.     <script src="https://cdn.tailwindcss.com"></script>
  9.     <style>
  10.         /* Custom styles for the game and body */
  11.         body {
  12.             background-color: #0d1117;
  13.             font-family: 'Inter', sans-serif;
  14.             color: #c9d1d9;
  15.             display: flex;
  16.             justify-content: center;
  17.             align-items: center;
  18.             height: 100vh;
  19.             margin: 0;
  20.             overflow: hidden;
  21.         }
  22.         .game-container {
  23.             display: flex;
  24.             flex-direction: column;
  25.             align-items: center;
  26.             padding: 20px;
  27.             max-width: 90%;
  28.             width: 800px;
  29.         }
  30.         h1 {
  31.             font-size: 2rem;
  32.             font-weight: 600;
  33.             margin-bottom: 1rem;
  34.             text-align: center;
  35.         }
  36.         p {
  37.             text-align: center;
  38.             max-width: 600px;
  39.             margin-bottom: 2rem;
  40.         }
  41.         canvas {
  42.             background-color: #161b22;
  43.             border: 2px solid #30363d;
  44.             border-radius: 12px;
  45.             box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2), 0 10px 20px rgba(0, 0, 0, 0.15);
  46.             touch-action: none;
  47.             width: 100%;
  48.             height: auto;
  49.             max-height: 600px;
  50.             aspect-ratio: 4 / 3;
  51.         }
  52.     </style>
  53. </head>
  54. <body class="bg-gray-900 text-gray-200">
  55.     <div class="game-container">
  56.         <h1>Canvas Particle System</h1>
  57.         <p>
  58.             Watch the colorful particles bounce and interact. This version includes a fix for the gradient color error, ensuring a smooth and continuous animation.
  59.         </p>
  60.         <canvas id="gameCanvas"></canvas>
  61.     </div>
  62.  
  63.     <script>
  64.         // --- Canvas and Context Setup ---
  65.         const canvas = document.getElementById('gameCanvas');
  66.         const ctx = canvas.getContext('2d');
  67.         const dpr = window.devicePixelRatio || 1; // Device pixel ratio for sharp rendering on high-DPI screens
  68.  
  69.         // Adjust canvas size to be responsive and high-resolution
  70.         function resizeCanvas() {
  71.             const container = document.querySelector('.game-container');
  72.             const newWidth = container.offsetWidth;
  73.             const newHeight = newWidth * 0.75; // Maintain a 4:3 aspect ratio
  74.  
  75.             canvas.style.width = `${newWidth}px`;
  76.             canvas.style.height = `${newHeight}px`;
  77.  
  78.             canvas.width = newWidth * dpr;
  79.             canvas.height = newHeight * dpr;
  80.             ctx.scale(dpr, dpr);
  81.         }
  82.  
  83.         window.addEventListener('resize', resizeCanvas);
  84.         resizeCanvas();
  85.  
  86.         // --- Particle Class ---
  87.         class Particle {
  88.             constructor(x, y, radius) {
  89.                 this.x = x;
  90.                 this.y = y;
  91.                 this.radius = radius;
  92.                 this.vx = (Math.random() - 0.5) * 2; // Velocity on x-axis
  93.                 this.vy = (Math.random() - 0.5) * 2; // Velocity on y-axis
  94.                 this.hue = Math.random() * 360; // Initial hue for color
  95.                 this.color = `hsl(${this.hue}, 80%, 60%)`;
  96.             }
  97.  
  98.             // Update the particle's position
  99.             update() {
  100.                 this.x += this.vx;
  101.                 this.y += this.vy;
  102.  
  103.                 // Bounce off the canvas edges
  104.                 if (this.x + this.radius > canvas.width / dpr || this.x - this.radius < 0) {
  105.                    this.vx = -this.vx;
  106.                }
  107.                if (this.y + this.radius > canvas.height / dpr || this.y - this.radius < 0) {
  108.                    this.vy = -this.vy;
  109.                }
  110.            }
  111.  
  112.            // Draw the particle with a radial gradient
  113.            draw() {
  114.                ctx.beginPath();
  115.                
  116.                // Create a radial gradient for a glowing effect
  117.                const gradient = ctx.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.radius);
  118.                
  119.                // The fix: Ensure color stops have valid color strings.
  120.                // The original error occurred if a variable used to create the color string
  121.                // became NaN. By using fixed or carefully validated values, this is prevented.
  122.                gradient.addColorStop(0, this.color);
  123.                gradient.addColorStop(1, 'rgba(183, 10, 255, 0.8)');
  124.  
  125.                ctx.fillStyle = gradient;
  126.                ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
  127.                ctx.fill();
  128.                ctx.closePath();
  129.            }
  130.        }
  131.  
  132.        // --- Game Loop and Initialization ---
  133.        let particles = [];
  134.        const numParticles = 50;
  135.  
  136.        function init() {
  137.            // Clear any previous particles and create new ones
  138.            particles = [];
  139.            for (let i = 0; i < numParticles; i++) {
  140.                const radius = Math.random() * 10 + 2;
  141.                const x = Math.random() * (canvas.width / dpr - radius * 2) + radius;
  142.                const y = Math.random() * (canvas.height / dpr - radius * 2) + radius;
  143.                particles.push(new Particle(x, y, radius));
  144.            }
  145.        }
  146.  
  147.        function gameLoop() {
  148.            // Clear the canvas for the next frame
  149.            ctx.clearRect(0, 0, canvas.width / dpr, canvas.height / dpr);
  150.            
  151.            // Update and draw each particle
  152.            particles.forEach(p => {
  153.                 p.update();
  154.                 p.draw();
  155.             });
  156.  
  157.             // Request the next animation frame
  158.             requestAnimationFrame(gameLoop);
  159.         }
  160.        
  161.         // Start the game when the window has loaded
  162.         window.onload = function() {
  163.             init();
  164.             gameLoop();
  165.         };
  166.  
  167.     </script>
  168. </body>
  169. </html>
  170.  
Advertisement
Add Comment
Please, Sign In to add comment