Interactive Physics Animations Javascript Canvas 11

Well, the last iteration was fun, but the animation went so quick. Now we’re going to do something to contain these dots in our canvas. Let’s have them bounce off the edges of the canvas. We’ll multiply the velocity by a bounce variable. This will reverse the direction the dot is going. We’ll have a series of conditional statements that will check a dots coordinates against the canvas width and height, factoring in it’s own radius so it the edge of the circle kisses the edge of the canvas rather than letting the center of the circle be what bounces on the walls. I hope it’s not too much for one iteration, I know I started with the premise of babysteps, but I’m getting anxious. interactive physics animations via javascript & canvas | 11.

[cc lang=”javascript”]
$(function () {
var canvas, context, width, height, x, y, radius = 25, clickX, clickY, drag = false;
var total_dots = 25;
var fps = 24;
var bounce = -1;

canvas = $(“#canvas”)[0];
context = canvas.getContext(“2d”);
var dots = new Array();
var drag_i = -1;

var this_dot = {};
for (var i=0; i < total_dots; i++){ var this_dot = { x: Math.random()*canvas.width, y: Math.random()*canvas.height, vx: Math.random()*30-10, vy: Math.random()*30-10, width:canvas.width, height: canvas.height, radius:Math.random()*20+10 }; dots.push(this_dot); } draw(); $("#canvas").mousedown(function (event) { var dx, dy, dist; for (var i=0; i < dots.length; i++){ dx = event.pageX - this.offsetLeft - dots[i].x; dy = event.pageY - this.offsetTop - dots[i].y; dist = Math.sqrt(dx * dx + dy * dy); if(dist < radius) { drag = true; drag_i = i clickX = dx; clickY = dy; continue; } } }); $("#canvas").mouseup(function (event) { drag = false; drag_i = -1; }); $("#canvas").mousemove(function (event) { if(drag) { dots[drag_i].x = event.pageX - this.offsetLeft - clickX; dots[drag_i].y = event.pageY - this.offsetTop - clickY; draw(); } }); function update(){ for (var i=0; i < dots.length; i++){ if (drag_i != i){ var this_dot = dots[i]; this_dot.x += this_dot.vx; this_dot.y += this_dot.vy; if (this_dot.x > canvas.width – this_dot.radius){
this_dot.x = canvas.width – this_dot.radius;
this_dot.vx = this_dot.vx * bounce;
}
else if(this_dot.x < 0 + this_dot.radius){ this_dot.x = this_dot.radius; this_dot.vx = this_dot.vx * bounce; } if (this_dot.y > canvas.height – this_dot.radius){
this_dot.y = canvas.height – this_dot.radius;
this_dot.vy = this_dot.vy * bounce;
}
else if(this_dot.y < 0 + this_dot.radius){ this_dot.y = this_dot.radius; this_dot.vy = this_dot.vy * bounce; } } } } function draw() { context.clearRect(0, 0, canvas.width, canvas.height); for (var i=0; i < dots.length; i++){ context.beginPath(); context.arc(dots[i].x, dots[i].y, dots[i].radius, 0, Math.PI * 2, false); context.fill(); context.closePath(); } } setInterval(function() { update(); draw(); }, 1000/fps); }); [/cc]Follow the whole Interactive Physics Animations via Javascript & Canvas series.

Interactive Physics Animations Javascript Canvas 10

Now that we have our framework for animation we can make things a bit more fluid. Let’s use a velocity to update the positions or coordinates of each dot rather than just throwing random numbers at them. We can then adjust the velocity or rate of movement and it will be a much more natural and fluid movement. Adding to each dot a vx and vy (we’re looking at the velocity in each dimension or axis). Then we update the x and y each frame by the current velocity. This iteration we’re just applying a flat random velocity, but it will be easy to apply a force like gravity, friction or anything to this velocity and it will calculate the balls position for us. This is when physics gets fun. interactive physics animations via javascript & canvas | 10.

[cc lang=”javascript”]
$(function () {
var canvas, context, width, height, x, y, radius = 25, clickX, clickY, drag = false;
var total_dots = 25;
var fps = 24;

canvas = $(“#canvas”)[0];
context = canvas.getContext(“2d”);
var dots = new Array();
var drag_i = -1;

var this_dot = {};
for (var i=0; i < total_dots; i++){ var this_dot = { x: Math.random()*canvas.width, y: Math.random()*canvas.height, vx: Math.random()*30-10, vy: Math.random()*30-10, width:canvas.width, height: canvas.height, radius:Math.random()*20+10 }; dots.push(this_dot); } draw(); $("#canvas").mousedown(function (event) { var dx, dy, dist; for (var i=0; i < dots.length; i++){ dx = event.pageX - this.offsetLeft - dots[i].x; dy = event.pageY - this.offsetTop - dots[i].y; dist = Math.sqrt(dx * dx + dy * dy); if(dist < radius) { drag = true; drag_i = i clickX = dx; clickY = dy; continue; } } }); $("#canvas").mouseup(function (event) { drag = false; drag_i = -1; }); $("#canvas").mousemove(function (event) { if(drag) { dots[drag_i].x = event.pageX - this.offsetLeft - clickX; dots[drag_i].y = event.pageY - this.offsetTop - clickY; draw(); } }); function update(){ for (var i=0; i < dots.length; i++){ if (drag_i != i){ var this_dot = dots[i]; this_dot.vy = this_dot.vy; this_dot.vx = this_dot.vx; this_dot.x += this_dot.vx; this_dot.y += this_dot.vy; if (this_dot.x > canvas.width – this_dot.radius){
this_dot.x = canvas.width – this_dot.radius;
this_dot.vx = this_dot.vx * bounce;
}
else if(this_dot.x < 0 + this_dot.radius){ this_dot.x = this_dot.radius; this_dot.vx = this_dot.vx * bounce; } if (this_dot.y > canvas.height – this_dot.radius){
this_dot.y = canvas.height – this_dot.radius;
this_dot.vy = this_dot.vy * bounce;
}
else if(this_dot.y < 0 + this_dot.radius){ this_dot.y = this_dot.radius; this_dot.vy = this_dot.vy * bounce; } } } } function draw() { context.clearRect(0, 0, canvas.width, canvas.height); for (var i=0; i < dots.length; i++){ context.beginPath(); context.arc(dots[i].x, dots[i].y, dots[i].radius, 0, Math.PI * 2, false); context.fill(); context.closePath(); } } setInterval(function() { update(); draw(); }, 1000/fps); }); [/cc]Follow the whole Interactive Physics Animations via Javascript & Canvas series.

Interactive Physics Animations Javascript Canvas 09

Here’s a quick and easy update. I tend to think of frames in animation and rarely do I think of milliseconds. I’m going to make a var called fps and it will be used to calculate our animation rate. interactive physics animations via javascript & canvas | 09.

[cc lang=”javascript”]
$(function () {
var canvas, context, width, height, x, y, radius = 25, clickX, clickY, drag = false;
var total_dots = 25;
var fps = 24;

canvas = $(“#canvas”)[0];
context = canvas.getContext(“2d”);
var dots = new Array();
var drag_i = -1;

var this_dot = {};
for (var i=0; i < total_dots; i++){ var this_dot = { x: Math.random()*canvas.width, y: Math.random()*canvas.height, width:canvas.width, height: canvas.height, radius:Math.random()*20+10 }; dots.push(this_dot); } draw(); $("#canvas").mousedown(function (event) { var dx, dy, dist; for (var i=0; i < dots.length; i++){ dx = event.pageX - this.offsetLeft - dots[i].x; dy = event.pageY - this.offsetTop - dots[i].y; dist = Math.sqrt(dx * dx + dy * dy); if(dist < radius) { drag = true; drag_i = i clickX = dx; clickY = dy; continue; } } }); $("#canvas").mouseup(function (event) { drag = false; drag_i = -1; }); $("#canvas").mousemove(function (event) { if(drag) { dots[drag_i].x = event.pageX - this.offsetLeft - clickX; dots[drag_i].y = event.pageY - this.offsetTop - clickY; draw(); } }); function update(){ for (var i=0; i < dots.length; i++){ if (drag_i != i){ var this_dot = dots[i]; this_dot.x += Math.random() * 10 - 5; this_dot.y += Math.random() * 10 - 5; } } } function draw() { context.clearRect(0, 0, canvas.width, canvas.height); for (var i=0; i < dots.length; i++){ context.beginPath(); context.arc(dots[i].x, dots[i].y, dots[i].radius, 0, Math.PI * 2, false); context.fill(); context.closePath(); } } setInterval(function() { update(); draw(); }, 1000/fps); }); [/cc]Follow the whole Interactive Physics Animations via Javascript & Canvas series.

Link: Close Pixelate · David DeSandro

I saw this script back when David put it out there and was very impressed, but totally forgot where I’d seen it. Working lots with canvas and imageData recently and have been trying to remember where I’d seen this awesome experiment using it, I wanted to shout it. And now he’s linking to Ben Keens web app that uses this script with an interface! Very fun!

Link: Close Pixelate · David DeSandro – http://desandro.com/resources/close-pixelate/ by David DeSandro

pixelator

Interactive Physics Animations Javascript Canvas 08

Thus far, we’ve been doing lot of setup and it hasn’t been very visually exciting. Now we start the fun stuff! Adding motion! Before we just has a draw function, but now we’ll add a function that will control the animations and we’ll also need a way to execute code repeatedly over a period of time. We’ll use a setInterval function to call first update and then draw multiple times a second and this will give the essence of animation! Here we’re just adjusting the coordinates of each of the dots every time the update function is fired, which happens to be every 100 milliseconds, or 10 times a second. interactive physics animations via javascript & canvas | 08.

[cc lang=”javascript”]
$(function () {
var canvas, context, width, height, x, y, radius = 25, clickX, clickY, drag = false;
var total_dots = 25;

canvas = $(“#canvas”)[0];
context = canvas.getContext(“2d”);
var dots = new Array();
var drag_i = -1;

var this_dot = {};
for (var i=0; i < total_dots; i++){ var this_dot = { x: Math.random()*canvas.width, y: Math.random()*canvas.height, width:canvas.width, height: canvas.height, radius:Math.random()*20+10 }; dots.push(this_dot); } draw(); $("#canvas").mousedown(function (event) { var dx, dy, dist; for (var i=0; i < dots.length; i++){ dx = event.pageX - this.offsetLeft - dots[i].x; dy = event.pageY - this.offsetTop - dots[i].y; dist = Math.sqrt(dx * dx + dy * dy); if(dist < radius) { drag = true; drag_i = i clickX = dx; clickY = dy; continue; } } }); $("#canvas").mouseup(function (event) { drag = false; drag_i = -1; }); $("#canvas").mousemove(function (event) { if(drag) { dots[drag_i].x = event.pageX - this.offsetLeft - clickX; dots[drag_i].y = event.pageY - this.offsetTop - clickY; draw(); } }); function update(){ for (var i=0; i < dots.length; i++){ if (drag_i != i){ var this_dot = dots[i]; this_dot.x += Math.random() * 10 - 5; this_dot.y += Math.random() * 10 - 5; } } } function draw() { context.clearRect(0, 0, canvas.width, canvas.height); for (var i=0; i < dots.length; i++){ context.beginPath(); context.arc(dots[i].x, dots[i].y, dots[i].radius, 0, Math.PI * 2, false); context.fill(); context.closePath(); } } setInterval(function() { update(); draw(); }, 100); }); [/cc]Follow the whole Interactive Physics Animations via Javascript & Canvas series.

Interactive Physics Animations Javascript Canvas 7b

Here’s an interesting rendering I found when I was playing with drawing multiple dots. interactive physics animations via javascript & canvas | 07 B.

[cc lang=”javascript”]
$(function () {
var canvas, context, width, height, x, y, radius = 25, clickX, clickY, drag = false;
var total_dots = 25;

canvas = $(“#canvas”)[0];
context = canvas.getContext(“2d”);
var dots = new Array();
var drag_i = -1;

var this_dot = {};
for (var i=0; i < total_dots; i++){ var this_dot = { x: Math.random()*canvas.width, y: Math.random()*canvas.height, width:canvas.width, height: canvas.height, radius:Math.random()*20+10 }; dots.push(this_dot); } draw(); $("#canvas").mousedown(function (event) { var dx, dy, dist; for (var i=0; i < dots.length; i++){ dx = event.pageX - this.offsetLeft - dots[i].x; dy = event.pageY - this.offsetTop - dots[i].y; dist = Math.sqrt(dx * dx + dy * dy); if(dist < radius) { drag = true; drag_i = i clickX = dx; clickY = dy; continue; } } }); $("#canvas").mouseup(function (event) { drag = false; drag_i = -1; }); $("#canvas").mousemove(function (event) { if(drag) { dots[drag_i].x = event.pageX - this.offsetLeft - clickX; dots[drag_i].y = event.pageY - this.offsetTop - clickY; draw(); } }); function draw() { context.clearRect(0, 0, canvas.width, canvas.height); context.beginPath(); for (var i=0; i < dots.length; i++){ context.arc(dots[i].x, dots[i].y, dots[i].radius, 0, Math.PI * 2, false); } context.fill(); } }); [/cc]Follow the whole Interactive Physics Animations via Javascript & Canvas series.

Interactive Physics Animations Javascript Canvas 07

This step we’ll add a variable to hold the total number of dots we want to create and use it in our for loop that creates the dots. We’ll also give the dots a little more randomness by varying the size with a radius value. interactive physics animations via javascript & canvas | 07.

[cc lang=”javascript”]
$(function () {
var canvas, context, width, height, x, y, radius = 25, clickX, clickY, drag = false;
var total_dots = 25;

canvas = $(“#canvas”)[0];
context = canvas.getContext(“2d”);
var dots = new Array();
var drag_i = -1;

var this_dot = {};
for (var i=0; i < total_dots; i++){ var this_dot = { x: Math.random()*canvas.width, y: Math.random()*canvas.height, width:canvas.width, height: canvas.height, radius:Math.random()*20+10 }; dots.push(this_dot); } draw(); $("#canvas").mousedown(function (event) { var dx, dy, dist; for (var i=0; i < dots.length; i++){ dx = event.pageX - this.offsetLeft - dots[i].x; dy = event.pageY - this.offsetTop - dots[i].y; dist = Math.sqrt(dx * dx + dy * dy); if(dist < radius) { drag = true; drag_i = i clickX = dx; clickY = dy; continue; } } }); $("#canvas").mouseup(function (event) { drag = false; drag_i = -1; }); $("#canvas").mousemove(function (event) { if(drag) { dots[drag_i].x = event.pageX - this.offsetLeft - clickX; dots[drag_i].y = event.pageY - this.offsetTop - clickY; draw(); } }); function draw() { context.clearRect(0, 0, canvas.width, canvas.height); for (var i=0; i < dots.length; i++){ context.beginPath(); context.arc(dots[i].x, dots[i].y, dots[i].radius, 0, Math.PI * 2, false); context.fill(); context.closePath(); } } }); [/cc]Follow the whole Interactive Physics Animations via Javascript & Canvas series.

Interactive Physics Animations Javascript Canvas 06

Here we’re going to get more into the interactive programming on these dots. We started with one dot that was draggable. This update applies a drag/drop code to each dot object with some logic to keep track of which dot is being dragged. This is quite a bit different than accomplishing the same thing in flash. Flash lets us have visual objects, but here in javascript we have all these objects and they are drawn on the stage/canvas every “frame”. The elements once drawn really don’t have any properties. So we’re attaching mousedown, mouseup and mousemove events to the canvas. In flash we would be applying a click event to the objects themselves. On mousedown we check coordinates to see if we’ve clicked on any of the dots. We also need a variable to store which one is being clicked or dragged at the moment, and this is pretty easy since we set up earlier to have an array holding all our dots, we’ll just use the index of that dot. With mousemove we drag the dot that’s been clicked using that index value, and then mouseup we drop it. interactive physics animations via javascript & canvas | 06.

[cc lang=”javascript”]
$(function () {
var canvas, context, width, height, x, y, radius = 25, clickX, clickY, drag = false;

canvas = $(“#canvas”)[0];
context = canvas.getContext(“2d”);
var dots = new Array();
var drag_i = -1;

var this_dot = {};
for (var i=0; i < 5; i++){ var this_dot = { x: Math.random()*canvas.width, y: Math.random()*canvas.height, width:canvas.width, height: canvas.height, radius:25}; dots.push(this_dot); } draw(); $("#canvas").mousedown(function (event) { var dx, dy, dist; for (var i=0; i < dots.length; i++){ dx = event.pageX - this.offsetLeft - dots[i].x; dy = event.pageY - this.offsetTop - dots[i].y; dist = Math.sqrt(dx * dx + dy * dy); if(dist < radius) { drag = true; drag_i = i clickX = dx; clickY = dy; continue; } } }); $("#canvas").mouseup(function (event) { drag = false; drag_i = -1; }); $("#canvas").mousemove(function (event) { if(drag) { dots[drag_i].x = event.pageX - this.offsetLeft - clickX; dots[drag_i].y = event.pageY - this.offsetTop - clickY; draw(); } }); function draw() { context.clearRect(0, 0, canvas.width, canvas.height); for (var i=0; i < dots.length; i++){ context.beginPath(); context.arc(dots[i].x, dots[i].y, dots[i].radius, 0, Math.PI * 2, false); context.fill(); context.closePath(); } } }); [/cc]Follow the whole Interactive Physics Animations via Javascript & Canvas series.

Interactive Physics Animations Javascript Canvas 05

Now we’ll apply this object oriented programming to each dot and give them all random placement. interactive physics animations via javascript & canvas | 05.

[cc lang=”javascript”]
$(function () {
var canvas, context, width, height, x, y, radius = 25, clickX, clickY, drag = false;

canvas = $(“#canvas”)[0];
context = canvas.getContext(“2d”);
var dots = new Array();

var this_dot = {};
for (var i=0; i < 5; i++){ var this_dot = { x: Math.random()*canvas.width, y: Math.random()*canvas.height, width:canvas.width, height: canvas.height, radius:25}; dots.push(this_dot); } draw(); $("#canvas").mousedown(function (event) { var dx, dy, dist; dx = event.pageX - this.offsetLeft - this_dot.x; dy = event.pageY - this.offsetTop - this_dot.y; dist = Math.sqrt(dx * dx + dy * dy); if(dist < radius) { drag = true; clickX = dx; clickY = dy; } else { drag = false; } }); $("#canvas").mouseup(function (event) { drag = false; }); $("#canvas").mousemove(function (event) { if(drag) { this_dot.x = event.pageX - this.offsetLeft - clickX; this_dot.y = event.pageY - this.offsetTop - clickY; draw(); } }); function draw() { context.clearRect(0, 0, canvas.width, canvas.height); for (var i=0; i < dots.length; i++){ context.beginPath(); context.arc(dots[i].x, dots[i].y, dots[i].radius, 0, Math.PI * 2, false); context.fill(); context.closePath(); } } }); [/cc]Follow the whole Interactive Physics Animations via Javascript & Canvas series.

Interactive Physics Animations Javascript Canvas 04

This time we won’t make the canvas any different visually, it’s more just cleaning up the code. We’re making the circle into a dot object, then later it will be easier to keep track of it (and any others). interactive physics animations via javascript & canvas | 04.

[cc lang=”javascript”]
$(function () {
var canvas, context, width, height, x, y, radius = 25, clickX, clickY, drag = false;

canvas = $(“#canvas”)[0];
context = canvas.getContext(“2d”);

var this_dot = {
x: Math.random()*canvas.width/5,
y: Math.random()*canvas.height/5,
width:canvas.width,
height: canvas.height,
radius:25};

draw();

$(“#canvas”).mousedown(function (event) {
var dx, dy, dist;
dx = event.pageX – this.offsetLeft – this_dot.x;
dy = event.pageY – this.offsetTop – this_dot.y;
dist = Math.sqrt(dx * dx + dy * dy);
if(dist < radius) { drag = true; clickX = dx; clickY = dy; } else { drag = false; } }); $("#canvas").mouseup(function (event) { drag = false; }); $("#canvas").mousemove(function (event) { if(drag) { this_dot.x = event.pageX - this.offsetLeft - clickX; this_dot.y = event.pageY - this.offsetTop - clickY; draw(); } }); function draw() { context.clearRect(0, 0, canvas.width, canvas.height); context.beginPath(); context.arc(this_dot.x, this_dot.y, this_dot.radius, 0, Math.PI * 2, false); context.arc(this_dot.x*2, this_dot.y*2, this_dot.radius, 0, Math.PI * 2, false); context.arc(this_dot.x*3, this_dot.y*3, this_dot.radius, 0, Math.PI * 2, false); context.arc(this_dot.x*4, this_dot.y*4, this_dot.radius, 0, Math.PI * 2, false); context.arc(this_dot.x*5, this_dot.y*5, this_dot.radius, 0, Math.PI * 2, false); context.arc(this_dot.x*6, this_dot.y*6, this_dot.radius, 0, Math.PI * 2, false); context.fill(); } }); [/cc]Follow the whole Interactive Physics Animations via Javascript & Canvas series.