100 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| ---
 | |
| title: Particle Sim
 | |
| ---
 | |
| ## Particle Simulation in Canvas
 | |
| 
 | |
| In this guide, we're going to build a basic particle simulation in Canvas using simple principles of animation.
 | |
| 
 | |
| We will want to set up an array of particles with accelerations and velocities. We will create 100 particles at random points on the canvas.
 | |
| 
 | |
| ```js
 | |
| canvas = document.getElementById("canvas");
 | |
| ctx = canvas.getContext('2d');
 | |
| 
 | |
| var particles = [];
 | |
| for(var i=0; i<100; i++) {
 | |
|   particles.push(
 | |
|     {
 | |
|       x:Math.random()*canvas.width,
 | |
|       y:Math.random()*canvas.height,
 | |
|       vx:0,
 | |
|       vy:0,
 | |
|       ax:0,
 | |
|       ay:0
 | |
|     }
 | |
|   );
 | |
| }
 | |
| ```
 | |
| 
 | |
| In our draw loop, we render these particles.
 | |
| 
 | |
| ```js
 | |
| function draw() {
 | |
|   ctx.clearRect(0, 0, canvas.width, canvas.height);
 | |
|   for(var i=0; i<particles.length; i++) {
 | |
|     // update state
 | |
| 
 | |
|     // render state
 | |
|     ctx.beginPath();
 | |
|     ctx.arc(particles[i].x, particles[i].y, 5, 0, 2*Math.PI);
 | |
|     ctx.fill();
 | |
|   }
 | |
| 
 | |
|   window.requestAnimationFrame(draw);
 | |
| }
 | |
| window.requestAnimationFrame(draw);
 | |
| ```
 | |
| 
 | |
| Now, all we need to do is update velocity and acceleration each frame. We will add the acceleration to the velocity and add the velocity to the position.
 | |
| 
 | |
| ```js
 | |
| function draw() {
 | |
|   for(var i=0; i<particles.length; i++) {
 | |
|     // update state
 | |
|     particles[i].x+=particles[i].vx;
 | |
|     particles[i].y+=particles[i].vy;
 | |
|     particles[i].vx+=particles[i].ax;
 | |
|     particles[i].vy+=particles[i].ay;
 | |
|   
 | |
|     /* render code */
 | |
|   }
 | |
| 
 | |
|   window.requestAnimationFrame(draw);
 | |
| }
 | |
| window.requestAnimationFrame(draw);
 | |
| ```
 | |
| 
 | |
| That's it! All we need to do to is create a force somewhere. Let's do it with a click listener.
 | |
| 
 | |
| ```js
 | |
| canvas.addEventListener("click", function(e) {
 | |
|   var clickX = e.clientX-canvas.offsetLeft;
 | |
|   var clickY = e.clientY-canvas.offsetTop;
 | |
|   for(var i=0; i<particles.length; i++) {
 | |
|     var delx = particles[i].x-clickX;
 | |
|     var dely = particles[i].y-clickY;
 | |
|     var magnitudeSquared = Math.pow(delx, 2)+Math.pow(dely, 2);
 | |
|     
 | |
|     
 | |
|     particles[i].ax = 0.1*delx/magnitudeSquared;
 | |
|     particles[i].ay = 0.1*dely/magnitudeSquared;
 | |
|     
 | |
|   }
 | |
| });
 | |
| ```
 | |
| 
 | |
| This adds force via the inverse-square law. See [this page](#placeholder) for more details.
 | |
| 
 | |
| That's all! The final codepen:
 | |
| 
 | |
| <p data-height="265" data-theme-id="0" data-slug-hash="OjMbpm" data-default-tab="js,result" data-user="alanluo" data-embed-version="2" data-pen-title="Particle Sim (FCC)" class="codepen">See the Pen <a href="https://codepen.io/alanluo/pen/OjMbpm/">Particle Sim (FCC)</a> by Alan Luo (<a href="https://codepen.io/alanluo">@alanluo</a>) on <a href="https://codepen.io">CodePen</a>.</p>
 | |
| <script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>
 | |
| 
 | |
| <!-- TODO: make it cooler! -->
 | |
| 
 | |
| #### More Information:
 | |
| 
 | |
| - [MDN Canvas API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API)
 | |
| 
 | |
| 
 |