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.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.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.

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,

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.

Interactive Physics Animations Javascript Canvas 03

This iteration really isn’t that big, but I figured baby steps may be the way to go here. We’re just giving the first circle a random position. The other dots are positioned relative to the first one still. interactive physics animations via javascript & canvas | 03.

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

canvas = \$(“#canvas”)[0];
context = canvas.getContext(“2d”);
width = canvas.width;
height = canvas.height;
x = Math.random()*canvas.width/5;
y = Math.random()*canvas.height/5;
draw();

\$(“#canvas”).mousedown(function (event) {
var dx, dy, dist;
dx = event.pageX – this.offsetLeft – x;
dy = event.pageY – this.offsetTop – 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) { x = event.pageX - this.offsetLeft - clickX; y = event.pageY - this.offsetTop - clickY; draw(); } }); function draw() { context.clearRect(0, 0, width, height); context.beginPath(); context.arc(x, y, radius, 0, Math.PI * 2, false); context.arc(x*2, y*2, radius, 0, Math.PI * 2, false); context.arc(x*3, y*3, radius, 0, Math.PI * 2, false); context.arc(x*4, y*4, radius, 0, Math.PI * 2, false); context.arc(x*5, y*5, radius, 0, Math.PI * 2, false); context.arc(x*6, y*6, radius, 0, Math.PI * 2, false); context.fill(); } }); [/cc] Follow the whole Interactive Physics Animations via Javascript & Canvas series.

Interactive Javascript Canvas Series

I’ve been playing with canvas and different javascript drawing libraries a lot lately in my projects at work. I’ve been antsy to play with the techniques I’ve learned and apply it to some more interactive experiments. Much like my last series on generative art in flash, but this will all be in javascript! In case you’re extra interested in this type of stuff, go check out Keith Peters’ month long exploration into javascript on his bit-101 site, he’s did some great stuff, and I learned a lot from that. I’m not going to sign up to post every day or anything, but I’ll keep it going for a while at least. So, stay tuned! And let me know if you’re really wanting to see this go into any specific directions.

Here goes nothin’