Canvas drawing API (paths, rectangles, text, etc.)
Canvas is a powerful drawing tool in HTML5 that enables rich graphic rendering capabilities through its JavaScript API. It supports various drawing operations such as paths, rectangles, text, and more, making it suitable for scenarios like data visualization, game development, and image processing.
Path Drawing
Paths are the most fundamental way to draw in Canvas, combining a series of lines or curves to form any shape. Use beginPath()
to start a new path, moveTo()
to move the pen to a specified coordinate, lineTo()
to draw a straight line to a new coordinate, and finally stroke()
or fill()
to outline or fill the path.
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Draw a triangle
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(100, 50);
ctx.lineTo(75, 100);
ctx.closePath(); // Automatically close the path
ctx.strokeStyle = 'blue';
ctx.stroke();
Bezier curves can create smooth curves. Quadratic Bézier curves use quadraticCurveTo()
, while cubic Bézier curves use bezierCurveTo()
.
// Quadratic Bézier curve
ctx.beginPath();
ctx.moveTo(20, 20);
ctx.quadraticCurveTo(80, 100, 150, 20);
ctx.strokeStyle = 'red';
ctx.stroke();
// Cubic Bézier curve
ctx.beginPath();
ctx.moveTo(50, 150);
ctx.bezierCurveTo(100, 50, 150, 250, 200, 150);
ctx.strokeStyle = 'green';
ctx.stroke();
Rectangle Drawing
Canvas provides direct APIs for drawing rectangles, which are simpler than using paths. The rect()
method defines a rectangular path, fillRect()
directly draws a filled rectangle, strokeRect()
draws an outlined rectangle, and clearRect()
clears a rectangular area.
// Filled rectangle
ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';
ctx.fillRect(10, 10, 100, 80);
// Outlined rectangle
ctx.lineWidth = 3;
ctx.strokeStyle = '#00f';
ctx.strokeRect(150, 10, 100, 80);
// Clear an area
ctx.clearRect(180, 30, 40, 40);
Rounded rectangles require combining paths with the arcTo()
method:
function drawRoundedRect(x, y, width, height, radius) {
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
ctx.lineTo(x + width, y + height - radius);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
ctx.lineTo(x + radius, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
ctx.closePath();
ctx.stroke();
}
Text Drawing
Canvas supports two text-drawing methods: fillText()
for filled text and strokeText()
for outlined text. Use the font
property to set the font style, textAlign
to control horizontal alignment, and textBaseline
to control vertical alignment.
ctx.font = 'bold 24px Arial';
ctx.fillStyle = 'purple';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('Hello Canvas', canvas.width/2, 50);
ctx.font = 'italic 18px serif';
ctx.strokeStyle = 'black';
ctx.lineWidth = 1;
ctx.strokeText('Outlined text effect', 100, 100);
Measure text width using the measureText()
method:
const text = 'Measure text width';
const metrics = ctx.measureText(text);
console.log(`Text width: ${metrics.width}px`);
Styles and Colors
Canvas offers rich styling options. fillStyle
and strokeStyle
accept color strings, gradient objects, or pattern objects. Linear gradients use createLinearGradient()
, while radial gradients use createRadialGradient()
.
// Linear gradient
const gradient = ctx.createLinearGradient(0, 0, 200, 0);
gradient.addColorStop(0, 'red');
gradient.addColorStop(0.5, 'yellow');
gradient.addColorStop(1, 'green');
ctx.fillStyle = gradient;
ctx.fillRect(10, 10, 200, 100);
// Radial gradient
const radialGrad = ctx.createRadialGradient(100, 100, 10, 100, 100, 50);
radialGrad.addColorStop(0, 'white');
radialGrad.addColorStop(1, 'blue');
ctx.fillStyle = radialGrad;
ctx.arc(100, 100, 50, 0, Math.PI*2);
ctx.fill();
Image Operations
Canvas can draw images and apply various transformations. The drawImage()
method has three forms: basic drawing, scaled drawing, and sliced drawing.
const img = new Image();
img.src = 'example.jpg';
img.onload = function() {
// Basic drawing
ctx.drawImage(img, 0, 0);
// Scaled drawing
ctx.drawImage(img, 0, 0, img.width/2, img.height/2);
// Sliced drawing
ctx.drawImage(img,
10, 10, 100, 100, // Source image slice area
0, 0, 200, 200 // Target drawing area
);
};
Transformations and Compositing
Canvas supports various graphic transformations: translate()
to move the origin, rotate()
to rotate, scale()
to scale, and transform()
for matrix transformations. Use save()
and restore()
to save and restore the drawing state.
// Draw a rotated rectangle
ctx.save();
ctx.translate(150, 150);
ctx.rotate(Math.PI/4);
ctx.fillStyle = 'orange';
ctx.fillRect(-50, -50, 100, 100);
ctx.restore();
// Graphic compositing
ctx.globalCompositeOperation = 'xor';
ctx.fillStyle = 'red';
ctx.fillRect(100, 100, 100, 100);
ctx.fillStyle = 'blue';
ctx.fillRect(150, 150, 100, 100);
Animation Implementation
Canvas animations are achieved by continuously clearing and redrawing, typically optimized using requestAnimationFrame
.
let x = 0;
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(x, 50, 50, 50);
x += 2;
if(x > canvas.width) x = 0;
requestAnimationFrame(animate);
}
animate();
Performance Optimization
For complex drawings, consider the following optimization strategies:
- Use
offscreenCanvas
for offscreen rendering - Avoid frequently creating objects in animation loops
- Layer static content for separate drawing
- Use the
willReadFrequently
hint appropriately
// Offscreen Canvas example
const offscreen = new OffscreenCanvas(300, 150);
const offCtx = offscreen.getContext('2d');
// Draw complex graphics on the offscreen Canvas
offCtx.fillRect(0, 0, 300, 150);
// Draw the result onto the main Canvas
ctx.drawImage(offscreen, 0, 0);
Advanced Path Operations
Canvas also supports path clipping and hit detection. The clip()
method creates a clipping region, and isPointInPath()
detects whether a point is inside a path.
// Create a circular clipping region
ctx.beginPath();
ctx.arc(100, 100, 50, 0, Math.PI*2);
ctx.clip();
// Subsequent drawings will only appear within the clipped region
ctx.fillRect(0, 0, 200, 200);
// Hit detection
canvas.addEventListener('click', (e) => {
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
ctx.beginPath();
ctx.arc(100, 100, 50, 0, Math.PI*2);
if(ctx.isPointInPath(x, y)) {
alert('Clicked the circle!');
}
});
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:'