Interactive Physics Animations Javascript Canvas 14

Here is an update to allow the end user to create more dots. A good way to do that is to just let users click on the canvas, and if they click a dot, drag it, if they don’t click a dot, create a new dot at the point of click. I moved the dot creation into it’s own function and we can use that as our constructor for every dot. It has settings we can send in, but the defaults are set to pick random values. This could also be used to create a particle emitter of sorts, but for now it’s just creating a dot on clicking the blank canvas. interactive physics animations via javascript & canvas | 14.

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

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

var this_dot = {};
for (var i=0; i < total_dots; i++){ createDot(); } function createDot(x, y, r, vx, vy){ var this_dot = { x: typeof(x) != 'undefined' ? x : Math.random()*canvas.width, y: typeof(y) != 'undefined' ? y : Math.random()*canvas.height, radius: typeof(r) != 'undefined' ? r : Math.random()*20+10, vx: typeof(vx) != 'undefined' ? vx : Math.random()*30-10, vy: typeof(vy) != 'undefined' ? vy : Math.random()*30-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; } } //none clicked if (!drag) { createDot(event.pageX - this.offsetLeft, event.pageY - this.offsetTop); } }); $("#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.vx *= friction; this_dot.vy = this_dot.vy * friction + gravity; 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);$("#gravity").click(function(){ if($("#gravity").is(':checked')){ gravity = 2; } else{ gravity = 0; } }); }); [/cc]Follow the whole Interactive Physics Animations via Javascript & Canvas series.

Interactive Physics Animations Javascript Canvas 13

Now that we have gravity we’re really seeing some natural looking movement. Yet, it’s still missing something. In the real world we have friction or drag (or even air resistance) on everything. Without this friction it’s like these balls are moving in space. Even when they bounce on the walls they don’t loose any velocity, it’s just reversed. Typically, there should be a dampening effect that lessens the velocity by a fraction because it looses some speed in turning around on the wall. In this step we’re decreasing the velocity of x and y slightly every frame with a friction variable we’ve set to .98. Over time we see the velocity lessen and the dots move slower and slower until they come to a stop. e’re also updating the bounce variable from -1 to -.96, just to give a sense that changing direction lessens the velocity. interactive physics animations via javascript & canvas | 13.

[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 = -.96;
var gravity = 2;
var friction = .98;

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.vx *= friction; this_dot.vy = this_dot.vy * friction + gravity; 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);$("#gravity").click(function(){ if($("#gravity").is(':checked')){ gravity = 2; } else{ gravity = 0; } }); }); [/cc]Follow the whole Interactive Physics Animations via Javascript & Canvas series.

Interactive Physics Animations Javascript Canvas 12

Adding gravity! Here we’ve adjusting the y velocity in every frame with the force of gravity. It’s fun to play with options and see how they are affecting the animation and the physics, so I’ve also got a checkbox that will toggle gravity to either a vlaue of 2 or 0. interactive physics animations via javascript & canvas | 12.

[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;
var gravity = 2;

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 + gravity; 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);$("#gravity").click(function(){ if($("#gravity").is(':checked')){ gravity = 2; } else{ gravity = 0; } }); }); [/cc]Follow the whole Interactive Physics Animations via Javascript & Canvas series.

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.

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.