canvas-画布
概述
HTML5 的 canvas 元素用于定义画布,是一个矩形区域,默认颜色为白色,默认大小为 300 * 150;通过 JavaScript 可以在该区域上绘制图像 ,开发人员可以控制其每一个像素;canvas 拥有多种绘制:路径、矩形、圆形、字符以及添加图像的方法。
注意:如果要设置画布的大小不能通过 CSS 样式进行设置,只能通过元素的 width
、height
属性进行设置,否则会出现问题。
相关属性、方法
getContext()
canvas.getContext(contextID)
获取一个用于在画布上绘图的环境(上下文,相当于一个绘制工具箱);返回值为一个 CanvasRenderingContext2D 对象,该对象包含了一个画布所使用的大多数方法。
canvas
canvas 元素对象contextID
绘制的类型,是个字符串,目前支持 2D(二维)绘图
moveTo()
context.moveTo(x,y)
将画笔移动到指定位置,准备绘制线条
context
获取的上下文(绘图环境)x, y
画布中某个位置(横纵坐标)
lineTo()
context.lineTo(x,y)
该方法用于在画布上添加一个新点,然后创建从该点到画布中最后指定点(上一个点)的线条;该方法并不会真正绘制线条。
- 参数同 moveTo()
stroke()
context.stroke()
该方法会在画布上实际地绘制出通过 moveTo() 和 lineTo() 方法定义的路径;路径的颜色默认为黑色。
示例:绘制一个三角形
<canvas id="can" width="500" height="400"></canvas>
<script> var c = document.querySelector('#can') // 获取绘图环境 var ctx = c.getContext('2d') // 移动位置 ctx.moveTo(100, 100) // 添加点(斜边) ctx.lineTo(200, 300) // 添加新点(直角边) ctx.lineTo(100, 300) // 添加新点(直角边) ctx.lineTo(100, 100) ctx.stroke() </script>
CSS:
canvas {
border: 1px solid gray;
}
关于线条问题
canvas 中的线条默认的粗细为 1px
,默认颜色为黑色,但是看到的线条颜色为灰色,线条粗细为 2px。
产生原因:canvas 绘制线条时是从中间向两边绘制的,比如说定义 x 坐标为 1,会以 1 为中心,向两边分为 0.5px(上下或左右),但是浏览器在渲染时不支持小于 0.5px 的内容显示,所以会将 0.5px 绘制成 1px,然后两边各 1px,所以得到的就是双倍的线条,颜色比较浅。
解决办法:将 x 坐标或 y 坐标,向前或向后移动 0.5px。
举例:
<canvas id="can" width="500" height="400"></canvas>
<script> var c = document.querySelector('#can') // 获取上下文(绘图工具箱) var ctx = c.getContext('2d') // 移动位置 ctx.moveTo(100, 100.5) // 向下移动 0.5px // 添加点 ctx.lineTo(200, 100.5) // 向下移动 0.5px // 移动位置 ctx.moveTo(100, 150) // 添加新点 ctx.lineTo(200, 150) ctx.stroke() </script>
CSS:
canvas {
border: 1px solid gray;
}
修改线条颜色和粗细
strokeStyle
context.strokeStyle=color | gradient | pattern
通过该属性可以设置或返回通过 stroke() 方法绘制的线条的颜色、渐变或模式。
color
css 颜色值gradient
渐变对象pattern
用于填充绘图的 pattern 对象
lineWidth
context.lineWidth=number
该属性可设置或返回当前线条的宽度,以像素计
number
像素值,不带 px 后缀
示例:绘制一条线颜色为红色粗细为 6px,另一条线颜色为蓝色粗细为 10px
<canvas id="can" width="500" height="400"></canvas>
<script> var c = document.querySelector('#can') // 获取上下文(绘图工具箱) var ctx = c.getContext('2d') // 移动位置 ctx.moveTo(100, 100) // 添加点 ctx.lineTo(200, 100) // 设置线条颜色为红色 ctx.strokeStyle = 'red' // 设置线条粗细为 6px ctx.lineWidth = 6 ctx.stroke() // 移动位置 ctx.moveTo(100, 150) // 添加新点 ctx.lineTo(200, 150) // 设置线条粗细为蓝色 ctx.strokeStyle = 'blue' // 线条粗细为 10px ctx.lineWidth = 10 ctx.stroke() </script>
CSS:
canvas {
border: 1px solid gray;
}
由上图可以发现,并没有达到预期的效果,线条样式均被最后设置的样式覆盖了;这时通过 beginPath()
在指定位置开启新路径就可以解决上面的样式覆盖问题。
重置路径
beginPath()
context.beginPath()
该方法用于开始一条路径,或重置当前的路径;通过该方法可以隔开路径,这样就可以为路径设置不同的样式。
代码:
<canvas id="can" width="500" height="200"></canvas>
<script> var c = document.querySelector('#can') var ctx = c.getContext('2d') // 移动位置 ctx.moveTo(100, 100) // 添加点 ctx.lineTo(200, 100) // 设置线条颜色为红色 ctx.strokeStyle = 'red' // 设置线条粗细为 6px ctx.lineWidth = 6 ctx.stroke() // 重置路径 ctx.beginPath() // 移动位置 ctx.moveTo(100, 150) // 添加新点 ctx.lineTo(200, 150) // 设置线条粗细为蓝色 ctx.strokeStyle = 'blue' // 线条粗细为 10px ctx.lineWidth = 10 ctx.stroke() </script>
路径关闭问题
闭合路径的方法有两种,一种是手动闭合,另一种是通过 closePath()
方法来闭合路径
手动闭合
<canvas id="can" width="500" height="400"></canvas>
<script> var c = document.querySelector('#can') // 获取绘图环境 var ctx = c.getContext('2d') // 移动位置 ctx.moveTo(100, 100) // 添加点(斜边) ctx.lineTo(200, 100) // 添加新点(直角边) ctx.lineTo(200, 300) // 添加新点,手动闭合路径 ctx.lineTo(100, 100) // 设置画笔宽度 ctx.lineWidth = 10 ctx.stroke() </script>
CSS:
canvas {
border: 1px solid gray;
}
注意:通过手动闭合的路径会产生 0.5px 的像素问题,起始点和 lineTo() 的结束点无法完全闭合缺角;只是中心点的闭合,闭合的并不完美。
通过 lineTo() 方法闭合
将上述例子中的
// 添加新点,手动闭合路径
ctx.lineTo(100, 100)
替换为
// 通过方法闭合路径
ctx.closePath()
通过 closePath()
方法闭合的路径可以完美解决闭合缺角的问题。
路径填充
fill()
context.fill()
该方法用于填充当前的路径(图像),默认填充的颜色为黑色;如果路径未关闭,fill() 方法会从路径结束点到开始点之间添加一条线,以关闭该路径,然后填充颜色。
fillStyle
context.fillStryle = color | gradient | pattern
设置或返回用于填充绘画的颜色、渐变或模式。
示例:
<canvas id="can" width="500" height="400"></canvas>
<script> var c = document.querySelector('#can') var ctx = c.getContext('2d') // 移动位置 ctx.moveTo(100, 100) // 添加点(斜边) ctx.lineTo(200, 100) // 添加新点(直角边) ctx.lineTo(200, 300) // 通过方法闭合路径 ctx.closePath() // 设置填充颜色 ctx.fillStyle = 'red' // 填充路径 ctx.fill() </script>
非零匝数规则(非零环绕填充规则)
canvas 中的 fill()
填充方法遵循非零环绕填充规则,绘制的路径会根据该规则来判断是否对路径进行填充。
非零环绕填充规则:如果要判断某一区域是否会被填充,就从这一区域向外画一条直线,穿过所有路径;该线与其他路径的交点处,如果其他路径是顺时针方向画的就加 1,逆时针则减 1,如果最后相加的总和为 0,则这块区域不会被填充,非零就进行填充。
举个例子:
<canvas id="c" width="500" height="400"></canvas>
<script type="text/javascript"> var c = document.querySelector('#c') var ctx = c.getContext('2d') // 顺时针画外矩形 ctx.beginPath() ctx.moveTo(100, 100) ctx.lineTo(300, 100) ctx.lineTo(300, 300) ctx.lineTo(100, 300) ctx.closePath() // 逆时针画内矩形 ctx.moveTo(150, 150) ctx.lineTo(150, 250) ctx.lineTo(250, 250) ctx.lineTo(250, 150) ctx.closePath() // 填充 ctx.fill() </script>
CSS:
canvas {
border: 1px solid gray;
}
分析:
效果:
线条末端类型、相交线拐点类型
lineCap
context.lineCap
该属性用于设置或返回线条末端的样式;其值有:butt
默认值,平直的边缘,round
圆形样式, square
正方形样式;需要注意的是:round 和 square 会使线条略微变长,就像线条两端戴了个帽子(就是所谓的线帽)。
示例:
<canvas id="c" width="500" height="400"></canvas>
<script type="text/javascript"> var c = document.querySelector('#c') var ctx = c.getContext('2d') // 路径1 ctx.beginPath() ctx.moveTo(100, 100) ctx.lineTo(300, 100) ctx.lineWidth = '10' // 设置末端样式 ctx.lineCap = 'round' ctx.stroke() // 路径2 ctx.beginPath() ctx.moveTo(100, 150) ctx.lineTo(300, 150) ctx.lineWidth = '5' // 设置末端样式 ctx.lineCap = 'square' ctx.stroke() </script>
lineJoin
context.lineJoin
设置或返回相交线拐点的样式;其值有:bevel
斜角,round
圆角,miter
默认,尖角。
示例:
<canvas id="c" width="500" height="400"></canvas>
<script type="text/javascript"> var c = document.querySelector('#c') var ctx = c.getContext('2d') ctx.beginPath() ctx.moveTo(100, 100) ctx.lineTo(300, 100) ctx.lineTo(300, 200) ctx.closePath() ctx.lineWidth = '10' // 设置拐点样式 // ctx.lineJoin = 'round' ctx.stroke() </script>
设置前:
设置后:
虚线相关方法
setLineDash()
context.setLineDash(segments)
该方法用来设置线条的显示方式为虚线样式,该方法没有返回值(undefined)
segments
该参数是必要的,参数为一个数组;其值为一组描述交替绘制线段和间距(坐标空间单位)长度的数字。
该方法的参数分为两种:一种是数组元素为偶数个,另一种是为奇数个
偶数个情况
数组元素为两个时:数组中的第一个元素用于设置虚线的尺寸,就是每个可见线段的长度;第二个元素用于设置虚线的间隔,就是不可见线段的长度。
<canvas id="c" width="500" height="400"></canvas>
<script type="text/javascript"> var c = document.querySelector('#c') var ctx = c.getContext('2d') ctx.beginPath() ctx.moveTo(100, 100) ctx.lineTo(300, 100) // 设置虚线 ctx.setLineDash([5, 10]) ctx.lineWidth = '20' ctx.stroke() </script>
数组元素为 2 的倍数时:奇数个的元素用于顺次设置线段的长度,偶数个用于顺次设置线段的间隔。
<canvas id="c" width="500" height="400"></canvas>
<script type="text/javascript"> var c = document.querySelector('#c') var ctx = c.getContext('2d') ctx.beginPath() ctx.moveTo(100, 200) ctx.lineTo(300, 200) ctx.lineWidth = '20' // 设置虚线 ctx.setLineDash([5, 10, 15, 20]) ctx.stroke() </script>
奇数个情况
当数组元素的个数为奇数个时会自动复制,然后按照偶数个的显示方式进行显示,例如:[5, 10, 15]
会变成 [5, 10, 15, 5, 10, 15]
。
getLineDash()
context.getLineDash()
获取虚线线条的显示方式;如果数组元素的数量是奇数,数组元素会被复制,会以偶数的形式返回,例如:[5, 10, 15]
会变成 [5, 10, 15, 5, 10, 15]
返回。
lineDashOffset
ccontext.lineDashOffset
该属性用于设置虚线的偏移量,值为正时向左偏移,值为负时向右偏移。
示例:
<canvas id="c" width="500" height="400"></canvas>
<script type="text/javascript"> var c = document.querySelector('#c') var ctx = c.getContext('2d') ctx.beginPath() ctx.moveTo(100, 100) ctx.lineTo(300, 100) // 设置虚线 ctx.setLineDash([10, 5]) ctx.lineWidth = '10' ctx.stroke() ctx.beginPath() ctx.moveTo(100, 150) ctx.lineTo(300, 150) // 设置虚线 ctx.setLineDash([10, 5]) ctx.lineWidth = '10' // 设置虚线偏移量,向右偏移 10 像素 ctx.lineDashOffset = '-10' ctx.stroke() </script>
获取画布的宽、高
在上下文的 canvas
属性中可以获取画布的宽和高
<canvas id="c" width="500" height="400"></canvas>
<script type="text/javascript"> var c = document.querySelector('#c') // 获取上下文 var ctx = c.getContext('2d') // 获取画布的宽和高 var canWidth = ctx.canvas.width, canHeight = ctx.canvas.height // 打印 console.log(canWidth, canHeight) // 500 400 </script>
矩形
react()
context.react(x, y, width, height)
该方法用于绘制一个矩形;x, y
为起点(矩形左上角的坐标)width, height
为矩形的宽和高,参数均为数字不需要带单位。
注意:通过该方法绘制的矩形路径不是独立的路径。
示例:绘制一个宽为 300px,高位 100px 的矩形
<canvas width="500" height="400"></canvas>
<script> var c = document.querySelector('canvas') var ctx = c.getContext('2d') ctx.beginPath() // 绘制矩形 ctx.rect(100, 100, 300, 100) // 路径颜色 ctx.strokeStyle = 'blue' // 绘制路径 ctx.stroke() </script>
fillRect()
context.fillRect(x, y, width, height)
绘制已填充的矩形;默认填充的是黑色。通过该方法绘制的矩形有自己独立的路径。
<canvas width="500" height="400"></canvas>
<script> var c = document.querySelector('canvas') var ctx = c.getContext('2d') ctx.beginPath()`` // 绘制填充的矩形 ctx.fillRect(100, 100, 300, 100) ctx.fillStyle = 'red' ctx.fillRect(100, 250, 300, 100) </script>
clearRect()
context.clearRect(x, y, width, height)
该方法用于清除矩形;x, y
开始清除的坐标,width, height
清除的宽高。
<canvas width="500" height="400"></canvas>
<script> var c = document.querySelector('canvas') var ctx = c.getContext('2d') ctx.beginPath() // 绘制填充的矩形 ctx.fillRect(100, 100, 300, 100) ctx.fillStyle = 'red' ctx.fillRect(100, 250, 300, 100) // 清除矩形 ctx.clearRect(100, 250, 100, 50) </script>
线性渐变
createLinearGradient()
context.createLinearGradient(x0, y0, x1, y1)
该方法用于创建一个线性渐变的对象;x0, y0
为渐变的起始位置,x1, y1
为渐变的结束位置
addColorStop()
context.addColorStop(stop, color)
设置渐变对象的停止位置和渐变的颜色
stop
渐变停止的位置(也是开始的位置),值为 0.0 ~ 1.0 之间color
渐变颜色
绘制曲线
arc()
context.arc(x, y, r, sAngle, eAngle, counterclockwise)
通过该方法可以创建弧或曲线,也可以创建圆或部分圆。
x, y
圆心坐标r
圆的半径sAngle
起始角,以弧度计;弧的三点钟位置是 0 度eAngle
结束角,也是以弧度计counterclockwise
规定是逆时针还是顺时针绘图;为 false 时顺时针,为 true 时逆时针,该参数是一个可选参数
绘制伞形
绘制扇形时需要将起始点设置为圆心
<canvas width="600" height="400"></canvas>
<script> var c = document.querySelector('canvas') var ctx = c.getContext('2d') ctx.beginPath() // 将起始点设置为圆心 ctx.moveTo(300, 200) // 绘制弧度 ctx.arc(300, 200, 100, 0, (Math.PI * 3) / 2, true) // 填充 ctx.fill() </script>
文本相关
更新中。。。
还没有评论,来说两句吧...