const particle_canvas = $("#particle-canvas"); const particle_ctx = particle_canvas.getContext("2d"); let last_time; let particles = new Set; update_particle_canvas_size(); window.requestAnimationFrame(particle_loop); function update_particle_canvas_size() { particle_canvas.width = document.body.clientWidth; // Whatever's bigger, we use. particle_canvas.height = Math.max(document.body.clientHeight, window.innerHeight); } function spawn_particle(x, y, vel_x, vel_y, rot, vel_rot, img, w, h) { particles.add({ x: x, y: y, vel_x: vel_x, vel_y: vel_y, rot: rot, vel_rot: vel_rot, img: img, w: w, h: h }); } function update_particles(delta_time) { particle_ctx.clearRect(0, 0, particle_canvas.width, particle_canvas.height); for (particle of particles) { // Delete off-screen particles, more or less. For now, it's // designed so that particles go down with the force of // gravity, so we just check if the particle goes below the // screen. if (particle.y > particle_canvas.height) { particles.delete(particle); continue; } // Update the position and rotation of the particle. particle.x += particle.vel_x * delta_time; particle.y += particle.vel_y * delta_time; particle.rot += particle.vel_rot * delta_time; // Update the velocity to take into account "gravity". particle.vel_y += 0.001 * delta_time; // Render particle. particle_ctx.save(); particle_ctx.translate(particle.x + particle.w / 2, particle.y + particle.h / 2); particle_ctx.rotate(particle.rot * Math.PI / 180); particle_ctx.drawImage(particle.img, -particle.w / 2, -particle.h / 2, particle.w, particle.h) particle_ctx.restore(); } } function particle_loop(timestamp) { // Calculate the times needed for updating. update_particles(timestamp - last_time); last_time = timestamp; window.requestAnimationFrame(particle_loop); }