<canvas id="context" width="400px" height="400px">
Oops, your browser can't display this
</canvas>
<canvas id="container" width="400px" height="400px">
</canvas>
<script type="text/javascript">
var canvas = document.getElementById('container');
var context = canvas.getContext('2d');
context.fillStyle = '#CF0000';
context.fillRect(10, 10, 100, 100);
</script>
var canvas = document.getElementById('container');
var context = canvas.getContext('2d');
context.fillStyle = '#CF0000';
var x = 10;
setInterval(function() {
// clearRect is very important for animation
context.clearRect(0, 0, context.width, context.height);
if (x >= context.width) {
x = 20;
}
x += 5;
y = (Math.sin(x) * 10) + 150;
animate(x, y, context);
}, 40);
var animate = function(x, y, context) {
context.fillRect(x, y, 10, 10);
}
var Particle = function() {
this.x = 0;
this.y = 0;
this.xSpeed = 0;
this.ySpeed = 0;
this.angle = 0.0;
this.age = 0;
this.ageRate = 1;
this.ageLimit = 1000;
this.alive = true;
this.fillStyle = '#0032FF';
this.radius = 2;
};
Particle.prototype.update = function() {
if (this.alive) {
if (this.age <= this.ageLimit) {
this.x += this.xSpeed;
this.y += this.ySpeed;
this.age += this.ageRate;
} else {
this.alive = false;
}
}
};
var ParticleManager = function() {
this.particles = [];
if (arguments.length === 1) {
if (typeof arguments[0] === 'number' &&
arguments[0] > 0) {
this.particleCount = arguments[0];
}
} else {
this.particleCount = 200;
}
};
ParticleManager.prototype.initialize = function(origin) {
this.particles = [];
for (i = 0; i < this.particleCount; i++) {
this.particles.push(new Particle());
this.particles[i].x = origin.x;
this.particles[i].y = origin.y;
this.particles[i].age = 0;
this.particles[i].angle = (360 / this.particleCount) * i;
this.particles[i].xSpeed = Math.abs(Math.cos(this.particles[i].angle * (Math.PI/180))) * 3;
this.particles[i].ySpeed = Math.abs(Math.sin(this.particles[i].angle * (Math.PI/180))) * 3;
if (this.particles[i].angle >= 90 && this.particles[i].angle < 180) {
this.particles[i].ySpeed = -this.particles[i].ySpeed;
} else if (this.particles[i].angle >= 180 && this.particles[i].angle < 270) {
this.particles[i].ySpeed = -this.particles[i].ySpeed;
this.particles[i].xSpeed = -this.particles[i].xSpeed;
} else if (this.particles[i].angle >= 270 && this.particles[i].angle < 360) {
this.particles[i].xSpeed = -this.particles[i].xSpeed;
}
}
};
ParticleManager.prototype.update = function() {
for (i = 0; i < this.particleCount; i++ ) {
this.particles[i].update();
}
};
ParticleManager.prototype.drawParticles = function(fn) {
for (i = 0; i < this.particleCount; i++) {
fn(this.particles[i]);
}
};
var Renderer = function(context) {
var c = context;
this.clear = function() {
c.clearRect(0, 0, c.width, c.height);
};
this.drawParticle = function(particle) {
if (!particle.alive) {
return;
}
c.beginPath();
c.arc(particle.x, particle.y, particle.radius, 0, Math.PI*2, true);
c.closePath();
if (particle.hasOwnProperty('fillStyle') && particle.fillStyle !== '') {
c.fillStyle = particle.fillStyle;
c.fill();
}
if (particle.hasOwnProperty('strokeStyle') && particle.strokeStyle !== '') {
c.strokeStyle = particle.strokeStyle;
c.stroke();
}
};
};
<body>
<canvas id="container" width="400px" height="400px">Bummer, your browser doesn't support HTML5.</canvas>
<script type="text/javascript">
$(document).ready(function() {
var $container = $('#container');
var interval = '';
var context = document.getElementById('container').getContext('2d');
context.width = $container.width();
context.height = $container.height();
var renderer = new Renderer(context);
var particleManager = new ParticleManager(200);
// this ole boy does the actual rendering calls
var mainLoop = function(m, r) {
m.update();
r.clear();
m.drawParticles(r.drawParticle);
};
$container.bind('click', function(event) {
// we have to take the location of the container that was clicked into account.
// see Ben Nadel's post here: http://www.bennadel.com/blog/1871-Translating-Global-jQuery-Event-Coordinates-To-A-Local-Context.htm
var point = { x: event.pageX - $container.offset().left, y: event.pageY - $container.offset().top };
particleManager.initialize(point);
// if we don't clear the interval, we'll have very strange results
if (interval !== '') {
clearInterval(interval);
}
interval = setInterval(function() {
mainLoop(particleManager, renderer);
}, 40);
});
});
</script>
</body>
var ParticleManager = function() {
this.gravity = .3;
this.bounds = { x: 0, y: 0 };
this.friction = .4;
// ...
this.particles[i].xSpeed = (Math.random() * 20) - 10;
this.particles[i].ySpeed = (Math.random() * 20) - 10;
ParticleManager.prototype.update = function() {
for (var i = 0; i < this.particleCount; i++ ) {
if (this.particles[i].x >= this.bounds.x || this.particles[i].x <= 0) {
this.particles[i].xSpeed = -this.particles[i].xSpeed * this.friction;
}
if (this.particles[i].y >= this.bounds.y || this.particles[i].y <= 0) {
this.particles[i].verticalBounces++;
this.particles[i].ySpeed = -this.particles[i].ySpeed * this.friction;
}
this.particles[i].update();
this.particles[i].ySpeed -= this.gravity;
}
};