6.1 Canvas 绘图基础

6.1 Canvas 绘图基础

Canvas 是 HTML5 中功能强大的绘图 API,它允许开发者通过 JavaScript 在网页上动态生成图形、动画和交互式内容。本节将详细介绍 Canvas 的基础绘图功能,帮助您快速掌握这一核心技术。

Canvas 基本设置

1. 创建 Canvas 元素

在 HTML 文档中添加 Canvas 元素:

<canvas id="myCanvas" width="500" height="300">
  您的浏览器不支持Canvas,请升级或更换浏览器
</canvas>
  • widthheight属性定义画布尺寸(单位:像素)
  • 不支持Canvas的浏览器会显示元素内的备用内容

2. 获取绘图上下文

通过JavaScript获取Canvas的2D绘图上下文:

const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
  • getContext('2d')返回2D渲染上下文对象
  • 所有绘图操作都通过这个上下文对象进行

基本绘图方法

1. 绘制矩形

Canvas提供了三种绘制矩形的方法:

// 填充矩形(实心)
ctx.fillStyle = 'blue';  // 设置填充颜色
ctx.fillRect(20, 20, 150, 100); // (x, y, width, height)

// 描边矩形(空心)
ctx.strokeStyle = 'red'; // 设置描边颜色
ctx.lineWidth = 3;       // 设置线宽
ctx.strokeRect(200, 20, 150, 100);

// 清除矩形区域
ctx.clearRect(50, 50, 100, 50); // 清除指定区域

2. 绘制路径

路径是Canvas中绘制复杂图形的基础:

// 开始新路径
ctx.beginPath();

// 绘制三角形
ctx.moveTo(50, 150);   // 移动到起点
ctx.lineTo(150, 150);  // 画线到第二点
ctx.lineTo(100, 50);   // 画线到第三点
ctx.closePath();       // 闭合路径(可选)

// 样式设置
ctx.fillStyle = 'green';
ctx.strokeStyle = 'black';
ctx.lineWidth = 2;

// 绘制
ctx.fill();   // 填充路径
ctx.stroke(); // 描边路径

3. 绘制圆弧和圆形

ctx.beginPath();
// arc(x, y, radius, startAngle, endAngle, anticlockwise)
ctx.arc(300, 100, 50, 0, Math.PI * 2); // 完整圆形
ctx.fillStyle = 'orange';
ctx.fill();

// 绘制半圆
ctx.beginPath();
ctx.arc(300, 200, 50, 0, Math.PI); // 0到π是下半圆
ctx.strokeStyle = 'purple';
ctx.lineWidth = 4;
ctx.stroke();

样式与颜色

1. 颜色设置

// 命名颜色
ctx.fillStyle = 'steelblue';

// 十六进制颜色
ctx.fillStyle = '#FF5733';

// RGB/RGBA颜色
ctx.fillStyle = 'rgb(255, 87, 51)';
ctx.fillStyle = 'rgba(255, 87, 51, 0.7)'; // 带透明度

// HSL/HSLA颜色
ctx.fillStyle = 'hsl(120, 100%, 50%)';

2. 渐变效果

Canvas支持线性渐变和径向渐变:

// 线性渐变
const linearGrad = ctx.createLinearGradient(0, 0, 200, 0);
linearGrad.addColorStop(0, 'red');
linearGrad.addColorStop(0.5, 'yellow');
linearGrad.addColorStop(1, 'green');
ctx.fillStyle = linearGrad;
ctx.fillRect(20, 150, 200, 100);

// 径向渐变
const radialGrad = ctx.createRadialGradient(350, 200, 10, 350, 200, 60);
radialGrad.addColorStop(0, 'white');
radialGrad.addColorStop(1, 'blue');
ctx.fillStyle = radialGrad;
ctx.beginPath();
ctx.arc(350, 200, 60, 0, Math.PI * 2);
ctx.fill();

3. 阴影效果

ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;

ctx.fillStyle = 'gold';
ctx.fillRect(250, 150, 100, 80);

// 重置阴影
ctx.shadowColor = 'transparent';

文本绘制

Canvas提供了在画布上绘制文本的方法:

ctx.font = '30px Arial'; // 设置字体
ctx.fillStyle = 'navy';  // 填充颜色
ctx.fillText('Hello Canvas', 50, 50); // 填充文本

ctx.strokeStyle = 'maroon'; // 描边颜色
ctx.lineWidth = 1;          // 线宽
ctx.strokeText('Hello Canvas', 50, 100); // 描边文本

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

图像绘制

Canvas可以绘制外部图像:

const img = new Image();
img.src = 'example.jpg';
img.onload = function() {
  // 基本绘制
  ctx.drawImage(img, 0, 0);
  
  // 缩放绘制
  ctx.drawImage(img, 100, 100, 150, 75); // (img, x, y, width, height)
  
  // 切片绘制
  ctx.drawImage(
    img, 
    50, 50, 100, 100, // 源图像切片区域
    200, 200, 150, 150 // 画布上的目标区域
  );
};

状态管理

Canvas使用栈结构管理绘图状态:

// 保存当前状态(颜色、变换等)
ctx.save();

ctx.fillStyle = 'red';
ctx.fillRect(10, 10, 50, 50);

// 恢复之前保存的状态
ctx.restore();

// 此时fillStyle恢复为保存前的值
ctx.fillRect(70, 10, 50, 50);

实战练习:绘制简单图表

<canvas id="chartCanvas" width="400" height="300"></canvas>

<script>
  const canvas = document.getElementById('chartCanvas');
  const ctx = canvas.getContext('2d');
  
  // 数据
  const data = [120, 80, 150, 60, 200];
  const labels = ['Jan', 'Feb', 'Mar', 'Apr', 'May'];
  const colors = ['#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF'];
  
  // 绘制条形图
  const barWidth = 50;
  const gap = 30;
  const maxHeight = Math.max(...data);
  const scale = (canvas.height - 50) / maxHeight;
  
  // 绘制坐标轴
  ctx.beginPath();
  ctx.moveTo(30, 20);
  ctx.lineTo(30, canvas.height - 30);
  ctx.lineTo(canvas.width - 20, canvas.height - 30);
  ctx.strokeStyle = '#000';
  ctx.lineWidth = 2;
  ctx.stroke();
  
  // 绘制条形
  data.forEach((value, index) => {
    const x = 50 + index * (barWidth + gap);
    const height = value * scale;
    const y = canvas.height - 30 - height;
    
    ctx.fillStyle = colors[index];
    ctx.fillRect(x, y, barWidth, height);
    
    // 添加标签
    ctx.fillStyle = '#000';
    ctx.font = '12px Arial';
    ctx.fillText(labels[index], x + barWidth/2 - 10, canvas.height - 10);
  });
</script>

常见问题与调试技巧

  1. Canvas不显示内容?

    • 确保JavaScript没有报错
    • 检查Canvas元素的width/height属性(不是CSS样式)
    • 确认绘图代码确实执行了
  2. 图像不显示?

    • 确保图像已加载完成(使用onload回调)
    • 检查图像路径是否正确
  3. 性能优化建议

    • 避免频繁的状态改变(如颜色、阴影等)
    • 对于复杂场景,考虑分层多个Canvas
    • 使用requestAnimationFrame实现动画

通过本节学习,您已经掌握了Canvas的基础绘图功能。接下来的章节将深入探讨Canvas的高级特性,包括路径操作、图像处理和动画技术。

#前端开发 分享于 2025-05-20

【 内容由 AI 共享,不代表本站观点,请谨慎参考 】