Canvas 笔记

1 minute read

canvas 元素在页面中指定一个区域,在这个区域内可以使用 canvas 相关的 API 绘制图形。

使用流程

  1. 在页面上创建一个 canvas 元素,并指定其 width 和 height
  2. 获取 canvas 对象的上下文
  3. 使用绘图API,绘制图形
var canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 200;

document.body.append('canvas');

var context = canvas.getContext('2d');

context.fillStyle = 'red';
context.fillRect(0, 0, 100, 100);

2D 上下文

canvas 图形绘制需先指定区域的高和宽, 坐标系原点位于区域左上角,x轴向左延长,y轴向下, 绘制图形时,首先取得canvas对应的 2D 上下文的引用,通过引用上API完成图形的绘制。

矩形相关

矩形相关方法,接收4个参数,分别为x、y坐标、矩形宽度、矩形高度。

  • strokeRect:描边矩形,strokeStyle属性定义描边色彩,lineWidth定义线条宽度,lineCap定义线条末端形状,lineJoin定义线条相交方式
  • fillRect:填充矩形,fillStyle属性定义填充色彩
  • clearRect:清除矩形区域

save() 方法可将当前描边、填充等属性压入一个栈中,对应的restore()将栈顶的属性设置弹出

路径

路径的绘制,通过beginPath()方法开始绘制,之后调用画直线、弧线、曲线,moveTo绘制开始的移动坐标点等,完成路径创建,最后调用closePath()或stroke()描边将路径显现出来。

  • arc(x, y, radius, startAngle, endAngle, counterclockwise):以(x,y)为圆心绘制一条弧线,弧线半径为 radius,起始和结束角度(用弧度表示)分别为 startAngle 和 endAngle。最后一个参数表示 startAngle 和 endAngle 是否按逆时针方向计算,值为 false 表示按顺时针方向计算。
  • arcTo(x1, y1, x2, y2, radius):从上一点开始绘制一条弧线,到(x2, y2)为止,并且以给定的半径 radius 穿过(x1,y1)。
  • bezierCurveTo(c1x, c1y, c2x, c2y, x, y):从上一点开始绘制一条曲线,到(x, y)为止,并且以(c1x, c1y)和(c2x, c2y)为控制点。
  • lineTo(x, y):从上一点开始绘制一条直线,到(x, y)为止。
  • moveTo(x, y):将绘图游标移动到(x, y),不画线。
  • quadraticCurveTo(cx, cy, x, y):从上一点开始绘制一条二次曲线,到(x, y)为止,并且以(cx, cy)作为控制点.
  • isPointInPath(x, y) 测试点是否在路径上

文本和图片

属性

  • font:字体、大小等
  • textAlign:对齐方式 start、end、center
  • textBaseline:文本基线,在指定坐标的上、中下方 top、middle、bottom

绘制方法

  • fillText(text, x, y, maxWidth)
  • strokeText()
  • drawImage(image, [sx, sy, sWidth, sHeight,] x, y, width, height) 源图像的开始坐标和宽高为可选,可将图像的指定位置和区域裁剪绘制到canvas的指定位置

measureText 可测量字体的宽度。

变换

  • rotate (angle):围绕原点旋转图像 angle 弧度。
  • scale (scaleX, scaleY):缩放图像,在 x 方向 乘以 scaleX, 在 y 方向乘以 scaleY。
  • translate (x, y): 将坐标原点移动到(x, y)。

阴影

  • shadowColor: 用 CSS 颜色格式表示的阴影颜色,默认黑色。
  • shadowOffsetX:x 轴方向的阴影偏移量
  • shadowOffsetY:y 轴方向的阴影偏移量
  • shadowBlur:模糊的像素数

渐变

渐变的使用步骤

// 1. 创建一个渐变,线性或径向渐变
var gradient = context.createLinearGradient(20, 20, 80, 80);
// 2. 为渐变起始位置添加渐变色
gradient.addColorStop(0, 'red');
gradient.addColorStop(1, 'blue');
// 3. 设置填充属性为渐变
context.fillStyle = gradient;
//4. 绘制
context.fillRect(20, 20, 90, 90);

createRadialGradient 接收两个圆描述参数(x, y, radius),渐变方向为连个圆盘中心连线,区域为两个圆的外切线.

近似的有个模式,pattern = context.createPattern(image, ‘repeat’),创建的模式也可当作填充属性,用作填充区域。

全局的属性设置 globalAlpha 和 globalCompositionOperation,用于处理绘制区域重复后叠加区域的显示效果和顺序。

图像数据

getImageData(x, y, width, height) 返回 canvas 画布上的图像数据对象,图像的颜色通道数据在对象的 data 属性中,可通过修改里面数据达到处理图像的效果

var image = document.images[0];
var imageData = context.getImageData(0, 0, image.width, image.height);
// 处理 imageData.data
context.putImageData(imageData, 0, 0);

这里有滤波相关博客。