<p>Use arrow keys to move</p>
html{
background-color: black;
color: #ccc;
text-align: center;
overflow: hidden;
}
xxxxxxxxxx
// Interesting fact! These are not more colorful when moving, that is an optical illusion.
// requestAnimFrame() As explained by Mr Irish: http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
var starfield = (function() {
// Variables - a quantity which during a calculation is assumed to vary or be capable of varying in value
var stars = [],
star_density = 25,
velocity = {x:0, y: 0},
star_colors = ["rgba(0,0,0,.5)", "#ffe9c4", "#d4fbff"],
stars_bg = "rgba(0,0,0,.5)",
frame,
star_canvas,
star_context,
viewport_width,
viewport_height;
function initialize() {
// Make canvas
star_canvas = document.createElement('canvas');
star_context = star_canvas.getContext('2d');
// Get viewport size and resize canvas
resize_canvas();
// Draw all the stars, I decided stars come in units of 10
for (var i = 0; i < (star_density*10); i++) {
var rad = Math.random() * 2;
create_star(rad);
// twice as many small stars as big
var rad = Math.random();
create_star(rad);
create_star(rad);
}
// Put the canvas on the page
document.body.appendChild(star_canvas);
// When you press keys stuff happens
document.addEventListener('keydown', function(e) {
e = e || window.event;
// We add to the existing velocity, this dampens the speed changes and makes changing directions more gradual just like flying a real spaceship... I imagine
if (e.keyCode == 39) {
velocity = {
x: velocity.x -5,
y: velocity.y
};
}
if (e.keyCode == 37) {
velocity = {
x: velocity.x +5,
y: velocity.y
};
}
if (e.keyCode == 40) {
velocity = {
x: velocity.x,
y: velocity.y -5
};
}
if (e.keyCode == 38) {
velocity = {
x: velocity.x,
y: velocity.y +5
};
}
}, false);
// Drawing our first frame starts the drawing loop
draw_frame();
function clear_canvas() {
// Each frame the canvas is painted wiht semi transparent black - this gives the trail effect behind moving stars
star_context.fillStyle=stars_bg;
star_context.fillRect(0, 0, viewport_width, viewport_height);
}
function draw_star() {
var s = stars.length;
// for every star
while(s--) {
var star = stars[s];
// update individual stars position
star.update();
// render the star to the canvas
star.render(star_context);
}
}
function create_star(rad) {
// I don't really need a function for create_star, but reads better and easy to expand upon
stars.push(new star(rad));
}
function draw_frame() {
clear_canvas();
// The infinate loop!
frame = requestAnimFrame(draw_frame);
draw_star();
}
}
function resize_canvas(){
viewport_width = window.innerWidth;
viewport_height = window.innerHeight;
star_canvas.width = viewport_width;
star_canvas.height = viewport_height;
}
var star = function(rad) {
this.alpha = Math.round((Math.random() * 100 - 70) + 70); // Random brightness
this.radius = rad || Math.random() * 2; // Radius
this.color = star_colors[Math.round(Math.random() * star_colors.length)]; // Random color from array
this.pos = {
// Initial random position
x: Math.random() * viewport_width,
y: Math.random() * viewport_height
};
};
star.prototype = {
update: function() {
// Depending on the radius the star will move at a differnt speed (slower where a greater perception of depth)
// Yes! 3 is a magic number :)
this.pos.y += velocity.y === 0 ? velocity.y : (velocity.y / (3 - this.radius));
this.pos.x += velocity.x === 0 ? velocity.x : (velocity.x / (3 - this.radius));
// Keep the stars on the canvas
if(this.pos.y > viewport_height){
this.pos.y = 0;
} else if(this.pos.y < 0){
this.pos.y = viewport_height;
}
// Keep the stars on the canvas in a different direction
if(this.pos.x > viewport_width){
this.pos.x = 0;
} else if(this.pos.x < 0){
this.pos.x = viewport_width;
}
// Dampen the velocity, ie slow down when you stop telling it to move
velocity.x = velocity.x /1.00005;
velocity.y = velocity.y /1.00005;
},
render: function(context) {
// Draw the star at its current position
var x = Math.round(this.pos.x),
y = Math.round(this.pos.y);
context.save();
context.globalCompositeOperation = 'lighter';
context.globalAlpha = this.alpha;
context.fillStyle = this.color;
context.beginPath();
context.moveTo(x, y);
context.arc(x, y, this.radius, 0, Math.PI * 2, true);
context.closePath();
context.fill();
context.restore();
}
};
return {
// Always kick things off with a really cool function name!
lets_roll: initialize
};
})();
starfield.lets_roll();