Canvas 2D 路径与形状:从坐标系到可维护绘制
本文目录
Canvas 不是图片标签,也不会自动把 JavaScript 里的对象变成 DOM。它提供一个位图表面,脚本通过 2D 渲染上下文把像素画出来;适合自由绘图、图表、游戏和图像处理。若主要内容是文字、链接或可单独交互的控件,优先用 HTML/SVG,避免把可访问结构压成无法选择的像素。
初始化与坐标
<canvas> 必须有闭合标签,可在内部提供替代内容。width/height 属性决定位图的固有像素尺寸,缺省时是 300×150;CSS 尺寸只是页面布局尺寸。若把小位图用 CSS 拉大,图像会模糊。设置 canvas 的 width 或 height 会清空位图并重置渲染状态,即使赋回相同数值也一样。
通过 getContext('2d') 取得上下文;它可能返回 null,应在绘制前处理。默认原点位于左上,x 向右、y 向下。矩形可用 fillRect、strokeRect 绘制,clearRect 清除指定像素区域;这些直接绘制方法不会帮你创建可编辑 DOM 节点。
function drawTriangle(canvas) {
const ctx = canvas.getContext('2d');
if (!ctx) return false;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.moveTo(24, 96);
ctx.lineTo(96, 24);
ctx.lineTo(168, 96);
ctx.closePath();
ctx.fillStyle = '#167d72';
ctx.fill();
ctx.strokeStyle = '#102a43';
ctx.lineWidth = 3;
ctx.stroke();
return true;
}
路径的生命周期
路径要先 beginPath(),再用 moveTo()、lineTo()、rect()、arc() 或曲线方法组成一个或多个子路径,最后选择 fill()、stroke() 或 clip()。每次新图形都明确开始新路径,否则旧子路径可能意外一起被描边或填充。closePath() 连回当前子路径起点;填充开放子路径时会隐式闭合填充区域,但单纯 stroke() 不会自动画出那条闭合边。
arc(x, y, radius, startAngle, endAngle) 的角度使用弧度;完整圆的角度跨度是 2 * Math.PI。quadraticCurveTo 使用一个控制点,bezierCurveTo 使用两个控制点;控制点影响曲线形状,但不一定落在曲线上。重复图形可用 Path2D 保存路径并重绘,避免每次重建相同几何数据。
路径填充规则默认是 nonzero,也可用 evenodd 表达带孔洞的复合形状。闭合路径、交叉子路径与填充规则共同决定哪些区域被填色。线条的 lineWidth、lineCap、lineJoin、miterLimit 与 setLineDash() 控制外观;抗锯齿、设备像素比、缩放和线宽都会影响边缘像素,不应把“坐标加 0.5”当所有尺寸下的通用修复。
清理、重绘和访问方式
clearRect() 只擦除指定区域,不会重置变换矩阵、裁剪区、颜色、线型或 alpha;复杂场景要么显式重置相关属性,要么在支持时调用 ctx.reset() 完整重置上下文。用赋值 canvas.width/height 重置会改变位图尺寸并清空全部绘制,应只在确实需要重新配置表面时使用。
把绘图拆成可重复的 render(state),数据变化后清屏并按确定顺序重画。高频输入可合并到下一帧,而不是每个 pointermove 都同步做昂贵布局。响应式调整要同时更新 CSS 尺寸和位图分辨率;不要在每一帧重新设 canvas 属性,否则会不断清空画面。
Canvas 中的文本、图形和控件对辅助技术不可见。提供有意义的 aria-label/fallback 描述,并把键盘操作、按钮、表格数据和焦点保留在 DOM 中;纯装饰画布可明确标记为 presentation。
- 检查上下文是否取得成功,初始化时只设置一次位图尺寸。
- 对每个独立形状使用
beginPath(),检查路径闭合、角度单位和填充规则。 - 覆盖空数据、画布缩放、设备像素比变化、清空、重绘和尺寸重置。
- 验证画布之外有文本/DOM 等价信息,并能通过键盘操作交互功能。
- 大量图形时测量绘制成本,再考虑 Path2D、分层画布或 OffscreenCanvas。
参考:MDN Canvas 基础、MDN 绘制形状、MDN CanvasRenderingContext2D、MDN Path2D、MDN getContext、MDN Canvas reset、MDN Canvas 可访问性。
Live Notes
留言提交后会先进入审核,审核通过后对其他读者公开。