Canvas
介绍
canvas 是绘制图形的。
canvas 是一个二维网格。左上角坐标为 (0,0)
首先创建一个画布
<canvas id="cvs" width="1000" height="800"></canvas>
然后获取到画布和二维模型
let canvas = document.getElementById('cvs');
let ctx = canvas.getContext('2d');
ctx 就相当于画笔了
检查支持性
let canvas = document.getElementById('cvs');
if (canvas.getContext) {
// 支持canvas
} else {
// 不支持canvas
}
大小
canvas 默认大小是宽度 300px,高度 150px。不能设置百分比,不能通过 css 设置宽高
方式一、直接设置 width 和 height 属性
<canvas id="cvs" width="1000" height="800"></canvas>
方式二、通过 js 设置
let canvas = document.getElementById('cvs');
let ctx = canvas.getContext('2d');
ctx.width = 1000; // 可以不写单位px
ctx.height = 800;
如果想动态设置宽高,比如想让 canvas 的宽度占据屏幕的 70%,根据16:9
的比例计算高度
const canvasWidth = window.innerWidth * 0.7;
const canvasHeight = (canvasWidth * 9) / 16;
ctx.width = canvasWidth;
ctx.height = canvasHeight;
线
ctx.moveTo(10, 20); // 定义起点
ctx.lineTo(50, 100); // 定义终点
ctx.strokeStyle = '#f00'; // 线的颜色
ctx.stroke(); // 画线
注意设置样式要在绘制之前,否则无效
画个树:
ctx.beginPath();
ctx.moveTo(500, 50);
ctx.lineTo(300, 200);
ctx.lineTo(450, 200);
ctx.lineTo(200, 300);
ctx.lineTo(450, 300);
ctx.lineTo(450, 400);
ctx.lineTo(550, 400);
ctx.lineTo(550, 300);
ctx.lineTo(770, 300);
ctx.lineTo(550, 200);
ctx.lineTo(700, 200);
ctx.fillStyle = '#0f0';
ctx.fill();
ctx.strokeStyle = '#0f0';
ctx.stroke();
ctx.closePath();
电子画笔
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let drawStatus = false;
canvas.onmousedown = e => {
ctx.moveTo(e.offsetX, e.offsetY);
drawStatus = true;
};
canvas.onmouseup = () => (drawStatus = false);
canvas.onmouseout = () => {
if (drawStatus) {
drawStatus = false;
}
};
canvas.onmousemove = e => {
if (drawStatus) {
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
}
};
二次贝塞尔曲线
二次贝塞尔曲线有一个开始点、一个结束点以及一个控制点
quadraticCurveTo(cp1x, cp1y, x, y); // cp1x,cp1y为一个控制点,x,y为结束点
示例:对钩
ctx.beginPath();
ctx.moveTo(500, 400); // 如果不设置,那么起始点位置就在控制点,视觉上就是绘制了一条直线
ctx.quadraticCurveTo(500, 600, 900, 400);
ctx.stroke();
ctx.closePath();
三次贝塞尔曲线
三次贝塞尔曲线有两个控制点
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); // cp1x,cp1y 为控制点一,cp2x,cp2y为控制点二,x,y为结束点
示例:红色爱心
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.fillStyle = '#f00';
ctx.fill();
路径
ctx.beginPath();
ctx.closePath();
如果要绘制多个图形,需要声明开始和结束路径,否则图形会相互干扰,影响结果。
- 使用
fill()
时,路径自动闭合,可以不用closePath()
。 - 使用
stroke()
时,不会闭合路径,如果没有closePath()
,则只绘制了两条线段,不是完整的三角形
矩形
fillRect(x, y, width, height)
绘制填充的矩形strokeRect(x, y, width, height)
绘制矩形的边框clearRect(x, y, width, height)
清除指定矩形区域
ctx.beginPath();
ctx.fillStyle = '#eee';
ctx.fillRect(50, 400, 200, 100);
ctx.clearRect(60, 420, 180, 60); // 在内部擦除一个矩形
ctx.strokeStyle = '#666';
ctx.strokeRect(140, 430, 30, 30);
ctx.closePath();
ctx.fillRect(50,400,200,100)
表示矩形左上角坐标为(50,400),宽 200px,高 100px
圆
arc(x, y, radius, startAngle, endAngle, anticlockwise);
参数分别表示圆心坐标,半径,起始弧度,结束弧度,绘制方向
ctx.arc(100, 100, 50, 0, 2 * Math.PI, false);
ctx.fillStyle = '#f00';
ctx.fill(); // 填充
角度与弧度的 js 表达式:
弧度 = (Math.PI/180) * 角度
anticlockwise
为 true,则按逆时针绘制,false 按顺时针绘制,默认为 false
数学中的角度逆时针为正,而这里的起止角是以顺时针为正。当起角设为 0 度,止角设为 120 度时,会从右边水平位置向下旋转 120 度。
文字
ctx.beginPath();
ctx.font = '100px 微软雅黑'; // 字体大小和类型
ctx.strokeStyle = 'gold';
ctx.strokeText('hello world !', 800, 200);
ctx.fillStyle = '#00f';
ctx.fillText('canvas', 800, 400); // 文字和位置
ctx.closePath();