文章目录
- HTML5 Canvas的核心方法与属性详细讲解
HTML5 Canvas的核心方法与属性详细讲解
HTML5 Canvas 的强大之处在于其丰富的绘图 API,通过 CanvasRenderingContext2D(2D 上下文,简称 ctx)提供的方法和属性,能实现从简单图形到复杂动画的全场景绘制。以下是最核心的方法与属性,按功能分类详解:
一、Canvas 元素基础:画布的「尺寸与上下文」
Canvas 元素本身的属性和方法是绘图的基础,决定了画布的「容器特性」。
1. width 与 height 属性(Canvas 元素)
- 功能:定义画布的实际像素尺寸(绘图坐标系的范围),是绘图的「真实画布大小」。
- 用法:必须通过元素属性设置(而非 CSS),否则图形会按 CSS 尺寸拉伸。
- 示例:
<!-- 正确:600x400 像素的画布 --> <canvas id="myCanvas" width="600" height="400"></canvas> <style> #myCanvas { border: 1px solid #000; /* 错误:用 CSS 设置宽高会导致拉伸(如设为 300px 会压缩画布) */ /* width: 300px; */ } </style> - 注意:若通过 JS 动态修改,需直接赋值(
canvas.width = 800),修改后画布会清空并重置。
2. getContext('2d') 方法(Canvas 元素)
- 功能:获取 2D 绘图上下文对象(
ctx),所有绘图操作均通过该对象执行,是 Canvas 绘图的「入口」。 - 用法:调用后返回
CanvasRenderingContext2D实例,包含所有绘图方法。 - 示例:
const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); // 获取 2D 上下文,后续操作通过 ctx 完成 - 注意:若浏览器不支持 Canvas,
getContext会返回null,可提前判断兼容性。
二、路径绘制:图形的「骨架搭建」
路径是 Canvas 绘图的基础,通过一系列点和线定义图形轮廓,再通过「填充」或「描边」显式化。
1. beginPath() 与 closePath()(ctx 方法)
- 功能:
beginPath()开启新路径(隔离当前图形与之前的路径);closePath()闭合路径(连接当前点与起点)。 - 用法:绘制任何图形前需用
beginPath()初始化路径,避免与上一路径关联。 - 示例:
// 绘制三角形(闭合路径) ctx.beginPath(); // 开启新路径 ctx.moveTo(100, 100); // 起点 ctx.lineTo(200, 100); // 线段1 ctx.lineTo(150, 50); // 线段2 ctx.closePath(); // 闭合(连接(150,50)到(100,100)) ctx.stroke(); // 描边显示 - 注意:
closePath()仅闭合路径,不会自动描边/填充,需配合stroke()或fill()。
2. moveTo(x, y) 与 lineTo(x, y)(ctx 方法)
- 功能:
moveTo(x, y)移动画笔到指定坐标(不绘制);lineTo(x, y)从当前点绘制线段到目标坐标。 - 用法:用于绘制折线、多边形等线性图形。
- 示例:
ctx.beginPath(); ctx.moveTo(50, 50); // 移动到起点(50,50) ctx.lineTo(200, 50); // 水平线 ctx.lineTo(200, 150); // 垂直线 ctx.lineTo(50, 150); // 水平线 ctx.closePath(); // 闭合为矩形 ctx.fillStyle = 'lightblue'; ctx.fill(); // 填充
3. arc(x, y, r, startAngle, endAngle, anticlockwise)(ctx 方法)
- 功能:绘制圆弧或圆形,参数分别为:圆心坐标
(x,y)、半径r、起始角度(弧度)、结束角度(弧度)、是否逆时针(false为顺时针)。 - 用法:圆形是
startAngle=0、endAngle=2π的圆弧。 - 示例:
// 绘制半圆(上半圆) ctx.beginPath(); ctx.arc(300, 100, 50, Math.PI, 0, false); // 从π(180°)到0(0°),顺时针 ctx.strokeStyle = 'red'; ctx.lineWidth = 3; ctx.stroke(); // 绘制完整圆形 ctx.beginPath(); ctx.arc(400, 100, 50, 0, Math.PI * 2, false); // 0到2π(360°) ctx.fillStyle = 'green'; ctx.fill(); - 注意:角度需用弧度(
角度 × Math.PI / 180转换,如 90° 为Math.PI/2)。
4. rect(x, y, width, height)(ctx 方法)
- 功能:创建矩形路径(等价于用
moveTo+lineTo绘制矩形轮廓)。 - 用法:需配合
stroke()或fill()显式化,也可直接用strokeRect/fillRect简化。 - 示例:
ctx.beginPath(); ctx.rect(50, 200, 150, 80); // x=50,y=200,宽150,高80 ctx.strokeStyle = 'purple'; ctx.stroke();
三、样式与颜色:图形的「外观装饰」
通过样式属性控制图形的填充、描边效果,决定视觉呈现。
1. fillStyle 与 strokeStyle(ctx 属性)
- 功能:
fillStyle定义填充颜色/样式;strokeStyle定义描边颜色/样式,支持:- 颜色值(
#ff0000、rgb(255,0,0)、rgba(255,0,0,0.5)); - 渐变对象(
createLinearGradient/createRadialGradient); - 图案对象(
createPattern)。
- 颜色值(
- 示例:
// 1. 纯色 ctx.fillStyle = '#ffcc00'; ctx.fillRect(50, 50, 100, 100); // 2. 线性渐变 const linearGrad = ctx.createLinearGradient(200, 50, 300, 150); // 从(200,50)到(300,150) linearGrad.addColorStop(0, 'blue'); linearGrad.addColorStop(1, 'pink'); ctx.fillStyle = linearGrad; ctx.fillRect(200, 50, 100, 100); // 3. 图案填充 const img = new Image(); img.src = 'dot.png'; img.onload = () => { const pattern = ctx.createPattern(img, 'repeat'); // 重复图案 ctx.strokeStyle = pattern; ctx.lineWidth = 10; ctx.strokeRect(350, 50, 100, 100); };
2. lineWidth、lineCap、lineJoin(ctx 属性)
- 功能:
lineWidth:线段宽度(默认1px);lineCap:线段端点样式(butt平角/round圆角/square方角,默认butt);lineJoin:线段连接处样式(miter尖角/round圆角/bevel斜角,默认miter)。
- 示例:
ctx.lineWidth = 10; ctx.lineCap = 'round'; // 端点圆角 ctx.lineJoin = 'round'; // 连接处圆角 ctx.beginPath(); ctx.moveTo(50, 200); ctx.lineTo(150, 150); ctx.lineTo(250, 200); ctx.stroke();
四、文本绘制:画布上的「文字排版」
通过文本方法在画布上绘制文字,支持填充和描边。
1. fillText(text, x, y, [maxWidth]) 与 strokeText(text, x, y, [maxWidth])(ctx 方法)
- 功能:
fillText绘制填充文字;strokeText绘制描边文字,参数为:文本内容、起点坐标(x,y)、可选最大宽度(超过会压缩)。 - 用法:需先设置
font、textAlign等样式属性。 - 示例:
ctx.font = 'bold 36px "Microsoft YaHei"'; // 字体样式(必须设置,否则默认10px sans-serif) ctx.textAlign = 'center'; // 水平对齐(left/center/right) ctx.textBaseline = 'middle'; // 垂直对齐(top/middle/bottom) ctx.fillStyle = '#333'; ctx.fillText('Canvas 文本', 300, 100); // 在(300,100)居中绘制填充文字 ctx.strokeStyle = 'red'; ctx.strokeText('描边文字', 300, 150); // 绘制描边文字
五、图像操作:画布上的「图片处理」
通过 drawImage 方法在画布上绘制图片,支持完整绘制、缩放、裁剪。
drawImage()(ctx 方法,多参数形式)
- 功能:
- 基础:
drawImage(img, x, y)→ 在(x,y)绘制完整图片; - 缩放:
drawImage(img, x, y, w, h)→ 绘制图片并缩放到w×h; - 裁剪:
drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh)→ 裁剪原图(sx,sy)开始的sw×sh区域,绘制到(dx,dy)并缩放到dw×dh。
- 基础:
- 示例:
const img = new Image(); img.src = 'scene.jpg'; // 图片路径 img.onload = () => { // 1. 绘制完整图片到(50,50) ctx.drawImage(img, 50, 50); // 2. 缩放绘制(缩放到200x150) ctx.drawImage(img, 350, 50, 200, 150); // 3. 裁剪绘制(裁剪原图(100,100)开始的200x200区域,绘制到(50, 250)并缩放到150x150) ctx.drawImage(img, 100, 100, 200, 200, 50, 250, 150, 150); }; - 注意:图片必须加载完成(
onload事件触发)后才能绘制,否则无效果;跨域图片绘制后会污染画布,导致无法用toDataURL导出。
六、变换与状态:坐标系的「乾坤大挪移」
通过变换方法修改坐标系,实现旋转、缩放、平移,配合状态保存/恢复管理绘图状态。
1. translate(x, y)、rotate(angle)、scale(sx, sy)(ctx 方法)
- 功能:
translate(x,y):平移坐标系原点到(x,y)(后续绘图基于新原点);rotate(angle):旋转坐标系(以当前原点为中心,角度为弧度);scale(sx,sy):缩放坐标系(sx水平缩放,sy垂直缩放,1为原尺寸)。
- 示例:
// 绘制旋转的矩形 ctx.save(); // 保存当前状态(原点、旋转等) ctx.translate(200, 200); // 原点移到(200,200) ctx.rotate(Math.PI / 4); // 旋转45°(π/4弧度) ctx.fillStyle = 'orange'; ctx.fillRect(-50, -50, 100, 100); // 以新原点为中心绘制100x100矩形 ctx.restore(); // 恢复到保存的状态(避免影响后续绘图)
2. save() 与 restore()(ctx 方法)
- 功能:
save()保存当前绘图状态(样式、变换、裁剪路径等)到栈中;restore()从栈中恢复最近保存的状态。 - 用法:用于隔离变换或样式,避免相互影响(必备技巧)。
七、像素操作:画布的「底层控制」
直接操作像素数据,实现滤镜、颜色处理等高级效果。
getImageData(x, y, w, h) 与 putImageData(data, x, y)(ctx 方法)
- 功能:
getImageData获取(x,y)开始的w×h区域像素数据(ImageData对象,data属性为[r,g,b,a,r,g,b,a,...]数组);putImageData将像素数据绘制到画布。 - 示例:实现灰度滤镜
// 假设画布已有图像,处理为灰度 const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const data = imageData.data; for (let i = 0; i < data.length; i += 4) { const r = data[i]; const g = data[i + 1]; const b = data[i + 2]; // 灰度公式:亮度 = 0.299r + 0.587g + 0.114b const gray = Math.round(0.299 * r + 0.587 * g + 0.114 * b); data[i] = data[i + 1] = data[i + 2] = gray; // r=g=b=灰度值 } ctx.putImageData(imageData, 0, 0); // 绘制处理后的像素 - 注意:像素操作性能消耗大,避免在动画中频繁调用;跨域图片会导致
getImageData报错(画布污染)。
八、合成与裁剪:图形的「混合魔法」
控制图形的叠加方式和绘制范围,实现复杂视觉效果。
1. globalCompositeOperation(ctx 属性)
- 功能:定义新绘制图形与已有图形的混合模式(默认
source-over:新图形覆盖旧图形)。 - 常用模式:
destination-over:新图形在旧图形下方;lighter:新旧图形叠加,颜色相加(变亮);xor:重叠区域透明。
- 示例:
// 绘制红色圆形 ctx.beginPath(); ctx.arc(150, 150, 50, 0, Math.PI * 2); ctx.fillStyle = 'red'; ctx.fill(); // 切换合成模式:新图形在下方 ctx.globalCompositeOperation = 'destination-over'; // 绘制蓝色圆形(会显示在红色圆形下方) ctx.beginPath(); ctx.arc(200, 150, 50, 0, Math.PI * 2); ctx.fillStyle = 'blue'; ctx.fill();
2. clip()(ctx 方法)
- 功能:将后续绘制限制在当前路径内(裁剪路径),超出路径的部分不显示。
- 示例:圆形内显示图片
// 创建圆形裁剪路径 ctx.beginPath(); ctx.arc(300, 200, 80, 0, Math.PI * 2); ctx.clip(); // 裁剪为圆形区域 // 绘制图片(仅圆形区域可见) const img = new Image(); img.src = 'photo.jpg'; img.onload = () => { ctx.drawImage(img, 220, 120, 160, 160); // 图片大小与圆形匹配 };
注意事项总结
- 宽高设置:必须通过
canvas.width/height属性设置,而非 CSS,否则图形拉伸。 - 路径隔离:每次绘制新图形前用
beginPath(),避免路径关联导致意外描边。 - 图像加载:
drawImage必须在图片onload后调用,跨域图片会污染画布。 - 性能优化:像素操作、复杂路径绘制耗时,动画中优先用
requestAnimationFrame并减少重绘区域。 - 状态管理:变换或样式修改后,用
save()/restore()隔离状态,避免影响后续绘图。
核心总结
HTML5 Canvas 的核心能力源于 CanvasRenderingContext2D 的方法与属性:通过路径定义图形骨架,样式控制外观,变换修改坐标系,像素操作实现底层控制,合成与裁剪创造复杂效果。掌握这些 API 后,可从简单图形扩展到动画、游戏、数据可视化等高级场景,核心是理解「画布即像素集合」,所有操作最终都是对像素的读写与计算。
HTML5 Canvas核心API详解

6223

被折叠的 条评论
为什么被折叠?



