var canvas = document.getElementById('art-board'); var context = canvas.getContext('2d'); var time = false; var circles = []; var loop = function(){ var now = new Date().getTime(); var d = now - (time || now); time = now; context.clearRect(0, 0, canvas.width, canvas.height); // draw for(var i = 0; i < circles.length; i++){ circles[i].update(d); circles[i].draw(); } requestAnimationFrame(loop); }; // circle var circle = function(options){ var circle = this; circle.settings = { x: 0, y: 0, radius: 10, orientation: 0, vector: { x: 0, y: 0 }, speed: 1, color: { red: 0, green: 0, blue: 0, alpha: 1} }; var newsettings = {}; for(var attrname in circle.settings){ newsettings[attrname] = circle.settings[attrname]; } for(var attrname in options){ newsettings[attrname] = options[attrname]; } circle.settings = newsettings; // update circle.update = function(d){ // update position circle.settings.x += circle.settings.vector.x * circle.settings.speed * d; circle.settings.y += circle.settings.vector.y * circle.settings.speed * d; if(circle.settings.x < 0 && circle.settings.vector.x < 0 || circle.settings.x > canvas.width && circle.settings.vector.x > 0){ circle.settings.vector.x = circle.settings.vector.x * -1; } if(circle.settings.y < 0 && circle.settings.vector.y < 0 || circle.settings.y > canvas.height && circle.settings.vector.y > 0){ circle.settings.vector.y = circle.settings.vector.y * -1; } }; // draw circle.draw = function(){ // gradient var gradient = context.createRadialGradient(circle.settings.x, circle.settings.y, circle.settings.radius /50, circle.settings.x, circle.settings.y, circle.settings.radius); //play with the below two color stop values (the .2 and .3) to change circle definition - should be a value between 0 and 1. I chose to use float values bc I like the 'orbs' look. Hint: If you make the first value a 0 and the second a 1, you'll achieve the smooth gradient effect. gradient.addColorStop(.2, 'rgba(' + circle.settings.color.red + ', ' + circle.settings.color.green + ', ' + circle.settings.color.blue + ', ' + circle.settings.color.alpha + ')'); gradient.addColorStop(.3, 'rgba(' + circle.settings.color.red + ', ' + circle.settings.color.green + ', ' + circle.settings.color.blue + ', ' + circle.settings.color.alpha / 20 + ')'); context.fillStyle = gradient; // draw context.beginPath(); context.arc(circle.settings.x, circle.settings.y, circle.settings.radius, 0, 2 * Math.PI, false); context.fill(); }; }; // create new var newcircles = function(){ // remove old circles = []; // create new circles for(var i = 0; i < 10; i++){ var newcircle = new circle({ x: Math.floor(Math.random() * canvas.width), y: Math.floor(Math.random() * canvas.height), radius: Math.floor(Math.random() * canvas.width), orientation: Math.floor(Math.random() * 360), vector: { x: Math.random() / 40, y: Math.random() / 40 }, speed: Math.random(), color: { red: 100 + Math.floor(Math.random() * 155), green: 100 + Math.floor(Math.random() * 155), blue: 100 + Math.floor(Math.random() * 155), alpha: 0.1 + Math.random() } }); // add new to array circles.push(newcircle); } }; // generate new window.addEventListener('click', newcircles, false); window.addEventListener('touchend', newcircles, false); newcircles(); // first frame loop();