这是我参与更文挑战的第1天,活动详情查看: 更文挑战
概念:
广义:h5新增canvas 2d 绘图功能 在html中:
- canvas 是html 标签
- canvas可以理解为一张画布
- 我们需要用js 在canvas 里绘制图形
<!--canvas 默认宽:300px 高:150px-->
<cavnas id="canvas" width="700" height="700"></canvas>
<script>
const canvas = document.querySelector('#canvas');
// 获取画笔
const ctx = canvas.selector('2d')
</script>
如何设置canvas的尺寸及尺寸限制
设置canvas dom 元素的 width height 属性。 canvas 的尺寸不能过大 ,尽量控制在4000 以内。 canvas 具体极限值因浏览器、平台不同而不同。 注意:不要使用css 设置canvas 尺寸。 在css中设置画布的大小会引起画布的拉伸、锯边等怪异行为。
canvas 上下文对象
如何获取canvas上下文对象
获取上下文对象的方法:canvas.getContext(‘2d’)
<canvas id="canvas" width="700" height="700">不兼容</canvas>
<script>
/*获取canvas画布*/
const canvas=document.getElementById('canvas');
/*获取画笔*/
const ctx=canvas.getContext('2d');
/*红色的填充矩形*/
ctx.fillStyle='red';
ctx.fillRect(20,20,300,200);
</script>
获取了上下文对象后,如何用它画画?
使用画笔在canvas 上画画,要考虑三个方面:
- 颜色
- 形状
- 绘图方法
兼容性
- canvas 兼容ie9 及其以上
canvas绘图的步骤
- 建立canvas 画布。
- 通过canvas 画布获取上下文对象,也就是画笔。
- 设置画笔颜色。
- 设置图形形状。
- 绘制图形。
canvas 画布的坐标系和栅格?
- canvas 的坐标系是二维直角坐标系,由x轴和y轴组成。
- canvas 坐标系中横向的轴为x轴,越往右越大;竖向的轴为y 轴,越往下越大。
- canvas 坐标系是以像素的宽高为基底的 栅格就是右图的4 个格子,每一个格子就是一个像素,像素具有rgba 数据。 像素的数量等于canvas 画布的宽度乘以高度。
矩形的绘制方法
填充矩形方法:fillRect(x,y,w,h)
<canvas id="canvas"></canvas>
<script>
const canvas=document.getElementById('canvas');
// 将画布的宽高设为浏览器的宽高
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
//画笔
const ctx=canvas.getContext('2d');
/*填充色*/
ctx.fillStyle='red';
/*填充矩形方法:fillRect(x,y,w,h)*/
ctx.fillRect(50,50,400,200);
</script>
描边矩形方法:strokeRect(x,y,w,h)
<canvas id="canvas"></canvas>
<script>
const canvas=document.getElementById('canvas');
// 将画布的宽高设为浏览器的宽高
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
// 画笔
const ctx=canvas.getContext('2d');
// 描边色, 默认黑色
// ctx.strokeStyle='maroon';
// 描边矩形方法:strokeRect(x,y,w,h)
ctx.strokeRect(50,50,400,200);
</script>
清理矩形方法:clearRect(x,y,w,h)
<canvas id="canvas"></canvas>
<script>
const canvas=document.getElementById('canvas');
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
//画笔
const ctx=canvas.getContext('2d');
/*描边宽度*/
ctx.lineWidth=20;
/*填充色*/
ctx.fillStyle='red';
/*描边色*/
// ctx.strokeStyle='maroon';
// /*填充矩形方法:fillRect(x,y,w,h)*/
ctx.fillRect(50,50,400,200);
// /*描边矩形方法:strokeRect(x,y,w,h)*/
ctx.strokeRect(50,50,400,200);
// /*清理矩形方法:clearRect(x,y,w,h)*/
ctx.clearRect(50,50,400,200);
</script>
绘制路径的步骤
- 开始建立路径:beginPath()
- 向路径集合中添加子路径:
- [ moveTo(x,y); 形状; closePath() 可选,
- moveTo(x,y); 形状; closePath() 可选,
- moveTo(x,y); 形状; closePath() 可选, ]
- 显示路径:填充fill() ,描边stroke()
子路径的形状
- 直线:lineTo(x,y);
<canvas id="canvas"></canvas>
<script>
const canvas=document.getElementById('canvas');
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
//画笔
const ctx=canvas.getContext('2d');
ctx.lineWidth=10;
/*直线:lineTo(x,y); */
ctx.beginPath();
ctx.moveTo(50,100);
ctx.lineTo(400,100);
ctx.lineTo(400,300);
ctx.closePath();
ctx.stroke();
</script>
- 圆弧:arc(x,y,半径,开始弧度,结束弧度,方向)
圆弧 arc(x,y,半径,开始弧度,结束弧度,方向)
<canvas id="canvas"></canvas>
<script>
const canvas=document.getElementById('canvas');
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
//画笔
const ctx=canvas.getContext('2d');
ctx.lineWidth=10;
/*
* 360° = Math.PI*2
* 1°=Math.PI*2/360
* */
/*arc(x,y,半径,开始弧度,结束弧度,方向)*/
ctx.beginPath();
ctx.arc(
300,300,
50,
0,Math.PI*3/2
)
// 第二个圆的起点
ctx.moveTo(370,500);
ctx.arc(
300,500,
70,
0,Math.PI*2
)
ctx.stroke();
</script>
- 切线圆弧:arcTo(x1,y1,x2,y2,半径)
<canvas id="canvas"></canvas>
<script>
const canvas=document.getElementById('canvas');
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
//画笔
const ctx=canvas.getContext('2d');
ctx.lineWidth=10;
/*切线圆弧:arcTo(x1,y1,x2,y2,半径)*/
ctx.beginPath();
ctx.moveTo(50,100);
ctx.lineTo(400,100);
ctx.lineTo(400,300);
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = 'red'
ctx.moveTo(50,100);
ctx.arcTo(400,100,400,300,100);
ctx.stroke();
</script>
- 二次贝塞尔曲线:quadraticCurverTo(cpx1,cpy1,x,y)
<canvas id="canvas"></canvas>
<script>
const canvas=document.getElementById('canvas');
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
//画笔
const ctx=canvas.getContext('2d');
ctx.lineWidth=10;
/*二次贝塞尔曲线:quadraCurverTo(cpx1,cpy1,x,y)*/
ctx.beginPath();
ctx.moveTo(50,100);
ctx.quadraticCurveTo(200,60,400,300);
ctx.stroke();
</script>
- 三次贝塞尔曲线:bezierCurverTo(cpx1,cpy1,cpx2,cpy2,x,y)
<canvas id="canvas"></canvas>
<script>
const canvas=document.getElementById('canvas');
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
//画笔
const ctx=canvas.getContext('2d');
ctx.lineWidth=10;
ctx.beginPath();
ctx.moveTo(50,100);
// 三次贝塞尔曲线:bezierCurverTo(cpx1,cpy1,cpx2,cpy2,x,y)
ctx.bezierCurveTo(
400,0,
400,400,
700,300);
ctx.stroke();
</script>
- 矩形:rect(x,y,w,h)
<script>
const canvas=document.getElementById('canvas');
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
//画笔
const ctx=canvas.getContext('2d');
ctx.lineWidth=10;
// 矩形:rect(x,y,w,h)
ctx.beginPath();
ctx.rect(50,50,100,100);
ctx.rect(50,200,100,100);
ctx.stroke();
</script>
绘制原理
路径和子路径的概念
路径:
- 路径是子路径的集合。
- 一个上下文对象同时只有一个路径,想要绘制新的路径,就要把当前路径置空。
- beginPath() 方法当前路径置空,也就是将路径恢复到默认状态,让之后绘制的路径不受以前路径的影响。
子路径:
- 子路径是一条只有一个起点的、连续不断开的线。
- moveTo(x,y) 是设置路径起点的方法,也是创建一条新的子路径的方法。
- 路径里的第一条子路径可以无需设置起点,它的起点默认是子路径中的第一个点。
注:rect(x,y,w,h) 绘制路径时,会具备moveTo() 功能。