Fundamentals of Canvas 2D Graphics Rendering
Core Concepts of Canvas
Canvas is an HTML5 element that provides a scriptable rendreing surface for 2D graphics. It allows dynamic generation of pixel-based images through JavaScript and serves as a foundational technology for web-based data visualization and interactive applications.
Distinction Between Canvas and SVG
- Canvas: A bitmap-based drawing API rendered through JavaScript. It operates as a single DOM element where all drawing is imperatively scripted.
- SVG: A vector-based XML format where graphics are composed of multiple DOM elements, enabling resolution-independent scaling and built-in event handling.
For performance with large datasets, Canvas is typically preferred. For interactive graphics requiring crisp scaling, SVG is often more suitable.
Initial Setup for Drawing
Basic usage involves creating the element, obtaining a drawing context, and issuing drawing commands.
<canvas id="drawSurface" width="500" height="300"></canvas>
<script>
const surface = document.getElementById('drawSurface');
const ctx = surface.getContext('2d');
ctx.moveTo(50, 75);
ctx.lineTo(250, 75);
ctx.stroke();
</script>
Important Considerations
- Default dimensions are 300 pixels wide by 150 pixels high.
- Width and height should be set via element attributes, not CSS, to avoid distortion.
- Line rendering defaults to 1px black, but anti-aliasing may cause visual thickness variations.
- Basic support starts from Internet Explorer 9.
Coordinate System
Canvas uses a W3C coordinate system where the origin (0,0) is at the top-left corner, with the X-axis increasing to the right and the Y-axis increasing downward.
Drawing Basic Shapes
Line Segments
Use moveTo(), lineTo(), and stroke() to draw lines.
ctx.beginPath();
ctx.moveTo(20, 30);
ctx.lineTo(180, 30);
ctx.lineWidth = 5;
ctx.strokeStyle = '#3498db';
ctx.stroke();
Polygons and Paths
Sequential lineTo() calls create polygonal paths. Use closePath() to automatically connect the last point back to the first.
ctx.beginPath();
ctx.moveTo(100, 50);
ctx.lineTo(200, 150);
ctx.lineTo(50, 150);
ctx.closePath(); // Creates triangle
ctx.lineWidth = 2;
ctx.stroke();
Rectangles
Multiple methods are available for rectangle drawing:
// Outline rectangle
ctx.strokeStyle = '#e74c3c';
ctx.strokeRect(50, 50, 150, 100);
// Filled rectangle
ctx.fillStyle = '#2ecc71';
ctx.fillRect(50, 200, 150, 100);
// Combined rectangle
ctx.fillStyle = '#f1c40f';
ctx.strokeStyle = '#c0392b';
ctx.lineWidth = 3;
ctx.fillRect(300, 50, 120, 80);
ctx.strokeRect(300, 50, 120, 80);
// Clear a rectangular area
ctx.clearRect(70, 70, 100, 50);
Circles and Arcs
Use arc() for circular shapes. Angles are specified in radians.
// Full circle
ctx.beginPath();
ctx.arc(200, 200, 60, 0, Math.PI * 2);
ctx.stroke();
// Semi-circle (top)
ctx.beginPath();
ctx.arc(200, 200, 60, 0, Math.PI, false);
ctx.closePath();
ctx.stroke();
// Arc segment
ctx.beginPath();
ctx.arc(350, 200, 60, 0.5, 2.2, false);
ctx.stroke();
The arcTo() method creates arcs tangent to two lines:
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.arcTo(150, 50, 150, 150, 40);
ctx.stroke();
Styling and Appearance
Line Customization
ctx.beginPath();
ctx.moveTo(50, 100);
ctx.lineTo(250, 100);
ctx.lineWidth = 8;
ctx.strokeStyle = '#9b59b6';
ctx.lineCap = 'round'; // Options: butt, round, square
ctx.stroke();
Corner Styling
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(150, 50);
ctx.lineTo(150, 120);
ctx.lineJoin = 'round'; // Options: miter, bevel, round
ctx.lineWidth = 10;
ctx.stroke();
Dashed Lines
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(250, 50);
ctx.setLineDash([10, 5]); // 10px dash, 5px gap
ctx.stroke();
// Get current dash pattern
const pattern = ctx.getLineDash();
// Set dash offset
ctx.lineDashOffset = 5;
Fill Operations
ctx.fillStyle = '#e67e22';
ctx.beginPath();
ctx.rect(50, 50, 200, 150);
ctx.fill();
Text Rendering
Basic Text Operations
ctx.font = 'bold 36px Arial';
ctx.fillStyle = '#2c3e50';
ctx.fillText('Hello Canvas', 50, 100);
ctx.strokeStyle = '#e74c3c';
ctx.lineWidth = 2;
ctx.strokeText('Outlined Text', 50, 160);
// Measure text dimensions
const metrics = ctx.measureText('Measurement');
console.log(metrics.width);
Text Alignment
// Horizontal alignment
ctx.textAlign = 'center'; // start, end, left, right, center
// Vertical alignment
ctx.textBaseline = 'middle'; // alphabetic, top, hanging, middle, bottom
ctx.fillText('Aligned Text', 200, 200);
Image Operations
Loading and Drawing Images
// Method 1: Create new Image object
const imgElement = new Image();
imgElement.src = 'image.jpg';
imgElement.onload = function() {
ctx.drawImage(imgElement, 50, 50);
};
// Method 2: Use existing DOM image
const domImage = document.getElementById('myImage');
ctx.drawImage(domImage, 100, 100, 150, 150); // With scaling
Image Cropping
// Parameters: image, sourceX, sourceY, sourceWidth, sourceHeight,
// destX, destY, destWidth, destHeight
ctx.drawImage(imgElement,
100, 50, // Source start
200, 150, // Source dimensions
50, 50, // Destination start
300, 200 // Destination dimensions
);