Canvas
Canvas的注意事项
< canvas > 和 < img > 元素很相像,唯一的不同就是它并没有 src 和 alt 属性。
-< canvas > 标签只有两个属性——width和height( 单位默认为px )。当没有设置宽度和高度时,canvas 会初始化宽为
300px 和高为 150px。
- 与 < img > 元素不同,< canvas > 元素必须需要结束标签 (</ canvas >)。如结束标签不存在,则文档其余部分会被认为是替
代内容,将不会显示出来。 - 测试 canvas.getContext() 方法的存在,可以检查浏览器是否支持Canvas。
Canvas Grid 和 坐标空间
Canvas Grid 或 坐标空间
- 假如,HTML 模板中有个宽 150px, 高 150px 的 < canvas > 元素。< canvas >元素默认被网格所覆盖。
- 通常来说网格中的一个单元相当于 canvas 元素中的一像素。
- 该网格的原点位于坐标 (0,0) 的左上角。所有元素都相对于该原点放置。
- 网格也可以理解为坐标空间(坐标系),坐标原点位于canvas元素的左上角,被称为初始坐标系
- 如右图中蓝色正方形,左上角的坐标为距离左边 x 像素,距离上边y 像素,坐标为(x, y)
- 网格或坐标空间是可以变换的,后面会讲如何将原点转换到不同的位置,旋转网格甚至缩放它。
- 注意:移动了原点后,默认所有后续变换都将基于新坐标系的变换。
绘制矩形( Rectangle )
Canvas支持两种方式来绘制矩形:矩形方法 和 路径方法。
- 路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。
- 除了矩形,其他的图形都是通过一条或者多条路径组合而成的。
- 通常我们会通过众多的路径来绘制复杂的图形。
Canvas 绘图的矩形方法: - fillRect(x, y, width, height): 绘制一个填充的矩形
- strokeRect(x, y, width, height): 绘制一个矩形的边框
- clearRect(x, y, width, height): 清除指定矩形区域,让清除部分完全透明。
方法参数: - 上面的方法都包含了相同的参数。
- x 与 y 指定了在canvas画布上所绘制矩形的左上角(相对于原点)的坐标(不支持 undefined )。
- width 和 height 设置矩形的尺寸。
认识路径
什么是路径?
- 图形的基本元素是路径。路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。
- 路径是可由很多子路径构成,这些子路径都是在一个列表中,列表中所有**子路径(线、弧形等)**将构成图形。
- 一个路径,甚至一个子路径,通常都是闭合的。
使用路径绘制图形的步骤: - 1.首先需要创建路径起始点(beginPath)。
- 2.然后使用画图命令去画出路径( arc 、lineTo )。
- 3.之后把路径闭合( closePath , 不是必须)。
- 4.一旦路径生成,就能通过**描边(stroke)或填充路径区域(fill)**来渲染图形。
以下是绘制路径时,所要用到的函数 - beginPath():新建一条路径,生成之后,图形绘制命令被指向到新的路径上绘图,不会关联到旧的路径。
- closePath():闭合路径之后图形绘制命令又重新指向到 beginPath之前的上下文中。
- stroke():通过线条来绘制图形轮廓/描边**(针对当前路径图形)**。
- fill():通过填充路径的内容区域生成实心的图形**(针对当前路径图形)**。
路径-绘制直线
移动画笔(moveTo)方法
- moveTo 方法是不能画出任何东西,但是它也是路径列表的一部分
- moveTo 可以想象为在纸上作业,一支钢笔或者铅笔的笔尖从一个点到另一个点的移动过程。
- moveTo(x, y): 将笔移动到指定的坐标 x 、 y 上。
- 当 canvas 初始化或者beginPath()调用后,我们通常会使用moveTo(x, y)函数设置起点。
- 使用moveTo函数能够绘制一些不连续的路径。
绘制直线(lineTo)方法 - lineTo(x, y): 绘制一条从当前位置到指定 (x ,y)位置的直线。
- 该方法有两个参数(x , y)代表坐标系中直线结束的点。
- 开始点和之前的绘制路径有关,之前路径的结束点就是接下来的开始点。
- 当然开始点也可以通过moveTo(x, y)函数改变。
绘制一条直线
- 第一步:调用 beginPath() 来生成路径。本质上,路径是由很多子路径(线、弧形、等)构成。
- 第二步:调用moveTo、lineTo函数来绘制路径(路径可以是连续也可以不连续)。
- 第三步:闭合路径 closePath(),虽然不是必需的,但是通常都是要闭合路径。
- 第四步:调用stroke()函数来给直线描边。
路径-绘制三角形( Triangle )
绘制一个三角形步骤
- 第一步:调用 beginPath() 来生成路径。
- 第二步:调用moveTo()、lineTo()函数来绘制路径。
- 第三步:闭合路径 closePath(),不是必需的。
- closePath() 方法会通过绘制一条从当前点到开始点的直线来闭合图形。
- 如果图形是已经闭合了的,即当前点为开始点,该函数什么也不做。
- 第四步:调用**stroke()函数来给线描边,或者调用fill()**函数来填充(使用填充 fill 时,路径会自动闭合,而 stroke 不会)。
路径-绘制圆弧(Arc)、圆 ( Circle)
绘制圆弧或者圆,使用arc()方法。
- **arc(x, y, radius, startAngle, endAngle, anticlockwise),**该方法有六个参数:
- x、y:为绘制圆弧所在圆上的圆心坐标。
- radius:为圆弧半径。
- startAngle、endAngle:该参数用弧度定义了开始以及结束的弧度。这些都是以 x 轴为基准。
- anticlockwise:为一个布尔值。为 true ,是逆时针方向,为false,是顺时针方向,默认为false。
计算弧度
- arc() 函数中表示角的单位是弧度,不是角度。
- 角度与弧度的 JS 表达式:弧度=( Math.PI / 180 ) * 角度 ,即 1角度= Math.PI / 180 个弧度
- 比如:旋转90°:Math.PI / 2; 旋转180°:Math.PI ; 旋转360°:Math.PI * 2; 旋转-90°:-Math.PI / 2;
绘制一个圆弧的步骤
- 比如:旋转90°:Math.PI / 2; 旋转180°:Math.PI ; 旋转360°:Math.PI * 2; 旋转-90°:-Math.PI / 2;
- 第一步:调用 beginPath() 来生成路径。
- 第二步:调用arc()函数来绘制圆弧。
- 第三步:闭合路径 closePath(),不是必需的。
- 第四步:调用stroke()函数来描边,或者调用fill()函数来填充(使用填充 fill 时,路径会自动闭合)。
路径-矩形(Rectangle)
绘制矩形的另一个方法:
- 调用rect() 函数绘制,即将一个矩形路径增加到当前路径上
- rect(x, y, width, height)
- 绘制一个左上角坐标为(x,y),宽高为 width 以及 height 的矩形。
注意:
- 绘制一个左上角坐标为(x,y),宽高为 width 以及 height 的矩形。
- 当该方法执行的时候,moveTo(x, y) 方法自动设置坐标参数(0,0)。也就是说,当前笔触自动重置回默认坐标。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body{
margin: 0;
padding: 0;
background-image: url(../images/grid.png);
}
canvas{
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<canvas id="tutorial" width="300" height="300px">
你的浏览器不兼容Canvas,请升级您的浏览器!
</canvas>
<script>
window.onload = function() {
let canvasEl = document.getElementById('tutorial')
if(!canvasEl.getContext){
return
}
let ctx = canvasEl.getContext('2d') // 2d | webgl
// 1.创建一个路径
ctx.beginPath()
// 2.绘图指令
// ctx.moveTo(0, 0)
ctx.rect(100, 100, 100, 50)
// 3.闭合路径
ctx.closePath()
// 4.填充和描边
ctx.stroke()
}
</script>
</body>
</html>
色彩 Colors
如果我们想要给图形上色,有两个重要的属性可以做到:
- fillStyle = color: 设置图形的填充颜色,需在 fill() 函数前调用。
- strokeStyle = color: 设置图形轮廓的颜色,需在 stroke() 函数前调用。
color颜色 - color 可以是表示 CSS 颜色值的字符串,支持:关键字、十六进制、rgb、rgba格式。
- 默认情况下,线条和填充颜色都是黑色(CSS 颜色值 #000000)。
注意 - 一旦设置了 strokeStyle 或者 fillStyle 的值,那么这个新值就会成为新绘制的图形的默认值。
- 如果你要给图形上不同的颜色,你需要重新设置 fillStyle 或 strokeStyle 的值。
额外补充 - fill() 函数是图形填充,fillStyle属性是设置填充色
- stroke() 函数是图形描边,strokeStyle属性是设置描边色
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body{
margin: 0;
padding: 0;
background-image: url(../images/grid.png);
}
canvas{
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<canvas id="tutorial" width="300" height="300px">
你的浏览器不兼容Canvas,请升级您的浏览器!
</canvas>
<script>
window.onload = function() {
let canvasEl = document.getElementById('tutorial')
if(!canvasEl.getContext){
return
}
let ctx = canvasEl.getContext('2d') // 2d | webgl
// 2.修改画笔的颜色
ctx.fillStyle = 'red'
ctx.fillRect(0,0, 100, 50) // 单位也是不用写 px
ctx.fillStyle = '#cdcdcd'
ctx.fillRect(200, 0, 100, 50)
ctx.fillStyle = 'green'
ctx.beginPath()
ctx.rect(0, 100, 100, 50)
ctx.fill()
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body{
margin: 0;
padding: 0;
background-image: url(../images/grid.png);
}
canvas{
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<canvas id="tutorial" width="300" height="300px">
你的浏览器不兼容Canvas,请升级您的浏览器!
</canvas>
<script>
window.onload = function() {
let canvasEl = document.getElementById('tutorial')
if(!canvasEl.getContext){
return
}
let ctx = canvasEl.getContext('2d') // 2d | webgl
// 2.修改画笔的颜色
ctx.fillStyle = 'rgba(255, 0, 0, 0.3)'
ctx.fillRect(0,0, 100, 50) // 单位也是不用写 px
ctx.strokeStyle = 'blue'
ctx.strokeRect(200, 0, 100, 50)
ctx.strokeStyle = 'green' // 关键字, 十六进制, rbg , rgba
ctx.beginPath()
ctx.rect(0, 100, 100, 50)
ctx.stroke()
}
</script>
</body>
</html>
透明度 Transparent
除了可以绘制实色图形,我们还可以用 canvas 来绘制半透明的图形。
- 方式一:strokeStyle 和 fillStyle属性结合RGBA:
- 方式二:globalAlpha 属性
- globalAlpha = 0 ~ 1
- 这个属性影响到 canvas 里所有图形的透明度
- 有效的值范围是 0.0(完全透明)到 1.0(完全不透明),默认是 1.0。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body{
margin: 0;
padding: 0;
background-image: url(../images/grid.png);
}
canvas{
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<canvas id="tutorial" width="300" height="300px">
你的浏览器不兼容Canvas,请升级您的浏览器!
</canvas>
<script>
window.onload = function() {
let canvasEl = document.getElementById('tutorial')
if(!canvasEl.getContext){
return
}
let ctx = canvasEl.getContext('2d') // 2d | webgl
// 针对于Canvas中所有的图形生效
ctx.globalAlpha = 0.3
// 2.修改画笔的颜色
// ctx.fillStyle = 'rgba(255, 0, 0, 0.3)'
ctx.fillRect(0,0, 100, 50) // 单位也是不用写 px
ctx.fillStyle = 'blue'
ctx.fillRect(200, 0, 100, 50)
ctx.fillStyle = 'green' // 关键字, 十六进制, rbg , rgba
ctx.beginPath()
ctx.rect(0, 100, 100, 50)
ctx.fill()
}
</script>
</body>
</html>
线型 Line styles
调用lineTo()函数绘制的线条,是可以通过一系列属性来设置线的样式。
- lineWidth = value: 设置线条宽度。
- lineCap = type: 设置线条末端样式。
- lineJoin = type: 设定线条与线条间接合处的样式。
- …
lineWidth - 设置线条宽度的属性值必须为正数。默认值是 1.0px,不需单位。( 零、负数、Infinity和NaN值将被忽略)
- 线宽是指给定路径的中心到两边的粗细。换句话说就是在路径的两边各绘制线宽的一半。
- 如果你想要绘制一条从 (3,1) 到 (3,5),宽度是 1.0 的线条,你会得到像第二幅图一样的结果。
- 路径的两边个各延伸半个像素填充并渲染出1像素的线条(深蓝色部分)
- 两边剩下的半个像素又会以实际画笔颜色一半色调来填充(浅蓝部分)
- 实际画出线条的区域为(浅蓝和深蓝的部分),填充色大于1像素了,这就是为何宽度为 1.0 的线经常并不准确的原因。
要解决这个问题,必须对路径精确的控制。如,1px的线条会在路径两边各延伸半像素,那么像第三幅图那样绘制从 (3.5 ,1) 到 (3.5,
5) 的线条,其边缘正好落在像素边界,填充出来就是准确的宽为 1.0 的线条。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body{
margin: 0;
padding: 0;
background-image: url(../images/grid.png);
}
canvas{
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<canvas id="tutorial" width="300" height="300px">
你的浏览器不兼容Canvas,请升级您的浏览器!
</canvas>
<script>
window.onload = function() {
let canvasEl = document.getElementById('tutorial')
if(!canvasEl.getContext){
return
}
let ctx = canvasEl.getContext('2d') // 2d | webgl
ctx.lineWidth = 2
ctx.beginPath()
ctx.moveTo(20, 20)
ctx.lineTo(20, 100)
ctx.stroke()
}
</script>
</body>
</html>