Recursive construction of a Sierpinski carpet by using the HTML5 canvas element and JavaScript

A Sierpinski carpet is a plane fractal. It's named after the Polish mathematician Wacław Sierpiński. This demo shows how to construct a Sierpinski carpet by using JavaScript and the HTML5 canvas element. You can interactively modify the recursion depth between 0 and 6. Have a look at the Wikipedia article for further information.

Your browser doesn't support the "canvas" tag.
Recursion depth:

JavaScript source code

/* 
 * Copyright 2012-2013 by Steffen A. Jakob (http://www.jakob.at/)
 * All rights reserved.
 */

// Constructor which initializes the canvas widget
function Sierpinski() {
    this.w = 600;
    this.h = this.w;
    this.canvas = document.getElementById("canvas");
    this.context = this.canvas.getContext("2d");
    this.maxDepth = 6;
    this.canvas.width = this.w;
    this.canvas.height = this.h;
}

// Draw a Sierpinski carpet with the given recursion depth
Sierpinski.prototype.drawSierpinskiCarpet = function(depth)
{
    this.context.clearRect(0, 0, this.w, this.h);

    // Draw the initial square (white)
    this.context.fillStyle = "#ffffff";
    this.drawSquare(0, 0, this.w);

    this.context.fillStyle = "#000000";
    if (depth > this.maxDepth) { // make sure that depth doesn't get too high
        depth = this.maxDepth;
        document.getElementById('depthStepper').value = depth;
    }
    this.removeCenterSquare(0, 0, this.w, depth);
};

// Draw a filled rectangle which is defined by the upper left corner
// x,y and its size
Sierpinski.prototype.drawSquare = function(x, y, size) {
    this.context.fillRect(x, y, size, size);
};

// Cut the square into 9 subsquares. Remove the center square (draw black)
// and execute this process for the remaining 8 subsquares.
Sierpinski.prototype.removeCenterSquare = function(x, y, size, depth) {
    if (depth > 0) {
        var subSize = size/3;
        
        // Remove the center square
        this.drawSquare(x+subSize, y+subSize, subSize);

        if (depth > 1) {
            // Recursively remove center square for the
            // remaining filled squares
            for (var i = 0; i < 3; ++i) {
                for (var j = 0; j < 3; ++j) {
                    if (i !== 1 || j !== 1) {
                        this.removeCenterSquare(x + i*subSize, y + j*subSize, subSize, depth - 1);                        
                    }
                }
            }
        }
    }
};