Fun with HTML5 Canvas: Free Hand Drawing

HTML5CanvasJavaScriptjQueryDrawing

Creating an interactive free hand drawing application with HTML5 Canvas and JavaScript

Fun with HTML5 Canvas: Free Hand Drawing

HTML5 Canvas opens up exciting possibilities for interactive content directly in the browser. One of the most intuitive applications is a simple drawing tool that allows users to sketch freely using their mouse or touch input.

Basic Implementation

Creating a free hand drawing app with HTML5 Canvas is surprisingly straightforward. Here's the basic structure we need:

<canvas id="drawingCanvas" width="800" height="600"></canvas>
$(document).ready(function() {
  // Canvas setup
  var canvas = document.getElementById('drawingCanvas');
  var ctx = canvas.getContext('2d');
  
  // Drawing state
  var isDrawing = false;
  var lastX = 0;
  var lastY = 0;
  
  // Set initial drawing style
  ctx.lineWidth = 5;
  ctx.lineJoin = 'round';
  ctx.lineCap = 'round';
  ctx.strokeStyle = '#000';
  
  // Event listeners for mouse/touch interactions
  $(canvas).mousedown(function(e) {
    isDrawing = true;
    lastX = e.pageX - canvas.offsetLeft;
    lastY = e.pageY - canvas.offsetTop;
  });
  
  $(canvas).mousemove(function(e) {
    if (isDrawing) {
      var currentX = e.pageX - canvas.offsetLeft;
      var currentY = e.pageY - canvas.offsetTop;
      
      draw(lastX, lastY, currentX, currentY);
      
      lastX = currentX;
      lastY = currentY;
    }
  });
  
  $(document).mouseup(function() {
    isDrawing = false;
  });
  
  // Drawing function
  function draw(fromX, fromY, toX, toY) {
    ctx.beginPath();
    ctx.moveTo(fromX, fromY);
    ctx.lineTo(toX, toY);
    ctx.stroke();
  }
});

This basic implementation tracks mouse movements and draws lines on the canvas accordingly.

Enhanced Features

To make our drawing application more useful and engaging, we can add several enhanced features:

1. Color Picker

$('#colorPicker').change(function() {
  ctx.strokeStyle = $(this).val();
});

2. Brush Size Control

$('#brushSize').on('input', function() {
  ctx.lineWidth = $(this).val();
});

3. Clear Canvas Button

$('#clearCanvas').click(function() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
});

4. Save Drawing as Image

$('#saveImage').click(function() {
  var dataURL = canvas.toDataURL('image/png');
  var link = document.createElement('a');
  link.href = dataURL;
  link.download = 'drawing.png';
  link.click();
});

Handling Touch Events

To make our drawing app work on mobile devices, we need to handle touch events:

canvas.addEventListener('touchstart', function(e) {
  e.preventDefault();
  var touch = e.touches[0];
  var mouseEvent = new MouseEvent('mousedown', {
    clientX: touch.clientX,
    clientY: touch.clientY
  });
  canvas.dispatchEvent(mouseEvent);
}, false);

canvas.addEventListener('touchmove', function(e) {
  e.preventDefault();
  var touch = e.touches[0];
  var mouseEvent = new MouseEvent('mousemove', {
    clientX: touch.clientX,
    clientY: touch.clientY
  });
  canvas.dispatchEvent(mouseEvent);
}, false);

canvas.addEventListener('touchend', function(e) {
  var mouseEvent = new MouseEvent('mouseup', {});
  canvas.dispatchEvent(mouseEvent);
}, false);

Line Smoothing

One challenge with free hand drawing is that lines can appear jagged. We can implement a simple smoothing algorithm:

// Instead of the basic draw function
function draw(fromX, fromY, toX, toY) {
  // Store points for line smoothing
  points.push({ x: toX, y: toY });
  
  if (points.length > 3) {
    // Get average of the last 3 points
    var xc = (points[points.length-2].x + points[points.length-1].x) / 2;
    var yc = (points[points.length-2].y + points[points.length-1].y) / 2;
    
    // Draw a curve instead of a straight line
    ctx.beginPath();
    ctx.moveTo(points[points.length-3].x, points[points.length-3].y);
    ctx.quadraticCurveTo(points[points.length-2].x, points[points.length-2].y, xc, yc);
    ctx.stroke();
  }
}

Pressure Sensitivity

For devices that support it, we can add pressure sensitivity to our drawing app:

canvas.addEventListener('pointerdown', function(e) {
  isDrawing = true;
  lastX = e.offsetX;
  lastY = e.offsetY;
  lastPressure = e.pressure;
});

canvas.addEventListener('pointermove', function(e) {
  if (isDrawing) {
    ctx.lineWidth = baseLineWidth * e.pressure;
    draw(lastX, lastY, e.offsetX, e.offsetY);
    lastX = e.offsetX;
    lastY = e.offsetY;
    lastPressure = e.pressure;
  }
});

Complete Demo

You can see the complete implementation in action in the demo below:

Conclusion

HTML5 Canvas provides a powerful and flexible platform for creating interactive drawing applications. With just a few lines of JavaScript, we can create a responsive drawing environment that works across devices.

This simple drawing app demonstrates the capabilities of Canvas and can serve as a foundation for more complex applications, such as collaborative whiteboards, annotation tools, or digital art applications.

Note: This article was migrated from the original A thousand nodes blog (2011)

Continue Reading

Browse All Articles