JavaScript Pulsing Binary Digit Background Effect, Best Implementation Method?

I coded I simple pulsing binary background effect for my personal website, and I was wanting to get input on the most efficient way to do this (I’m pretty sure my method is very lackluster and not the best way to go about it).

My end goal would be to create something less static and more free flowing. Instead of having a set list of digits to pulse (as I currently have) I would like to have all the digits have a chance to pulse, but looping through 25000 spans takes a good amount of resources on the client’s side and creates some undesirable lag.

Another goal of mine is to possibly make the digits fall like gravity is acting upon them, like a matrix style animation 😀

Any information on how to make this possible would be appreciated!

The code and JSFiddle is given: JSFiddle

document.write("<div id='binaryWrapper'>");
for (var i = 0; i < 25000; i++) {
    var digit = Math.round(Math.random());
    if (Math.random() > 0.03) {
        document.write("<span class='digit binaryDigit'>" + digit + "</span>");
    } else {
        document.write("<span class='digit binaryDigitColored'>" + digit + "</span>");
    } 
}
document.write("</div>");

var elements = document.getElementsByClassName("binaryDigitColored");
var staticElements = [];
for (var i = 0; i < elements.length; i++) {
    staticElements.push(elements[i]);
}
setInterval(function() {
    for (var i = 0; i < staticElements.length; i++) {
        if (Math.round(Math.random()) > 0.02) {
            staticElements[i].setAttribute("class", "binaryDigit");
        } else {
            var index = Math.round(Math.random() * (staticElements.length - 1));
            staticElements[index].removeAttribute("class", "binaryDigit");
            staticElements[index].setAttribute("class", "binaryDigitColored");
        }
    }
}, 500);
#binaryWrapper {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    word-wrap: break-word;
    z-index: -1;
    background-color: #000000;
}
.binaryDigit {
    color: #222222;
    transition: color 1s ease-in;
}
.binaryDigitColored {
    color:lightgreen;
    transition: color 1s ease-out;
}

Answer

I think you should look into js canvases, there are many resources online for them.

If you want to learn about programming in general then I would recommend you to try and do this using OOP, where every digit is an instantiated object. It would give some structure to your code.

If you just want a solution then here is some code: http://jsfiddle.net/jnuas/vxnpu7y0/

var c = document.getElementById("c");
var ctx = c.getContext("2d");

//making the canvas full screen
c.height = window.innerHeight;
c.width = window.innerWidth;

//chararr 
var chararr = "0123456789";
//converting the string into an array of single characters
chararr = chararr.split("");

var font_size = 10;
var columns = c.width/font_size; //number of columns for the rain
//an array of drops - one per column
var drops = [];
//x below is the x coordinate
//1 = y co-ordinate of the drop(same for every drop initially)
for(var x = 0; x < columns; x++)
    drops[x] = 1; 

//drawing the characters
function draw()
{
    //Black BG for the canvas
    //translucent BG to show trail
    ctx.fillStyle = "rgba(0, 0, 0, 0.05)";
    ctx.fillRect(0, 0, c.width, c.height);
    
    ctx.fillStyle = "#0F0"; //green text
    ctx.font = font_size + "px arial";
    //looping over drops
    for(var i = 0; i < drops.length; i++)
    {
        //a random chararr character to print
        var text = chararr[Math.floor(Math.random()*chararr.length)];
        //x = i*font_size, y = value of drops[i]*font_size
        ctx.fillText(text, i*font_size, drops[i]*font_size);
        
        //sending the drop back to the top randomly after it has crossed the screen
        //adding a randomness to the reset to make the drops scattered on the Y axis
        if(drops[i]*font_size > c.height && Math.random() > 0.975)
            drops[i] = 0;
        
        //incrementing Y coordinate
        drops[i]++;
    }
}

setInterval(draw, 33);