cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External CSS

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing "font" or "ribbon" below.

Quick-add: + add another resource

Add External JavaScript

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

Quick-add: + add another resource

Code Indentation


Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

              * {
  margin: 0; padding: 0;
#canvas {
  display: block;
              window.onload = function(){
	var canvas = document.getElementById("canvas");
	var ctx = canvas.getContext("2d");
	//Lets resize the canvas to occupy the full page
	var W = window.innerWidth;
	var H = window.innerHeight;
	canvas.width = W;
	canvas.height = H;
	//Some variables
	var length, divergence, reduction, line_width, start_points = [];
	function init()
		//filling the canvas white
		ctx.fillStyle = "white";
		ctx.fillRect(0, 0, W, H);
		//Lets draw the trunk of the tree
		//lets randomise the variables
		//length of the trunk - 100-150
		length = 100 + Math.round(Math.random()*50);
		//angle at which branches will diverge - 10-60
		divergence = 10 + Math.round(Math.random()*50);
		//Every branch will be 0.75times of the previous one - 0.5-0.75
		//with 2 decimal points
		reduction = Math.round(50 + Math.random()*20)/100;
		//width of the branch/trunk
		line_width = 10;
		//This is the end point of the trunk, from where branches will diverge
		var trunk = {x: W/2, y: length+50, angle: 90};
		//It becomes the start point for branches
		start_points = []; //empty the start points on every init();
		//Y coordinates go positive downwards, hence they are inverted by deducting it
		//from the canvas height = H
		ctx.moveTo(trunk.x, H-50);
		ctx.lineTo(trunk.x, H-trunk.y);
		ctx.strokeStyle = "brown";
		ctx.lineWidth = line_width;
	//Lets draw the branches now
	function branches()
		//reducing line_width and length
		length = length * reduction;
		line_width = line_width * reduction;
		ctx.lineWidth = line_width;
		var new_start_points = [];
		for(var i = 0; i < start_points.length; i++)
			var sp = start_points[i];
			//2 branches will come out of every start point. Hence there will be
			//2 end points. There is a difference in the divergence.
			var ep1 = get_endpoint(sp.x, sp.y, sp.angle+divergence, length);
			var ep2 = get_endpoint(sp.x, sp.y, sp.angle-divergence, length);
			//drawing the branches now
			ctx.moveTo(sp.x, H-sp.y);
			ctx.lineTo(ep1.x, H-ep1.y);
			ctx.moveTo(sp.x, H-sp.y);
			ctx.lineTo(ep2.x, H-ep2.y);
			//Time to make this function recursive to draw more branches
			ep1.angle = sp.angle+divergence;
			ep2.angle = sp.angle-divergence;
		//Lets add some more color
		if(length < 10) ctx.strokeStyle = "green";
		else ctx.strokeStyle = "brown";
		start_points = new_start_points;
		//recursive call - only if length is more than 2.
		//Else it will fall in an long loop
		if(length > 2) setTimeout(branches, 50);
		else setTimeout(init, 500);
	function get_endpoint(x, y, a, length)
		//This function will calculate the end points based on simple vectors
		//You can read about basic vectors from this link
		var epx = x + length * Math.cos(a*Math.PI/180);
		var epy = y + length * Math.sin(a*Math.PI/180);
		return {x: epx, y: epy};
Loading ..................