基本操作
const canvas = document.querySelect('canvas');
let ctx = canvas.getContext('2d');
绘制矩形
- 实心矩形 ctx.fillRexct(x,y,width,height);
ctx.fillStyle = "#ff0000";
ctx.fillRect(10,10,50,50);
ctx.fillStyle = "rgba(0,0,255,0.5)";
ctx.fillRect(30,30,50,50);
ctx.strokeStyle = "#ff0000";
ctx.strokeRect(10,10,50,50);
ctx.strokeStyle = "rgba(0,0,255,0.5)";
ctx.strokeRect(30,30,50,50);
/*这里把1部分的代码放到前面就行了*/
ctx.clearRect(40,40,10,10);
绘制路径
基本介绍
- beginPath() 新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。
- closePath() 闭合路径之后图形绘制命令又重新指向到上下文中
- fill() 通过填充路径的内容区域生成实心的图形。会自动闭合;
- stroke() 通过线条来绘制图形轮廓
画圆 arc(x,y,radius,startAngle,endAngle,counterclockwise)
x坐标,y坐标,开始弧度,结束弧度,布尔值(true表示逆时针画,false表示顺时针画(默认))
ctx.beginPath()
ctx.arc(30, 30, 20, 0, 2*Math.PI, false);
ctx.fillStyle = "rgba(0,0,255,0.5)";
ctx.fill();
ctx.beginPath();
ctx.arc(70,60,30,0,2*Math.PI);
ctx.stroke();
画弧 arcTo(x1,y1,x2,y2,radius)
ctx.beginPath();
ctx.arc(30,30,20,0,2*Math.PI);
ctx.moveTo(150,20);
ctx.arcTo(150,100,50,20,30);
ctx.stroke();
画直线
moveTo(x,y),移动笔触到(x,y) lineTo(x,y),从上一点开始绘制一条直线
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(150,150);
ctx.stroke();
ctx.moveTo(200,100);
ctx.lineTo(200,200);
ctx.lineTo(300,200);
ctx.fill(); // 这里会自动闭合,所以不用把终点移到起始点也行
ctx.beginPath();
ctx.arc(75,75,50,0,Math.PI*2,true); // 绘制
ctx.moveTo(110,75);
ctx.arc(75,75,35,0,Math.PI,false); // 口(顺时针)
ctx.moveTo(65,65);
ctx.arc(60,65,5,0,Math.PI*2,true); // 左眼
ctx.moveTo(95,65);
ctx.arc(90,65,5,0,Math.PI*2,true); // 右眼
ctx.stroke();
画曲线
- 二次贝塞尔曲线 quadraticCurveTo(cx,cy,x,y) 从上一点开始绘制一条二次曲线,到(x,y),以(cx,cy)为控制点
ctx.beginPath();
ctx.moveTo(100,100);
ctx.quadraticCurveTo(100,50,202,200);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(300,100);
ctx.quadraticCurveTo(300,50,202,200);
ctx.fill();
- 三次贝塞尔曲线 bezierCurveTo(c1x,c1y,c2x,c2y,x,y); 从上一点绘制曲线到(x,y),以(c1x,c1y)和(c2x,c2y)为控制点
ctx.beginPath();
ctx.moveTo(75,40);
ctx.bezierCurveTo(75,37,70,25,50,25);
ctx.bezierCurveTo(20,25,20,62.5,20,62.5);
ctx.bezierCurveTo(20,80,40,102,75,120);
ctx.bezierCurveTo(110,102,130,80,130,62.5);
ctx.bezierCurveTo(130,62.5,130,25,100,25);
ctx.bezierCurveTo(85,25,75,37,75,40);
ctx.fill();
绘制文本
- fillText(text,x,y[, maxWidth]) 在指定的(x,y)位置填充指定的文本,绘制的最大宽度是可选的.
- strokeText(text,x,y[, maxWidth]) 在指定的(x,y)位置绘制文本边框,绘制的最大宽度是可选的.
- font = value 当前我们用来绘制文本的样式. 这个字符串使用和 CSS font 属性相同的语法. 默认的字体是 10px sans-serif。
- textAlign = value 文本对齐选项. 可选的值包括:start, end, left, right or center. 默认值是 start
- textBaseline = value 基线对齐选项. 可选的值包括:top, hanging, middle, alphabetic, ideographic, bottom。默认值是 alphabetic。
- direction = value 文本方向。可能的值包括:ltr, rtl, inherit。默认值是 inherit。
ctx.font = "bold 20px Arial";
ctx.textAlign = "center";
ctx.textBaseLine = "middle";
ctx.fillText("CANVAS", 100,100);
ctx.font = "bold 20px Arial";
ctx.textAlign = "start";
ctx.textBaseLine = "middle";
ctx.strokeText("CANVAS", 100,120);
Path2D对象
Path2D()会返回一个新初始化的Path2D对象(可能将某一个路径作为变量——创建一个它的副本,或者将一个包含SVG path数据的字符串作为变量)。
let rectangle = new Path2D();
rectangle.rect(10,10,40,50);
let circle = new Path2D();
circle.arc(100,100,20,0,2*Math.PI);
ctx.fill(circle);
ctx.stroke(rectangle);
变换
状态的保存恢复
- save() 保存画布的所有状态,推入栈中
- restore() 将状态推出栈
- 状态:个人理解,就是ctx的一些属性,比如填充颜色,线条粗细等
ctx.fillRect(0,0,150,150);
ctx.save();
ctx.fillStyle = "#09f"
ctx.fillRect(15,15,120,120);
ctx.save();
ctx.fillStyle = "#fff";
ctx.fillRect(30,30,90,90)
ctx.restore();
ctx.fillRect(45,45,60,60)
ctx.restore();
ctx.fillRect(60,60,30,30);
ctx.font = "bold 20px Arial";
ctx.fillText("我爱你", 200,200);
ctx.save();
ctx.font = "bold 12px Arial";
ctx.fillText("我爱你", 200,250);
ctx.restore();
ctx.strokeText("我爱你",200,150)
移动,旋转
translate(xy) 将原点坐标移到(x,y)
rotate(angle) 围绕原点旋转图像angle弧度
ctx.translate(75,75);
for (var i=1;i<6;i++){ // Loop through rings (from inside to out)
ctx.save();
ctx.fillStyle = 'rgb('+(51*i)+','+(255-51*i)+',255)';
for (var j=0;j<i*6;j++){ // draw individual dots
ctx.rotate(Math.PI*2/(i*6));
ctx.beginPath();
ctx.arc(0,i*12.5,5,0,Math.PI*2,true);
ctx.fill();
}
ctx.restore();
}
缩放
scale(x,y) 方法可以缩放画布的水平和垂直的单位。两个参数都是实数,可以为负数,x 为水平缩放因子,y 为垂直缩放因子,如果比1小,会比缩放图形, 如果比1大会放大图形。默认值为1, 为实际大小。
ctx.fillRect(20,20,40,20);
ctx.scale(1,2);
ctx.fillRect(20,40,40,20);
translate(0,canvas.height);
scale(1,-1);
变形
- transform(m11, m12, m21, m22, dx, dy) 这个方法是将当前的变形矩阵乘上一个基于自身参数的矩阵,在这里我们用下面的矩阵:
m11 m12 dx
m21 m22 dy
0 0 1
m11:水平方向的缩放
m12:水平方向的倾斜偏移
m21:竖直方向的倾斜偏移
m22:竖直方向的缩放
dx:水平方向的移动
dy:竖直方向的移动
- setTransform(m11, m12, m21, m22, dx, dy)
- resetTransform() 重置当前变形为单位矩阵,它和调用以下语句是一样的:
ctx.setTransform(1, 0, 0, 1, 0, 0);
var sin = Math.sin(Math.PI/6);
var cos = Math.cos(Math.PI/6);
ctx.translate(100, 100);
var c = 0;
for (var i=0; i <= 12; i++) {
c = Math.floor(255 / 12 * i);
ctx.fillStyle = "rgb(" + c + "," + c + "," + c + ")";
ctx.fillRect(0, 0, 100, 10);
ctx.transform(cos, sin, -sin, cos, 0, 0);
}
ctx.setTransform(-1, 0, 0, 1, 100, 100);
ctx.fillStyle = "rgba(255, 128, 255, 0.5)";
ctx.fillRect(0, 50, 100, 100);