Simple Canvas Examples

In an earlier post I talked about how I added the ability to include simple JS examples into my blog pages. I started working on some new code examples, and realized I want to be able to draw things as well. So now I added a class for automatically running javascript that draws onto a canvas. The idea is to be able to enter code into a post using a pre tag of the following form.

<pre class="drawable prettyprint lang-javascript linenums">
drawing.fillRect(0,0,25,25);
</pre>

and have it appear with a canvas area below it as:

The drawable class triggers the script that builds the canvas. The other classes just make the code look nice. All of the code inside the pre tags is run with two special variables. canvas has the newly inserted canvas element, and drawing has the 2d context for that canvas.

By default the inserted canvas is 400 x 300 but that is often too big, so two attributes can be used to set the width and height of the inserted canvas. So that

<pre class="drawable prettyprint lang-javascript linenums" data-canvas-width="75" data-canvas-height="75">
drawing.fillRect(0,0,25,25);
</pre>

will show up as:

Adding a log below the canvas is as easy as adding the loggable class to the pre tag.

<pre class="drawable loggable prettyprint lang-javascript linenums" data-canvas-width="75" data-canvas-height="75">
drawing.fillRect(0,0,25,25);
log('with logger')
</pre>

The code to process these drawable sections is like the code for processing runnable, but i realized i would like to have some shared code on the page. So I updated the documentReady handler to grab some shared code:

var sharedCode = "";

$('.shared').each(function(index,element){

  sharedCode += $(element).text();
  sharedCode += "\n";
});

then I process the drawing elements:

$('.drawable').each(function(index,element){
    var code = $(element).text();
    var width = $(element).data('canvas-width') || 400;
    var height = $(element).data('canvas-height') || 300;

    code = sharedCode +
           "var canvas = document.getElementById('canvas-"+index+"');\n"+
           "var drawing = canvas.getContext('2d');\n"+
            "drawing.fillStyle = \"#000\";\n" +
            code;

    var newHtml = '<canvas id="canvas-'+index+'" width="'+width+'" height="'+height+'"></canvas>';

    if($(element).hasClass('loggable')) {
        code = "function log(str){$('#log-"+index+"').append(str+'\\n');}\n"+code;
        newHtml = newHtml + '<pre id="log-'+index+'"></pre>';
    }

    $(newHtml).insertAfter(element);

    try
    {
      eval(code);
    }
    catch(err)
    {
      $('#log-'+index).append(err.message+'\n');
    }
});

as with the code to process runnable code examples, this code just finds all of the drawable elements gets their content, augments that content and evaluates it. A canvas and pre element are also added to the page for each drawable element.

The default fill style is set to black to make it easy to draw in examples.

javascript canvas