HTML canvas标签使用指南-Day32

1. 什么是 <canvas>

<canvas> 是 HTML5 引入的一个绘图容器 ,它本身只是一个矩形的画布区域,本身不具备绘图能力。所有的图形绘制、动画、图像处理都需要通过 JavaScript 来完成。

它常用于:

  • 动态图表与数据可视化
  • 游戏开发(2D 渲染)
  • 图像滤镜与像素级操作
  • 签名板、绘图工具
  • 实时视频/图像处理

2. 基本用法

2.1 在 HTML 中定义画布

html 复制代码
<canvas id="myCanvas" width="400" height="300">
  您的浏览器不支持 Canvas,请升级浏览器。
</canvas>
  • id:便于 JavaScript 获取元素。
  • width / height :画布的实际像素尺寸(不是 CSS 样式尺寸)。
  • 标签内部的内容(如"您的浏览器不支持...")会在浏览器不支持 Canvas 时显示。

⚠️ 注意 :不要用 CSS 直接设置 widthheight,否则会拉伸画布内容。CSS 尺寸只控制显示大小,而 width/height 属性控制绘图分辨率。

3. 通过 JavaScript 绘制

3.1 获取绘图上下文

javascript 复制代码
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');   // 2D 绘图上下文

getContext('2d') 返回一个包含所有绘图方法的对象。

3.2 绘制基础图形

矩形
javascript 复制代码
// 填充矩形
ctx.fillStyle = '#3498db';
ctx.fillRect(20, 20, 150, 100);

// 描边矩形
ctx.strokeStyle = '#e74c3c';
ctx.lineWidth = 4;
ctx.strokeRect(200, 50, 120, 80);

// 清除矩形区域
ctx.clearRect(50, 50, 80, 60);
路径绘制(圆形、三角形等)
javascript 复制代码
// 绘制圆形
ctx.beginPath();
ctx.arc(100, 200, 40, 0, Math.PI * 2);
ctx.fillStyle = '#2ecc71';
ctx.fill();
ctx.strokeStyle = '#27ae60';
ctx.stroke();

// 绘制三角形
ctx.beginPath();
ctx.moveTo(250, 180);
ctx.lineTo(300, 250);
ctx.lineTo(200, 250);
ctx.closePath();
ctx.fillStyle = '#f1c40f';
ctx.fill();

3.3 样式与颜色

属性 说明
fillStyle 填充颜色 / 渐变 / 图案
strokeStyle 描边颜色
lineWidth 线条宽度(像素)
globalAlpha 全局透明度(0~1)
javascript 复制代码
ctx.fillStyle = 'rgba(255, 99, 132, 0.7)';
ctx.strokeStyle = '#2c3e50';
ctx.lineWidth = 6;

3.4 绘制文本

javascript 复制代码
ctx.font = 'bold 28px "Segoe UI", sans-serif';
ctx.fillStyle = '#2c3e50';
ctx.fillText('Hello Canvas', 30, 100);

ctx.strokeStyle = '#e74c3c';
ctx.lineWidth = 2;
ctx.strokeText('描边文字', 30, 160);

3.5 绘制图像

javascript 复制代码
const img = new Image();
img.src = 'image.png';
img.onload = () => {
    ctx.drawImage(img, 50, 50, 200, 150); // 缩放绘制
};

4. 高级特性

4.1 渐变

javascript 复制代码
// 线性渐变
const gradient = ctx.createLinearGradient(0, 0, 200, 0);
gradient.addColorStop(0, '#ff6b6b');
gradient.addColorStop(1, '#feca57');
ctx.fillStyle = gradient;
ctx.fillRect(10, 10, 300, 80);

// 径向渐变
const radGrad = ctx.createRadialGradient(150, 150, 20, 150, 150, 80);
radGrad.addColorStop(0, '#a29bfe');
radGrad.addColorStop(1, '#6c5ce7');
ctx.fillStyle = radGrad;
ctx.beginPath();
ctx.arc(150, 150, 80, 0, Math.PI * 2);
ctx.fill();

4.2 阴影效果

javascript 复制代码
ctx.shadowColor = 'rgba(0,0,0,0.3)';
ctx.shadowBlur = 12;
ctx.shadowOffsetX = 6;
ctx.shadowOffsetY = 6;
ctx.fillStyle = '#0984e3';
ctx.fillRect(100, 100, 120, 80);
// 记得重置阴影避免影响后续绘制
ctx.shadowBlur = 0;

4.3 变换操作

javascript 复制代码
ctx.save();          // 保存当前状态
ctx.translate(200, 150);
ctx.rotate(Math.PI / 4);
ctx.scale(1.2, 0.8);
ctx.fillStyle = '#fd79a8';
ctx.fillRect(-30, -30, 60, 60);
ctx.restore();       // 恢复状态

5. 动画与帧循环

使用 requestAnimationFrame 实现流畅动画:

javascript 复制代码
let x = 0;
function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = '#e17055';
    ctx.beginPath();
    ctx.arc(x, 150, 30, 0, Math.PI * 2);
    ctx.fill();
    x += 2;
    if (x > canvas.width) x = 0;
    requestAnimationFrame(draw);
}
draw();

6. 像素操作

使用 getImageDataputImageData 进行像素级处理:

javascript 复制代码
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;

// 反色滤镜
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);

7. 性能优化建议

优化点 说明
离屏渲染 使用 document.createElement('canvas') 绘制复杂内容,再用 drawImage 绘制到主画布
减少 clearRect 调用 只在需要时清除,或使用多个画布分层
避免频繁 save/restore 批量设置样式,减少状态切换
使用 requestAnimationFrame 替代 setInterval / setTimeout
控制像素操作区域 尽量只处理需要更新的矩形区域

8. 兼容性与回退

  • 所有现代浏览器(Chrome, Firefox, Safari, Edge)均支持 Canvas。
  • IE 9+ 支持基础功能,但部分高级特性(如 Path2D)可能不支持。
  • 回退方案:在 <canvas> 标签内添加备选内容(文本或图片)。
html 复制代码
<canvas width="400" height="300">
  <img src="fallback.png" alt="您的浏览器不支持 Canvas">
</canvas>

9. 实用示例:响应式画布

让画布自适应容器大小,并保持像素比清晰:

javascript 复制代码
function setupCanvas(canvas) {
    const rect = canvas.parentElement.getBoundingClientRect();
    const dpr = window.devicePixelRatio || 1;
    canvas.width = rect.width * dpr;
    canvas.height = rect.height * dpr;
    canvas.style.width = rect.width + 'px';
    canvas.style.height = rect.height + 'px';
    const ctx = canvas.getContext('2d');
    ctx.scale(dpr, dpr);
    return ctx;
}

10. 总结

核心概念 描述
canvas 元素 定义绘图区域,宽高决定分辨率
getContext('2d') 获取 2D 绘图上下文
路径绘制 beginPath / moveTo / lineTo / arc
样式控制 fillStyle / strokeStyle / lineWidth
图像 & 文本 drawImage / fillText
变换 & 状态 translate / rotate / save / restore
像素操作 getImageData / putImageData
动画循环 requestAnimationFrame

Canvas 提供了强大且灵活的 2D 绘图能力,结合 JavaScript 可以创造出丰富的交互式图形、数据可视化和游戏体验。掌握它的核心 API 是前端开发进阶的重要一步。

相关推荐
weixin1997010801620 分钟前
《alibaba.idle.isv.order.ship 接入实录:闲鱼订单发货回传的5个隐式约束》(附Python源码)
服务器·前端·python
初願致夕霞27 分钟前
五种IO模型(详解非阻塞IO与多路转接)
linux·前端·网络·数据库·tcp/ip
深圳多奥智能一卡(码、脸)通系统29 分钟前
智能梯控SDK可直接用于第三方开发对接的接口文档说明书
服务器·前端·算法
烂蜻蜓38 分钟前
Flask入门教程(十五):错误处理与日志——打造健壮的Web应用
前端·python·flask
深念Y1 小时前
浏览器缩放检测的前端通用方案
前端
风骏时光牛马1 小时前
AIAgent异常故障根因分析与复盘总结
前端
weixin_431600441 小时前
前端数据埋点(7):Web Vitals——页面慢不慢,不是再包一层 fetch
前端·性能优化·sentry·数据埋点
এ慕ོ冬℘゜2 小时前
前端实战:jQuery实现动态表格渲染与状态切换功能
前端·javascript·jquery
jay神3 小时前
【计算机毕业设计】基于Flask+Vue的电影数据可视化与智能推荐系统
前端·vue.js·python·信息可视化·flask·毕业设计·课程设计