阿里云主机折上折
  • 微信号
Current Site:Index > Basic usage of the '<canvas>' tag

Basic usage of the '<canvas>' tag

Author:Chuan Chen 阅读数:35658人阅读 分类: HTML

<canvas> is a powerful element introduced in HTML5 that allows for dynamic drawing of graphics, animations, and interactive content via JavaScript. It provides a pixel-level drawing method, making it suitable for game development, data visualization, image processing, and other scenarios.

Basic Syntax of <canvas>

The syntax for the <canvas> tag is very simple—just declare it in HTML:

<canvas id="myCanvas" width="500" height="300"></canvas>
  • The id attribute is used to reference the element in JavaScript.
  • The width and height attributes define the dimensions of the canvas (in pixels). If not set, the default width is 300px, and the default height is 150px.

Obtaining the Drawing Context

To draw on <canvas>, you must first obtain its rendering context. Currently, two main contexts are supported: 2D and WebGL (3D). Here’s an example of obtaining a 2D context:

const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

getContext('2d') returns a CanvasRenderingContext2D object, which provides a rich set of drawing methods.

Drawing Basic Shapes

Drawing Rectangles

CanvasRenderingContext2D provides three methods for drawing rectangles:

// Fill a rectangle (color determined by fillStyle)
ctx.fillStyle = 'blue';
ctx.fillRect(50, 50, 100, 75);

// Stroke a rectangle (border color determined by strokeStyle)
ctx.strokeStyle = 'red';
ctx.lineWidth = 3;
ctx.strokeRect(200, 50, 100, 75);

// Clear a rectangular area (makes it transparent)
ctx.clearRect(80, 80, 40, 20);

Drawing Paths

Paths can be used to draw arbitrary shapes. The basic steps are:

  1. Call beginPath() to start a new path.
  2. Use path methods (e.g., moveTo(), lineTo()) to draw.
  3. Call stroke() or fill() to render.
// Draw a triangle
ctx.beginPath();
ctx.moveTo(100, 100);  // Starting point
ctx.lineTo(150, 50);   // Second edge
ctx.lineTo(200, 100);  // Third edge
ctx.closePath();       // Close the path (optional)
ctx.stroke();          // Stroke the path

// Draw a circle
ctx.beginPath();
ctx.arc(300, 200, 50, 0, Math.PI * 2); // (x, y, radius, start angle, end angle)
ctx.fillStyle = 'green';
ctx.fill();

Styles and Colors

Color Settings

ctx.fillStyle = 'orange';       // Color name
ctx.fillStyle = '#FFA500';      // Hexadecimal
ctx.fillStyle = 'rgb(255,165,0)'; // RGB
ctx.fillStyle = 'rgba(255,165,0,0.5)'; // With transparency

Line Styles

ctx.lineWidth = 5;          // Line width
ctx.lineCap = 'round';      // Line cap style (butt|round|square)
ctx.lineJoin = 'bevel';     // Corner style (miter|round|bevel)
ctx.setLineDash([10, 5]);   // Dash pattern (dash length, gap length)

Drawing Text

ctx.font = '30px Arial';    // Font style
ctx.fillStyle = 'black';
ctx.fillText('Hello Canvas', 50, 50); // Fill text

ctx.strokeStyle = 'blue';
ctx.strokeText('Hello Canvas', 50, 100); // Stroke text

Text alignment can be adjusted using the textAlign and textBaseline properties:

ctx.textAlign = 'center';   // left|right|center|start|end
ctx.textBaseline = 'middle'; // top|hanging|middle|alphabetic|ideographic|bottom

Image Operations

Drawing Images

const img = new Image();
img.src = 'example.jpg';
img.onload = function() {
  // Draw at original size
  ctx.drawImage(img, 50, 50);
  
  // Draw scaled
  ctx.drawImage(img, 200, 50, 100, 80);
  
  // Crop and draw
  ctx.drawImage(img, 
    10, 10, 100, 100,  // Source image crop area (sx, sy, sw, sh)
    300, 50, 150, 150  // Canvas drawing area (dx, dy, dw, dh)
  );
};

Pixel Manipulation

You can directly manipulate pixel data:

// Get pixel data
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data; // Uint8ClampedArray

// Modify pixels (RGBA format)
for (let i = 0; i < data.length; i += 4) {
  data[i] = 255 - data[i];     // R
  data[i+1] = 255 - data[i+1]; // G
  data[i+2] = 255 - data[i+2]; // B
  // Alpha channel remains unchanged
}

// Write back the modified pixels
ctx.putImageData(imageData, 0, 0);

Transformations and State Management

Coordinate Transformations

ctx.translate(100, 100);  // Move the origin
ctx.rotate(Math.PI / 4);  // Rotate 45 degrees
ctx.scale(1.5, 1.5);      // Scale

// Draw a rotated rectangle
ctx.fillStyle = 'purple';
ctx.fillRect(0, 0, 50, 30);

Saving and Restoring State

The save() and restore() methods save/restore the current drawing state (including styles, transformations, etc.):

ctx.fillStyle = 'red';
ctx.save();              // Save current state

ctx.fillStyle = 'blue';
ctx.translate(100, 100);
ctx.fillRect(0, 0, 50, 50); // Blue rectangle

ctx.restore();           // Restore previous state
ctx.fillRect(50, 50, 50, 50); // Red rectangle

Animation Implementation

Smooth animations can be achieved using requestAnimationFrame:

let x = 0;

function animate() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  
  ctx.fillStyle = 'red';
  ctx.fillRect(x, 100, 50, 50);
  
  x += 2;
  if (x > canvas.width) x = -50;
  
  requestAnimationFrame(animate);
}

animate();

Event Interaction

<canvas> is a DOM element and can have event listeners:

canvas.addEventListener('click', function(event) {
  const rect = canvas.getBoundingClientRect();
  const x = event.clientX - rect.left;
  const y = event.clientY - rect.top;
  
  ctx.beginPath();
  ctx.arc(x, y, 10, 0, Math.PI * 2);
  ctx.fillStyle = 'blue';
  ctx.fill();
});

Performance Optimization Tips

  1. Layered Rendering: Use multiple <canvas> elements to separate static and dynamic content.
  2. Minimize State Changes: Group drawing operations with the same style.
  3. Offscreen Rendering: Draw complex graphics in an offscreen canvas first, then copy to the main canvas.
  4. Use clearRect() Wisely: Only clear the area that needs updating.
// Offscreen rendering example
const offscreenCanvas = document.createElement('canvas');
offscreenCanvas.width = 100;
offscreenCanvas.height = 100;
const offscreenCtx = offscreenCanvas.getContext('2d');

// Draw complex graphics on the offscreen canvas
offscreenCtx.beginPath();
offscreenCtx.arc(50, 50, 40, 0, Math.PI * 2);
offscreenCtx.fillStyle = 'rgba(255,0,0,0.5)';
offscreenCtx.fill();

// Copy to the main canvas
ctx.drawImage(offscreenCanvas, 50, 50);

Practical Examples

Drawing a Chart

// Simple bar chart
const data = [30, 60, 90, 40, 70];
const barWidth = 50;
const spacing = 20;
let x = 50;

ctx.fillStyle = 'steelblue';
data.forEach(value => {
  const height = value * 2;
  ctx.fillRect(x, canvas.height - height, barWidth, height);
  x += barWidth + spacing;
});

// Add axes
ctx.beginPath();
ctx.moveTo(30, 30);
ctx.lineTo(30, canvas.height - 30);
ctx.lineTo(canvas.width - 30, canvas.height - 30);
ctx.strokeStyle = 'black';
ctx.stroke();

Simple Drawing Board

<canvas id="drawingCanvas" width="600" height="400"></canvas>
<script>
const canvas = document.getElementById('drawingCanvas');
const ctx = canvas.getContext('2d');
let isDrawing = false;

canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseout', stopDrawing);

function startDrawing(e) {
  isDrawing = true;
  draw(e);
}

function draw(e) {
  if (!isDrawing) return;
  
  ctx.lineWidth = 5;
  ctx.lineCap = 'round';
  ctx.strokeStyle = '#000';
  
  ctx.lineTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
  ctx.stroke();
  ctx.beginPath();
  ctx.moveTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
}

function stopDrawing() {
  isDrawing = false;
  ctx.beginPath();
}
</script>

Browser Compatibility Notes

While modern browsers support <canvas>, note the following:

  1. Always provide fallback content:
<canvas>
  <p>Your browser does not support Canvas. Please upgrade your browser.</p>
</canvas>
  1. IE9 and below do not support it. Use ExplorerCanvas as a polyfill.

  2. For mobile devices, handle touch events and high-resolution screens:

// Handle high-DPI screens
function setupCanvas(canvas) {
  const dpr = window.devicePixelRatio || 1;
  const rect = canvas.getBoundingClientRect();
  
  canvas.width = rect.width * dpr;
  canvas.height = rect.height * dpr;
  
  const ctx = canvas.getContext('2d');
  ctx.scale(dpr, dpr);
  
  return ctx;
}

const ctx = setupCanvas(document.getElementById('myCanvas'));

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.