Fun with HTML5 Canvas: Free Hand Drawing
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)