<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<canvas id="myCanvas"></canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var mask;
var pointCount = 500;
var str = "Hello.";
var fontStr = "bold 128pt Helvetica Neue, Helvetica, Arial, sans-serif";
ctx.font = fontStr;
ctx.textAlign = "center";
c.width = ctx.measureText(str).width;
c.height = 128; // Set to font size
var whitePixels = [];
var points = [];
var point = function(x,y,vx,vy){
this.x = x;
this.y = y;
this.vx = vx || 1;
this.vy = vy || 1;
}
point.prototype.update = function() {
ctx.beginPath();
ctx.fillStyle = "#95a5a6";
ctx.arc(this.x,this.y,1,0,2*Math.PI);
ctx.fill();
ctx.closePath();
// Change direction if running into black pixel
if (this.x+this.vx >= c.width || this.x+this.vx < 0 || mask.data[coordsToI(this.x+this.vx, this.y, mask.width)] != 255) {
this.vx *= -1;
this.x += this.vx*2;
}
if (this.y+this.vy >= c.height || this.y+this.vy < 0 || mask.data[coordsToI(this.x, this.y+this.vy, mask.width)] != 255) {
this.vy *= -1;
this.y += this.vy*2;
}
for (var k = 0, m = points.length; k<m; k++) {
if (points[k]===this) continue;
var d = Math.sqrt(Math.pow(this.x-points[k].x,2)+Math.pow(this.y-points[k].y,2));
if (d < 5) {
ctx.lineWidth = .2;
ctx.beginPath();
ctx.moveTo(this.x,this.y);
ctx.lineTo(points[k].x,points[k].y);
ctx.stroke();
}
if (d < 20) {
ctx.lineWidth = .1;
ctx.beginPath();
ctx.moveTo(this.x,this.y);
ctx.lineTo(points[k].x,points[k].y);
ctx.stroke();
}
}
this.x += this.vx;
this.y += this.vy;
}
function loop() {
ctx.clearRect(0,0,c.width,c.height);
for (var k = 0, m = points.length; k < m; k++) {
points[k].update();
}
}
function init() {
// Draw text
ctx.beginPath();
ctx.fillStyle = "#000";
ctx.rect(0,0,c.width,c.height);
ctx.fill();
ctx.font = fontStr;
ctx.textAlign = "left";
ctx.fillStyle = "#fff";
ctx.fillText(str,0,c.height/2+(c.height / 2));
ctx.closePath();
// Save mask
mask = ctx.getImageData(0,0,c.width,c.height);
// Draw background
ctx.clearRect(0,0,c.width,c.height);
// Save all white pixels in an array
for (var i = 0; i < mask.data.length; i += 4) {
if (mask.data[i] == 255 && mask.data[i+1] == 255 && mask.data[i+2] == 255 && mask.data[i+3] == 255) {
whitePixels.push([iToX(i,mask.width),iToY(i,mask.width)]);
}
}
for (var k = 0; k < pointCount; k++) {
addPoint();
}
}
function addPoint() {
var spawn = whitePixels[Math.floor(Math.random()*whitePixels.length)];
var p = new point(spawn[0],spawn[1], Math.floor(Math.random()*2-1), Math.floor(Math.random()*2-1));
points.push(p);
}
function iToX(i,w) {
return ((i%(4*w))/4);
}
function iToY(i,w) {
return (Math.floor(i/(4*w)));
}
function coordsToI(x,y,w) {
return ((mask.width*y)+x)*4;
}
setInterval(loop,50);
init();
</script>
html {
background:#ecf0f1;
}
canvas {
display:block;
margin:auto;
background:#ecf0f1;
}