`<canvas>` - graphics drawing canvas
<canvas>
is a powerful tag introduced in HTML5 for dynamically drawing graphics, animations, or interactive content on web pages. It provides a complete drawing API through JavaScript, supporting pixel-level operations, making it suitable for scenarios like game development and data visualization.
Basic Usage of <canvas>
The <canvas>
tag itself is just a container; content must be drawn using JavaScript. Its basic syntax is as follows:
<canvas id="myCanvas" width="500" height="300"></canvas>
The width
and height
attributes define the dimensions of the canvas. If not set, the default width is 300px and the default height is 150px. It is recommended to always explicitly set these attributes to avoid distortion caused by CSS scaling.
Obtaining the Drawing Context
To draw on <canvas>
, you first need to obtain the rendering context. The 2D drawing context is the most commonly used:
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
getContext('2d')
returns a CanvasRenderingContext2D
object, which provides all the 2D drawing methods.
Drawing Basic Shapes
Rectangles
Canvas provides three methods for drawing rectangles:
// Fill a rectangle
ctx.fillStyle = 'blue';
ctx.fillRect(50, 50, 100, 75);
// Stroke a rectangle
ctx.strokeStyle = 'red';
ctx.lineWidth = 3;
ctx.strokeRect(200, 50, 100, 75);
// Clear a rectangular area
ctx.clearRect(80, 80, 40, 20);
Path Drawing
Complex shapes are created using paths:
// Draw a triangle
ctx.beginPath();
ctx.moveTo(100, 100); // Starting point
ctx.lineTo(150, 50);
ctx.lineTo(200, 100);
ctx.closePath(); // Automatically close the path
ctx.stroke();
// 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
Canvas offers rich styling options:
// Linear gradient
const gradient = ctx.createLinearGradient(0, 0, 200, 0);
gradient.addColorStop(0, 'red');
gradient.addColorStop(1, 'yellow');
ctx.fillStyle = gradient;
ctx.fillRect(50, 150, 200, 100);
// Shadow effects
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
ctx.fillRect(300, 150, 100, 100);
Text Drawing
Canvas can draw text with various styling options:
ctx.font = '30px Arial';
ctx.fillStyle = 'purple';
ctx.textAlign = 'center';
ctx.fillText('Hello Canvas', canvas.width/2, 50);
// Stroked text
ctx.font = 'bold 40px sans-serif';
ctx.strokeStyle = 'black';
ctx.lineWidth = 2;
ctx.strokeText('Stroke Text', 150, 120);
Image Operations
Canvas can draw, scale, and crop images:
const img = new Image();
img.src = 'example.jpg';
img.onload = function() {
// Draw the original image
ctx.drawImage(img, 10, 10);
// Draw scaled image
ctx.drawImage(img, 150, 10, 100, 80);
// Crop and draw part of the image
ctx.drawImage(img, 50, 50, 100, 100, 300, 10, 100, 100);
};
Animation Implementation
Smooth animations can be achieved using requestAnimationFrame
:
let x = 0;
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(x, 100, 50, 50);
x += 2;
if (x > canvas.width) x = 0;
requestAnimationFrame(animate);
}
animate();
Advanced Techniques
Saving and Restoring State
Canvas states (styles, transformations, etc.) can be managed using a stack:
ctx.fillStyle = 'red';
ctx.save(); // Save the current state
ctx.fillStyle = 'blue';
ctx.fillRect(50, 50, 100, 100);
ctx.restore(); // Restore the previously saved state
ctx.fillRect(200, 50, 100, 100); // Will use red fill
Transformation Operations
Canvas supports transformations like translation, rotation, and scaling:
ctx.fillStyle = 'orange';
ctx.translate(150, 150); // Move the origin
ctx.rotate(Math.PI / 4); // Rotate 45 degrees
ctx.fillRect(-50, -50, 100, 100); // Draw centered at the new origin
Pixel Manipulation
You can directly manipulate pixel data:
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
// Invert colors
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
}
ctx.putImageData(imageData, 0, 0);
Performance Optimization
For complex Canvas applications, performance optimization is crucial:
- Layered Rendering: Use multiple overlapping
<canvas>
elements to separate static and dynamic content. - Avoid Floating-Point Coordinates: Use integer coordinates to prevent blurring from sub-pixel rendering.
- Batch Operations: Minimize state changes (e.g., style changes).
- Offscreen Canvas: Pre-render complex graphics to a hidden canvas.
// Offscreen Canvas example
const offscreenCanvas = document.createElement('canvas');
const offscreenCtx = offscreenCanvas.getContext('2d');
// Pre-render complex graphics on the offscreen canvas
offscreenCtx.fillRect(0, 0, 100, 100);
// Draw the pre-rendered content on the main canvas
ctx.drawImage(offscreenCanvas, 0, 0);
Implementing Interactivity
Canvas itself has no built-in interactivity, but it can be achieved through event listeners:
canvas.addEventListener('click', function(event) {
const rect = canvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
if (ctx.isPointInPath(x, y)) {
alert('Clicked on the shape!');
}
});
WebGL Integration
<canvas>
also supports 3D graphics rendering via WebGL:
const gl = canvas.getContext('webgl');
if (gl) {
// WebGL code
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
}
Practical Application Examples
Drawing Charts
// Simple bar chart
const data = [30, 60, 90, 40, 70];
const barWidth = 50;
const spacing = 20;
ctx.fillStyle = 'steelblue';
data.forEach((value, index) => {
const x = index * (barWidth + spacing);
const height = value * 2;
ctx.fillRect(x, canvas.height - height, barWidth, height);
});
Drawing Board Application
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();
}
Compatibility and Limitations
Although modern browsers support <canvas>
, note the following:
- Older versions of IE (8 and below) do not support it.
- Canvas content is not part of the DOM and cannot be accessed via CSS selectors.
- Performance issues may arise when drawing a large number of objects.
- Blurring may occur on high-DPI devices and requires special handling:
// Handling high-DPI devices
const dpr = window.devicePixelRatio || 1;
canvas.style.width = canvas.width + 'px';
canvas.style.height = canvas.height + 'px';
canvas.width = canvas.width * dpr;
canvas.height = canvas.height * dpr;
ctx.scale(dpr, dpr);
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:<svg>-SVG矢量图形
下一篇:<map>-图像映射