Canvas 基础
概述
Canvas 是 html5 的一个新标签,相当于一个画布,用来绘制丰富的图形,最终渲染在浏览器上。 Canvas 本身不具备图形的能力,需配合 Javascript 提供的 CanvasAPI,才能绘制图形,以及交互。 Canvas 绘制的图形是一个位图,绘制的内容不属于 dom 元素,比 dom 元素绘制有更高的渲染能力。
- 缩放会导致图像失真
- 可以操作每个点位的像素,进而实现高度自定义的图形绘制和动画效果
- 相当于 img 引入的图片,可以右键另存
应用领域:
- 可视化图表
- h5 游戏制作
- banner 广告
创建画布和画笔
<canvas>标签,行内元素
html
<!-- canvas 元素 -->
<canvas id="c1"></canvas>
<script>
// 方式一
// 获取画布
const canvas = document.querySelector("#c1");
// 创建画笔
const context = canvas.getContext("2d"); // CanvasRenderingContext2D 对象
// 方式二
const canvas2 = document.createElement("canvas");
document.body.append(canvas2);
// 创建画笔
const context2 = canvas2.getContext("2d");
// 版本检查
if (!canvas2.getContext) {
console.log("当前浏览器版本过低,更换或升级浏览器后继续");
}
</script>画布区域特点
canvas,行内元素,支持设置 width 和 height(默认 300*150),也可以使用 style 设置宽高。
- 坐标系
- 每个画布都有一个坐标系统,画布左上角为默认原点(0, 0)
- 画布区域
- 使用 width 和 height 属性控制的区域,该区域为坐标系的大小
- 放置区域
- 使用 style 样式控制区域大小,默认放置区域与画布区域相同
- 放置区域比画布区域不一致时,画布中图形会等比缩放,导致失真 绘制图形
绘制矩形(填充矩形、描边矩形)
- 填充矩形:fillRect(orig_x, orig_y, width, height)
- 描边矩形:strokeRect(orig_x, orig_y, width, height)
- 矩形路径:rect(orig_x, orig_y, width, height)
- 必须搭配 stroke() 或 fill() 使用
- 设置样式:必须在图形绘制前设置
- fillStyle:填充颜色
- strokeStyle:描边颜色
- lineWidth:描边线宽
js
// 创建画布
const canvas = document.createElement("canvas");
document.body.append(canvas);
canvas.width = 400;
canvas.height = 400;
// 创建画笔
const context = canvas.getContext("2d");
// 1.填充矩形,ctx.fillRect(orig_x, orig_y, width, height)
context.fillRect(0, 0, 100, 100);
// 2.描边矩形
context.strokeRect(0, 0, 100, 100);
// 3.矩形路径,必须搭配 stroke 或 fill 使用,才能显示
context.rect(0, 0, 100, 100);
context.stroke(); // 描边矩形
context.fill(); // 填充矩形- beginPath 方法
- stroke 和 fill 会对之前绘制的所有路径进行绘制
- 使用 beginPath 方法,为不同路径设置开关
- 不会影响 fillRect 和 strokeRect 绘制
- 只与路径有关,与属性无关
js
// 第一次
context.fillStyle = "#f00";
context.beginPath();
context.rect(0, 0, 100, 100);
context.stroke(); // 描边矩形
// 第二次
context.fillStyle = "#0f0";
context.beginPath();
context.rect(100, 0, 100, 100);
context.fill(); // 填充矩形绘制圆角矩形
roundRect(orig_x, orig_y, width, height, radius)
圆角半径 radius 写法
- 一个值,10 或[10],四个角半径均为 10
- 两个值,[10, 20],左上和右下,右上和左下
- 三个值,[10, 20, 30],左上,右上和左下,右下
- 四个值,[10, 20, 30, 40],左上,右上,右下,左下
js
// 圆角矩形,orig_x,orig_y,width,height,radius
context.roundRect(0, 0, 100, 100, 3);绘制直线和曲线
- moveTo(x, y),将画笔移动到指定坐标点
- lineTo(x, y),从上一个点绘制直线到指定的点
js
context.moveTo(20, 20); // 移动
context.lineTo(40, 20); // 绘制直线路径[20, 20] -> [40, 20]
context.lineTo(40, 40); // 绘制直线路径[40, 20] -> [40, 40]
context.stroke(); // 绘制图形- 线条 API
- 属性 lineWidth:线宽
- 属性 lineCap:端点样式
- butt:默认,平的
- round:圆头
- square:方头
- 属性 lineJoin:折线连接处样式
- miter:默认,尖的
- round:圆头
- bevel:平的
- 属性 miterLimit:设置折线形成的尖限制
- lineJoin=miter 时有效
- 线粗夹角小时,尖过长,可裁剪
- 方法 setLineDash(array):设置虚线
- 参数 array,表示线段长度和留白长度;
- array=[10],线段长 10,留白长 10
- array=[20, 10],线段长 20,留白长 10
- array=[10, 20, 30],按数组,无限延续,线段 10-留白 20-线段 30-留白 10-...
- 属性 lineDashOffset:设置虚线起始位置偏移
- 虚线时有效
- 动态控制 lineDashOffset 可以实现动画效果
- 方法 closePath():闭合路径
- 使用 closePath 方法,使得曲线首尾自动闭合
虚线动画
js
context.beginPath();
context.moveTo(0, 10);
context.lineWidth = 10;
context.strokeStyle = "#f00";
context.setLineDash([200]);
context.lineDashOffset = 200; // 偏移
function move() {
context.beginPath();
context.lineDashOffset -= 1;
context.stroke();
if (context.lineDashOffset == 200) {
context.lineDashOffset = 200;
}
requestAnimationFrame(move);
}
requestAnimationFrame(move);- 线条区域填充
- 多个连续线条合围区域,可以使用 fill 填充 绘制圆弧
- arc(orig_x, orig_y, r, startAngle, endAngle[, dir])
- x、y,圆心坐标
- r,半径
- startAngle,起始绘制角度(弧度,1 角度=Math.PI / 180),默认圆心 x 轴右侧半径位置为绘制起点
- endAngle,结束点角度(弧度)
- dir,绘制方向
- false,默认,顺时针
- true,逆时针
- arcTo(x1, y1, x2, y2, r)
- 通过 3 个控制点绘制圆弧
- x1,y1,第二个点
- x2,y2,第三个点
- 按 1、2、3 顺序连线,形成一个夹角,通过半径确定圆弧
js
//
context.beginPath();
context.arc(100, 100, 50, 0, Math.PI); // 绘制半圆路径
context.stroke();
//
context.beginPath();
context.MoveTo(0, 100);
context.arcTo(100, 100, 100, 0, 30); // 绘制半圆路径
context.stroke();绘制椭圆
- ellipse(x, y, rx, ry, rotate, startAngle, endAngle[, dir])
- x、y,圆心坐标
- rx、ry,x 轴/y 轴半径
- rotate,x 轴旋转角度(弧度,1 角度=Math.PI / 180,顺时针)
- startAngle,起始绘制角度(弧度),默认圆心 x 轴右侧半径位置为绘制起点
- endAngle,结束点角度(弧度)
- dir,绘制方向
- false,默认,顺时针
- true,逆时针 // context.beginPath(); context.ellipse(100, 100, 50, 50, 0, 0, Math.PI * 2); // 绘制椭圆路径 context.stroke(); 绘制曲线 canvas 提供绘制曲线的方法:贝赛尔曲线(二次、三次)
- 二次贝赛尔曲线:一个起点、终点,一个控制点
- quadraticCurveTo(cx1, cy1, ex, ey)
- cx1、cy1,控制点坐标
- ex、ey,终点坐标
- 三次贝赛尔曲线:一个起点、终点,两个控制点
- bezierCurveTo(cx1, cy1, cx2, cy2, ex, ey)
- cx1、cy1、cx2、cy2,控制点坐标
- ex、ey,终点坐标 // context.beginPath(); context.MoveTo(50, 200); context.quadraticCurveTo(150, 100, 250, 200); context.stroke(); 绘制文本
- fillText(textStr, x, y[, maxWidth]),填充文本
- textStr
- x、y,文本位置
- maxWidth,可选,设置文本最大宽度
- strokeText(),描边文本
- 属性 font:设置文本样式(粗体,斜体,字号,字体)
- 必须设置字体,否则样式无效
- 属性 textAlign:设置基于锚点水平位置(left、center、right)
- 属性 textBaseline:设置基于锚点垂直位置(top、center、bottom)
js
//
context.beginPath();
context.font = "bold italic 80px sans-serif";
context.fillText("hello world", 100, 100);