Canvas 常用 API
基础设置
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
基础图形绘制
矩形绘制
// 绘制填充矩形
ctx.fillRect(x, y, width, height);
// 绘制描边矩形
ctx.strokeRect(x, y, width, height);
// 清除矩形区域
ctx.clearRect(x, y, width, height);
路径绘制
// 开始新路径
ctx.beginPath();
// 移动画笔到指定位置
ctx.moveTo(x, y);
// 绘制直线到指定位置
ctx.lineTo(x, y);
// 绘制矩形路径
ctx.rect(x, y, width, height);
// 绘制圆弧
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
// 绘制椭圆
ctx.ellipse(
x,
y,
radiusX,
radiusY,
rotation,
startAngle,
endAngle,
anticlockwise
);
// 绘制二次贝塞尔曲线
ctx.quadraticCurveTo(cpx, cpy, x, y);
// 绘制三次贝塞尔曲线
ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
// 关闭路径
ctx.closePath();
// 填充路径
ctx.fill();
// 描边路径
ctx.stroke();
样式与颜色
颜色设置
// 设置填充颜色
ctx.fillStyle = "red";
ctx.fillStyle = "#ff0000";
ctx.fillStyle = "rgb(255, 0, 0)";
ctx.fillStyle = "rgba(255, 0, 0, 0.5)";
// 设置描边颜色
ctx.strokeStyle = "blue";
ctx.strokeStyle = "#0000ff";
ctx.strokeStyle = "rgb(0, 0, 255)";
ctx.strokeStyle = "rgba(0, 0, 255, 0.5)";
线条样式
// 设置线条宽度
ctx.lineWidth = 5;
// 设置线条末端样式
ctx.lineCap = "butt"; // 默认
ctx.lineCap = "round"; // 圆形
ctx.lineCap = "square"; // 方形
// 设置线条连接处样式
ctx.lineJoin = "miter"; // 默认,尖角
ctx.lineJoin = "round"; // 圆角
ctx.lineJoin = "bevel"; // 斜角
// 设置虚线
ctx.setLineDash([10, 5]); // 实线10px,间隔5px
ctx.setLineDash([]); // 重置为实线
渐变
// 线性渐变
const linearGradient = ctx.createLinearGradient(x0, y0, x1, y1);
linearGradient.addColorStop(0, "red");
linearGradient.addColorStop(0.5, "yellow");
linearGradient.addColorStop(1, "blue");
ctx.fillStyle = linearGradient;
// 径向渐变
const radialGradient = ctx.createRadialGradient(x0, y0, r0, x1, y1, r1);
radialGradient.addColorStop(0, "white");
radialGradient.addColorStop(1, "black");
ctx.fillStyle = radialGradient;
阴影
// 设置阴影颜色
ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
// 设置阴影模糊度
ctx.shadowBlur = 10;
// 设置阴影偏移
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
文本绘制
文本属性
// 设置字体
ctx.font = "48px sans-serif";
ctx.font = "bold 32px Arial";
ctx.font = "italic 24px Georgia";
// 设置文本对齐方式
ctx.textAlign = "start"; // 默认
ctx.textAlign = "end";
ctx.textAlign = "left";
ctx.textAlign = "right";
ctx.textAlign = "center";
// 设置文本基线
ctx.textBaseline = "top";
ctx.textBaseline = "hanging";
ctx.textBaseline = "middle";
ctx.textBaseline = "alphabetic"; // 默认
ctx.textBaseline = "ideographic";
ctx.textBaseline = "bottom";
文本绘制方法
// 绘制填充文本
ctx.fillText(text, x, y, maxWidth);
// 绘制描边文本
ctx.strokeText(text, x, y, maxWidth);
// 测量文本宽度
const metrics = ctx.measureText(text);
const width = metrics.width;
图像处理
绘制图像
const img = new Image();
img.src = "image.jpg";
img.onload = () => {
// 绘制完整图像
ctx.drawImage(img, x, y);
// 绘制缩放图像
ctx.drawImage(img, x, y, width, height);
// 裁剪并绘制图像
ctx.drawImage(img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
};
图像数据操作
// 获取图像数据
const imageData = ctx.getImageData(x, y, width, height);
const data = imageData.data;
// data 数组结构:[r, g, b, a, r, g, b, a, ...]
// 每个像素占 4 个位置(RGBA)
// 修改像素数据
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
const a = data[i + 3];
// 修改像素
data[i] = 255; // R
data[i + 1] = 0; // G
data[i + 2] = 0; // B
data[i + 3] = 255; // A
}
// 将修改后的数据放回画布
ctx.putImageData(imageData, x, y);
变换操作
状态管理
// 保存当前状态
ctx.save();
// 恢复之前保存的状态
ctx.restore();
变换方法
// 平移
ctx.translate(x, y);
// 旋转(弧度制)
ctx.rotate(angle);
// 缩放
ctx.scale(x, y);
// 自定义变换矩阵
ctx.transform(a, b, c, d, e, f);
// 重置变换矩阵
ctx.setTransform(a, b, c, d, e, f);
变换示例
// 绘制旋转的矩形
ctx.save();
ctx.translate(100, 100);
ctx.rotate(Math.PI / 4); // 旋转45度
ctx.fillRect(-50, -50, 100, 100);
ctx.restore();
// 绘制缩放的图形
ctx.save();
ctx.translate(200, 200);
ctx.scale(2, 0.5); // 水平放大2倍,垂直缩小一半
ctx.fillRect(-25, -25, 50, 50);
ctx.restore();
合成操作
全局透明度
ctx.globalAlpha = 0.5; // 设置全局透明度为50%
合成模式
// 设置合成模式
ctx.globalCompositeOperation = "source-over"; // 默认
ctx.globalCompositeOperation = "source-in";
ctx.globalCompositeOperation = "source-out";
ctx.globalCompositeOperation = "source-atop";
ctx.globalCompositeOperation = "destination-over";
ctx.globalCompositeOperation = "destination-in";
ctx.globalCompositeOperation = "destination-out";
ctx.globalCompositeOperation = "destination-atop";
ctx.globalCompositeOperation = "lighter";
ctx.globalCompositeOperation = "copy";
ctx.globalCompositeOperation = "xor";
ctx.globalCompositeOperation = "multiply";
ctx.globalCompositeOperation = "screen";
ctx.globalCompositeOperation = "overlay";
ctx.globalCompositeOperation = "darken";
ctx.globalCompositeOperation = "lighten";
ctx.globalCompositeOperation = "color-dodge";
ctx.globalCompositeOperation = "color-burn";
ctx.globalCompositeOperation = "hard-light";
ctx.globalCompositeOperation = "soft-light";
ctx.globalCompositeOperation = "difference";
ctx.globalCompositeOperation = "exclusion";
ctx.globalCompositeOperation = "hue";
ctx.globalCompositeOperation = "saturation";
ctx.globalCompositeOperation = "color";
ctx.globalCompositeOperation = "luminosity";
常用合成模式说明
source-over: 新图形覆盖在旧图形之上(默认)destination-over: 新图形在旧图形之下lighter: 颜色值相加multiply: 颜色值相乘(变暗)screen: 颜色值反转相乘再反转(变亮)overlay: 结合 multiply 和 screen
像素级操作
ImageData 对象
// 创建空的 ImageData
const imageData = ctx.createImageData(width, height);
// 获取画布区域的 ImageData
const imageData = ctx.getImageData(x, y, width, height);
// ImageData 属性
imageData.width; // 宽度
imageData.height; // 高度
imageData.data; // Uint8ClampedArray 数组,包含 RGBA 数据
像素遍历
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
for (let y = 0; y < canvas.height; y++) {
for (let x = 0; x < canvas.width; x++) {
const index = (y * canvas.width + x) * 4;
const r = data[index];
const g = data[index + 1];
const b = data[index + 2];
const a = data[index + 3];
// 处理像素
}
}
ctx.putImageData(imageData, 0, 0);
作者:李伟_Li慢慢 链接:[canvas-基础篇 - 李伟_Li慢慢的专栏 - 掘金 (juejin.cn)] 来源:稀土掘金