1. 什么是canvas
- 是h5新增的一个标签,可以通过js在这个标签上绘制各种图案,可以通过js在这个标签上绘制各种图案
- 拥有多种绘制路径、矩阵、原形、字符以及图片的方法
1. canvas使用步骤
- 创建一个canvas标签
- 通过js拿到canvas标签
- 从cavas标签中获取到绘图工具
- 通过绘图工具在canvas标签上绘制图形
- 以绘制一条直线为例子
4-1. 设置路径的起点
4-2. 设置路径的终点
4-3. 告知canvas连接这两个点
<script>
// 2. 通过js拿到canvas标签
let oCanvas = document.querySelector('canvas')
// 3. 从cavas标签中获取到绘图工具
let oCtx = oCanvas.getContext('2d')
// 4. 通过绘图工具在canvas标签上绘制图形
// eg:简单地绘制直线
// 4-1. 设置路径的起点
oCtx.moveTo(50, 50)
// 4-2. 设置路径的终点
oCtx.lineTo(200, 50)
// 4-3. 告知canvas连接这两个点
oCtx.stroke()
</script>
效果如图:
2. 使用canvas的注意点
- canvas标签有默认的宽度和高度(300*150px)
- 不能通过css选择器的属性width和height来设置其宽高
* 倘若直接修改canvas的宽高,其采用在原有宽高的基础上拉伸的方式,会影响到里面的内容的宽高和形状
* 需要通过canvas标签提供的行内属性来修改
eg:
- canvas内部规定线条的粗细是1px,颜色是黑色,但是实际情况下,粗细是2px,并且颜色不是纯黑色
当需要绘制显示的时候,会采用以线条的中线去对齐页面上两个小格子之间的线条
所以此时该线条占用了两个像素的各一半,会自动去填满
剩余的像素部分
默认情况canvas线条的颜色是黑色,但是由于占用了两个像素的一半,一半没有颜色,一半是黑色,所以颜色会变淡
解决方法:向上挪动0.5px的像素,使其与1个像素的底部对齐,效果:
oCtx.moveTo(50, 50.5)
oCtx.lineTo(200, 50.5)
2. canvas线条相关
1. 基础属性
属性 | 含义 |
---|---|
lineWidth | 线条宽度 |
strokeStyle | 线条颜色 |
lineCap | 线末端类型 (butt默认)、round、square |
2. 绘制多条直线
重复地绘制即可,只不过canvas会默认复原前面的直线样式,需要重新开启一个路径
oCtx.beginPath()
let oCanvas = document.querySelector('canvas')
let oCtx = oCanvas.getContext('2d')
// 修改线条的高度,颜色,线条两端添加装饰
oCtx.lineWidth = 20
oCtx.strokeStyle = 'pink'
oCtx.lineCap = 'round'
oCtx.moveTo(50, 50)
oCtx.lineTo(200, 50)
oCtx.stroke()
// 默认会复用前面的直线样式
oCtx.beginPath() //表示重新开启一个路径
oCtx.strokeStyle = 'green' //重新设置样式
oCtx.moveTo(50, 70)
oCtx.lineTo(200, 70)
oCtx.stroke()
oCtx.beginPath()
oCtx.strokeStyle = 'black'
oCtx.moveTo(50, 90)
oCtx.lineTo(200, 90)
oCtx.stroke()
3. canvas绘制简单图形
1. 三角形
方法 | 含义 |
---|---|
closePath | 自动创建从当前点回到起始点的闭合路径 |
lineJoin | 设置相交线的拐点样式 |
绘图的基本思路:找到图形的顶点,比如三角形有三个顶点,然后通过stroke方法连接起来就可以了
坑点1:stroke默认不会去连接最后一个点到起始点
- 方法1:在起始点出通过lineTo再设置一个点,效果很差,衔接处处理不到位,如下图所示
- 方法2:使用
closePath
,自动创建从当前点回到起始点的路径 - 可以通过
lineJoin
设置相交线的拐点样式,比如笔直的拐角连接,变圆或者切片miter(默认)、round、bevel
let oCanvas = document.querySelector('canvas')
let oCtx = oCanvas.getContext('2d')
// 修改线条的高度,颜色,线条两端添加装饰
oCtx.lineWidth = 10
oCtx.strokeStyle = 'pink'
oCtx.moveTo(50, 50)
oCtx.lineTo(150, 50)
oCtx.lineTo(100, 90)
// 默认情况下不会从最后一个点链接回起点,所以需要再加一个起点
// oCtx.lineTo(50, 50)
// 并且闭合的位置,通过lineTo转角没办法很好地闭合
oCtx.closePath()
// 可以设置线条链接的样式
// oCtx.lineJoin = 'bevel'
// oCtx.lineJoin = 'round'
oCtx.stroke()
2. 正方形
思路也一样,只不过设置四个点就ok
3. 绘制填充图形
1. 填充颜色
fillStyle
属性
fill()
方法
2. 非零环绕规则
从内部的矩形拉一条先出来,result用来计数
如果路径为顺时针则+1
如果路径为逆时针则-1
只要result为0就不填充,不为0就填充
-
情况1:看下面的图
对于内部矩形,从内部拉出来一条线,result为2,填充
对于看下面的图从内部拉出来一条线,result为2,填充
-
情况2
内部为0,不填充
外部为1,填充
oCtx.moveTo(50, 50)
oCtx.lineTo(150, 50)
oCtx.lineTo(150, 150)
oCtx.lineTo(50, 150)
oCtx.closePath()
//逆时针,注意,这里没有重开一条路径,所以两个矩形框都走的一个路径
oCtx.moveTo(125, 75)
oCtx.lineTo(75, 75)
oCtx.lineTo(75, 125)
oCtx.lineTo(125, 125)
oCtx.closePath()
oCtx.lineWidth = 4
oCtx.strokeStyle = 'pink'
oCtx.lineJoin = 'round'
oCtx.fillStyle = "#058864" //这个要写在fill之前
oCtx.fill()
oCtx.stroke()