Random Recursive Trees

This is an old demo which I wrote for the "Thank You" page for my first serious canvas project. For future demos, I will write my code along with explanatory text with the explicit intention of sharing how the demo works.

For this old thing, however, I will let the code speak for itself.

var ThanksTree = {
    init: function (ctx) {
        var txt;
        ctx.beginPath();
        ctx.lineWidth = 1;
        ctx.fillStyle = 'black';
        ctx.strokeStyle = Map.trunk;;
        ctx.font = "bold 15pt Tahoma";
        txt = 'Math.Random Canvas Trees';
        ctx.fillText(txt, 10, 30);
        ThanksTree.addBranch(470, 320, -1.7, 8);
        setInterval(ThanksTree.step, 20);
        ctx.beginPath();
        ctx.strokeStyle = Map.trunk;
        ctx.fillStyle = 'rgba(' + Math.round(50 + (200 * Math.random())) + ', ' + Math.round(50 + (200 * Math.random())) + ', 0,50)';
    },
    step: function (ctx) {
        var branch;
        for (var i = 0; i < ThanksTree.branches.length; i++) {
            branch = ThanksTree.branches[i];
            if (!ThanksTree.leavesOn) {
                branch.theta -= 0.05;
                branch.theta += 0.1 * Math.random();
            }
            ctx.beginPath();
            ctx.lineWidth = branch.width;
            ctx.moveTo(branch.x, branch.y);
            branch.x += Math.cos(branch.theta);
            branch.y += Math.sin(branch.theta);
            branch.length++;
            ctx.lineTo(branch.x, branch.y);
            ctx.stroke();
            if (branch.length > branch.width * 5 + 1 + branch.magic) {
                if (branch.width > 0.75) {
                    if (ThanksTree.leavesOn && branch.width < 1.2) {
                        ctx.fillStyle = 'rgba(' + Map.leaf.r + ',' + Map.leaf.g + ',' + Map.leaf.b + ',0.6)';
                        ctx.fillRect(branch.x - 4, branch.y - 4, 8, 8);
                    }
                    ThanksTree.addBranch(branch.x, branch.y, branch.theta + Math.random() * 2 - 1, branch.width * 0.8);
                    branch.width *= 0.8;
                    branch.length = 0;
                    branch.magic = Math.random() * 2;
                    if (!ThanksTree.leavesOn && branch.width < 1.5) {
                        ThanksTree.leavesOn = 1;
                    }
                } else {
                    ThanksTree.leavesOn = 0;
                    return false;
                    ThanksTree.branches = [];
                    ThanksTree.addBranch(50 + Math.random() * 800, 320, -1.8 + Math.random() / 2, 4 + 8 * Math.random());
                    ctx.beginPath();
                    ctx.strokeStyle = Map.trunk;
                    ctx.fillStyle = 'rgba(' + Math.round(50 + (200 * Math.random())) + ', ' + Math.round(50 + (200 * Math.random())) + ', 0,0.5)';
                    ThanksTree.leavesOn = 0;
                    break;
                }
            }
        }
        return true;
    },
    addBranch: function (x, y, t, w) {
        ThanksTree.branches.push({
            length: 0,
            x: x,
            y: y,
            theta: t,
            width: w,
            magic: Math.random() * 2
        });
    },
    leavesOn: 0,
    branches: []
};

var Map = {
    leaf: {
        r: 50 + Math.ceil(131 * Math.random()),
        g: 50 + Math.ceil(131 * Math.random()),
        b: 3
    },
    trunk: 'rgb(39, ' + Math.round(200 * Math.random()) + ', 0)'
};
var grow = 0;
var many;
var ctx
$(document).ready(function () {
    ctx = $("#trees")[0].getContext("2d");
    var index = Math.ceil(Math.random() * 1000);
    ThanksTree.branches = [];
    ThanksTree.addBranch(100 + Math.ceil(Math.random() * 400), 425, 3 * Math.PI / 2 - 0.2 + Math.random() * 0.4, 10 + Math.random() * 13);
    grow = setInterval(function () {
        if (!ThanksTree.step(ctx)) {
            ctx.beginPath();
            ctx.fillStyle = "rgba(255,255,255,0.5)";
            ctx.fillRect(0, 0, 600, 400);
            ThanksTree.branches = [];
            Map.leaf = {
                r: 50 + Math.ceil(131 * Math.random()),
                g: 50 + Math.ceil(131 * Math.random()),
                b: 3
            };
            Map.trunk = 'rgb(' + (10 + Math.round(15 * Math.random())) + ', ' + (20 + Math.round(30 * Math.random())) + ', 0)';
            ctx.strokeStyle = Map.trunk;
            ThanksTree.addBranch(100 + Math.ceil(Math.random() * 400), 425, 3 * Math.PI / 2 - 0.2 + Math.random() * 0.4, 10 + Math.random() * 13);
        }
    }, 5);
});

var Map = {leaf:{r:50 + Math.ceil(131 * Math.random()) , g: 50 + Math.ceil(131 * Math.random()), b: 3},
			trunk: 'rgb(39, ' + Math.round(200 * Math.random()) + ', 0)'};
	var grow = 0;
	var many;
	var ctx
	$(document).ready(function(){
		ctx = $("#trees")[0].getContext("2d");
		var index = Math.ceil(Math.random()*1000);
		ThanksTree.branches = [];
			ThanksTree.addBranch(100 + Math.ceil(Math.random()*400),425,3*Math.PI/2 - 0.2 + Math.random()*0.4,10 + Math.random()*13);
		grow = setInterval(function(){
			if(!ThanksTree.step(ctx)){
				setTimeout(function(){
					ctx.beginPath();
					ctx.fillStyle = "rgba(255,255,255,0.2)";
					ctx.fillRect(0,0,600,400);
					ThanksTree.branches = [];
					Map.leaf = {r:50 + Math.ceil(131 * Math.random()) , g: 50 + Math.ceil(131 * Math.random()), b: 3};
					Map.trunk = 'rgb(' + (10 + Math.round(15 * Math.random())) + ', ' + (20 + Math.round(30 * Math.random())) + ', 0)';
					ctx.strokeStyle = Map.trunk;
					ThanksTree.addBranch(100 + Math.ceil(Math.random()*400),425,3*Math.PI/2 - 0.2 + Math.random()*0.4,10 + Math.random()*13);
				}, 1500);
			}
		},5);
	});



`