Free Hand Drawing using HTML5 Canvas

This is an example of a simple free hand drawer built with HTML5 canvas.

by cranes

HTML

<h1>Free Hand Drawer using HTML5 Canvas</h1>

<span id="controls">Controls</span>
            <canvas id="canvas-display" width="400" height="400" ></canvas>
            <br/>
            <ul id="colors">
                <li style="background-color:black;"> </li>
                <li style="background-color:red;"> </li>
                <li style="background-color:green;"> </li>
                <li style="background-color:orange;"> </li>
                <li style="background-color:brown;"> </li>
                <li style="background-color:#d2232a;"> </li>
                <li style="background-color:#fcb017;"> </li>
                <li style="background-color:#fff460;"> </li>
                <li style="background-color:#9ecc3b;"> </li>
                <li style="background-color:#fcb017;"> </li>
                <li style="background-color:#fff460;"> </li>
                <li style="background-color:#F43059;"> </li>
                <li style="background-color:#82B82C;"> </li>
                <li style="background-color:#0099FF;"> </li>
                <li style="background-color:#ff00ff;"> </li>
            </ul>
            <br style="clear:both;"/>
            <br style="clear:both;"/>
            <div id="control-buttons">
                <div style="float:left;">
                <button id="undo" href="#" disabled="disabled">Undo</button>
                <button id="clear" href="#">Reset</button>
                <button id="export" href="#">Save as Image</button>
                </div>
                <div style="float:left;margin-left: 22px;text-align: center;width: 130px;">
                Brush Size:<br />
                <input name="brush" id="brush_size" type="range" value="5"  min="0" max="20" />
                </div>
            </div>
        <script type="text/javascript">
            $(document).ready(function(){
                $('#canvas-display').paintBrush();
                });
        </script>

CSS

h1 {
 font-size: 20px;
 font-weight: bold;   
}

#canvas-display {
      border: solid 1px greenyellow;
      cursor: crosshair;
      float: left;
      }

#colors {
      background-color: #fff;
      border: 1px solid #000000;
      display: none;
      float: left;
      left: -55px;
      margin-top: 10px;
      padding: 0;
      position: relative;
      width: 50px;
      }
  
#colors li {
      border: 1px solid #000000;
      height: 20px;
      width: 20px;
      cursor: pointer;
      float: left;
      margin: 1px;
      list-style: none;
      }
  
#colors li.selected {
      border: solid 1px #eee;
      }

#controls {
      background: none repeat scroll 0 0 grey;
      border: 1px solid;
      border-radius: 5px 5px 5px 5px;
      cursor: pointer;
      font-weight: bold;
      margin-left: -72px;
      opacity: 0.7;
      padding: 5px;
      position: relative;
      top: 5px;
  }
  
#control-buttons {
      background-color: gray;
      border: 1px solid #000000;
      border-radius: 5px 5px 5px 5px;
      display: none;
      float: left;
      margin-left: 1px;
      margin-top: -78px;
      opacity: 0.7;
      padding: 10px;
      position: relative;
      width: 378px;   
}

JavaScript

(function($) {
      $.fn.paintBrush = function(options) {
          var undoHistory = [];
              var settings = {
               'targetID' : 'canvas-display'
          },
  
              $this = $(this),
              o = {},
              ui = {},
          
          core = {
              init : function(options) {
                  ui.$loadParentDiv = o.targetID;
                  core.draw();
                  core.controls();
                  //core.toggleScripts();
              },
  
              canvasInit : function() {
                      context = document.getElementById("canvas-display").getContext("2d");
                      context.lineCap = "round";
                      //Fill it with white background
                      context.save();
                      context.fillStyle = '#fff';
                      context.fillRect(0, 0, context.canvas.width, context.canvas.height);
                      context.restore();
              },
              
              saveActions : function() {
                      var imgData = document.getElementById("canvas-display").toDataURL("image/png");
                      undoHistory.push(imgData);
                      $('#undo').removeAttr('disabled');
              
              },
              
              undoDraw : function() {
                  if(undoHistory.length > 0){
                      var undoImg = new Image();
                      $(undoImg).load(function(){
                          var context = document.getElementById("canvas-display").getContext("2d");
                          context.drawImage(undoImg, 0,0);
                      });
                      undoImg.src = undoHistory.pop();
                      if(undoHistory.length == 0)
                          $('#undo').attr('disabled','disabled');
                  }                            
              },
  
              draw : function() {
                      var canvas, cntxt, top, left, draw, draw =...