HTML5 and JavaScript - Sierpinski Triangle

06.07.2013

HTML5 and JavaScript - Draw a Sierpinski Triangle on a Canvas

The following article describes how to draw lines into the 2D context of an HTML5 canvas with JavaScript. As example I use the Sierpinski Triangle (Sierpinski Curve). I will give a short description of the algorithm which is used to draw the Sierpinski curve and show how to use the combination of JavaScript and the HTML5 canvas element.

The following image is not an image. It is an HTML canvas where I draw the Sierpinski triangle with JavaScript.

Your browser does not support the HTML5 canvas tag.

The Sierpinski triangle is a kind of fractal which is created by a recursive rule:

  • Draw an equilateral triangle
  • Search the middle point of every line of the triangle
  • Connect the middle points with three new lines
  • Repeat the last two steps with the new triangles, until the exit condition is reached

The source code of a first version of the algorithm can be found in the following JavaScript listing:

<script  type="text/javascript">

var width = 600;
var height = 600;
var size = 500;

function sierpinski(Ax,Ay,Bx,By,Cx,Cy,d,ctx) {
	if(d>0) {
	    var pointAx = (Bx + Cx) / 2;
		var pointAy = (By + Cy) / 2;

		var pointBx = (Ax + Cx) / 2;
		var pointBy = (Ay + Cy) / 2;

		var pointCx = (Ax + Bx) / 2;
		var pointCy = (Ay + By) / 2;

        var d2 = d-1;
        sierpinski(Ax,Ay,pointBx,pointBy,pointCx,pointCy,d2,ctx);
        sierpinski(pointCx,pointCy,pointAx,pointAy,Bx,By,d2,ctx);
        sierpinski(pointBx,pointBy,pointAx,pointAy,Cx,Cy,d2,ctx);
    }
    else {
		ctx.moveTo(Ax,Ay);
		ctx.lineTo(Bx,By);
		ctx.lineTo(Cx,Cy);
		ctx.lineTo(Ax,Ay);
    }
}


function drawSierpinski(ctx) {
	var midPointX = width/2;
	var midPointY = height/2;

	var deep = 4;

	var ri = (size/6) * Math.sqrt(3);
	var ru = (size/3) * Math.sqrt(3);

	var pointAx = midPointX-(size/2);
	var pointAy = midPointY+ri;

	var pointBx = midPointX+(size/2);
	var pointBy = midPointY+ri;

	var pointCx = midPointX;
	var pointCy = midPointY-ru;

	sierpinski(pointAx,pointAy,pointBx,pointBy,pointCx,pointCy,deep,ctx);
}

var ctx=document.getElementById("sierpinskiCanvas").getContext("2d");
drawSierpinski(ctx);
ctx.fillStyle = '#00FF00';
ctx.fill();
ctx.strokeStyle = 'black';
ctx.lineWidth = 2;
ctx.stroke();

</script>

The JavaScript code will be embedded in a HTML page later. The important parts are the methods drawSierpinski and sierpinkski.

The method drawSierpinski is used to calculate the start points for the triangle. The variables can be found in the following figure, where a is size:

The method drawSierpinski calls the method sierpinski recursively where the new middle points are calculated. The middle points are used to call the method sierpinski until the exit condition is reached. The exit is reached if d is equal 0.

Below the two methods the context ctx is determined from the HTML element canvas. (The canvas has the id sierpinskiCanvas). Before the Sierpinski triangle is painted with crx.stroke() the colors and line width is set.

That is all. If you embed the JavaScript into an HTML page with a canvas element as follows the Sierpinski triangle will be displayed.

<!DOCTYPE html>
<html>
<body>

<canvas id="sierpinskiCanvas" width="600" height="470" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

<script>
function sierpinski(Ax,Ay,Bx,By,Cx,Cy,d,ctx) {
 ...
}

...

</script>

</body>
</html>

The JavaScript code can be "optimized" so that the source code is shorter. The start points are calculated before and so the method drawSierpinski can be removed. Also the calculation of the middle points are moved into the call of the method sierpinkski. I think this code is shorter but not very comprehensible. It is up to you which version you prefer:

<!DOCTYPE html>
<html>
<body>

<canvas id="sierpinskiCanvas" width="600" height="470" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

<script>
function sierpinski(Ax,Ay,Bx,By,Cx,Cy,d,ctx) {
	if(d>0) {
        sierpinski(Ax,Ay,(Ax + Cx) / 2,(Ay + Cy) / 2,(Ax + Bx) / 2,(Ay + By) / 2,d-1,ctx);
        sierpinski((Ax + Bx) / 2,(Ay + By) / 2,(Bx + Cx) / 2,(By + Cy) / 2,Bx,By,d-1,ctx);
        sierpinski((Ax + Cx) / 2,(Ay + Cy) / 2,(Bx + Cx) / 2,(By + Cy) / 2,Cx,Cy,d-1,ctx);
    }
    else {
		ctx.moveTo(Ax,Ay);
		ctx.lineTo(Bx,By);
		ctx.lineTo(Cx,Cy);
		ctx.lineTo(Ax,Ay);
    }
}

var ctx=document.getElementById("sierpinskiCanvas").getContext("2d");
sierpinski(50,365.47,450,365.47,250,19.06,4,ctx);
ctx.fillStyle = '#00FF00';
ctx.fill();
ctx.strokeStyle = 'black';
ctx.lineWidth = 2;
ctx.stroke();
</script>

</body>
</html>

Please note that the shorter version is optimized for one size. If you change the size of the canvas the size of the triangle remains the same. If you use the other version the triangle changes its size when changing width and height.

I think with HTML5 it is now possible to draw images in a very easy way and embed them in an HTML page.

If you change the variable d (recusion deep) you can change the looking of the triangle. For d=2 the Sierpinski triangle looks as follows:

Your browser does not support the HTML5 canvas tag.