文章目录
- 一、Canvas的颜色和样式设置
- 1.1 颜色(不设置默认黑色)
- 1.2 透明度 Transparent
- 1.3 线型 Line styles
- 二、Canvas绘制文本
- 2.1 文本的样式(需在绘制文本前调用)
- 2.2 fillText(text, x, y [, maxWidth])
- 2.3 strokeText(text, x, y [, maxWidth])
- 三、Canvas绘制图片
- 3.1 绘制图片,可以使用 drawImage 方法将它渲染到 canvas 里。drawImage 方法有三种形态:
- 3.2 图片的来源,canvas 的 API 可以使用下面这些类型中的一种作为图片的源:
- 3.3 Canvas绘画状态-保存和恢复
- 四、变形 Transform
- 4.1 移动-translate
- 4.2 旋转-rotate
- 4.3 缩放-scale
一、Canvas的颜色和样式设置
1.1 颜色(不设置默认黑色)
◼ fillStyle = color: 设置图形的填充颜色,需在 fill() 函数前调用。
◼ strokeStyle = color: 设置图形轮廓的颜色,需在 stroke() 函数前调用。
◼ 一旦设置了 strokeStyle 或者 fillStyle 的值,那么这个新值就会成为新绘制的图形的默认值。
◼ 如果你要给图形上不同的颜色,需要重新设置 fillStyle 或 strokeStyle 的值。
<!DOCTYPE html>
<html lang="zh-CH">
<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>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
margin: auto;
}
canvas {
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<!-- 如果不给宽高 默认宽300px 高150px -->
<canvas id="box" width="300" height="300">
您的浏览器不兼容Canvas,请升级浏览器
</canvas>
<script>
window.onload = function() {
const canvasEl = document.getElementById('box')
if (!canvasEl.getContext) return
let ctx = canvasEl.getContext('2d')
ctx.fillStyle = 'green'; // 不设置颜色时 默认为填充黑色(如果需要设置颜色,必须写在绘制元素的前面)
ctx.fillRect(0, 0, 100, 50)
ctx.fillStyle = 'red';
ctx.fillRect(200, 0, 100, 50)
ctx.fillStyle = '#aaaaaa';
ctx.beginPath()
ctx.rect(0, 100, 100, 50)
ctx.fill()
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh-CH">
<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>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
margin: auto;
}
canvas {
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<!-- 如果不给宽高 默认宽300px 高150px -->
<canvas id="box" width="300" height="300">
您的浏览器不兼容Canvas,请升级浏览器
</canvas>
<script>
window.onload = function() {
const canvasEl = document.getElementById('box')
if (!canvasEl.getContext) return
let ctx = canvasEl.getContext('2d')
ctx.strokeStyle = 'green'; // 不设置颜色时 默认为填充黑色(如果需要设置颜色,必须写在绘制元素的前面)
ctx.strokeRect(0, 0, 100, 50)
ctx.strokeStyle = 'red';
ctx.strokeRect(200, 0, 100, 50)
ctx.strokeStyle = 'skyblue';
ctx.beginPath()
ctx.rect(0, 100, 100, 50)
ctx.stroke()
}
</script>
</body>
</html>
1.2 透明度 Transparent
◼ 除了可以绘制实色图形,我们还可以用 canvas 来绘制半透明的图形。
◼ 方式一:strokeStyle 和 fillStyle属性结合RGBA:
◼ 方式二:globalAlpha 属性(globalAlpha = 0 ~ 1,这个属性影响到 canvas 里所有图形的透明度 , 有效的值范围是 0.0(完全透明)到 1.0(完全不透明),默认是 1.0。)
<!DOCTYPE html>
<html lang="zh-CH">
<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>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
margin: auto;
}
canvas {
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<!-- 如果不给宽高 默认宽300px 高150px -->
<canvas id="box" width="300" height="300">
您的浏览器不兼容Canvas,请升级浏览器
</canvas>
<script>
window.onload = function() {
const canvasEl = document.getElementById('box')
if (!canvasEl.getContext) return
let ctx = canvasEl.getContext('2d')
ctx.fillStyle = 'rgba(0, 255, 0, 0.3)'; // 不设置颜色时 默认为填充黑色(如果需要设置颜色,必须写在绘制元素的前面)
ctx.fillRect(0, 0, 100, 50)
ctx.fillStyle = 'rgba(255, 0, 0, 0.3)';
ctx.fillRect(200, 0, 100, 50)
ctx.fillStyle = 'rgba(0, 0, 255, 0.3)';
ctx.beginPath()
ctx.rect(0, 100, 100, 50)
ctx.fill()
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh-CH">
<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>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
margin: auto;
}
canvas {
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<!-- 如果不给宽高 默认宽300px 高150px -->
<canvas id="box" width="300" height="300">
您的浏览器不兼容Canvas,请升级浏览器
</canvas>
<script>
window.onload = function() {
const canvasEl = document.getElementById('box')
if (!canvasEl.getContext) return
let ctx = canvasEl.getContext('2d')
// 全局透明度(针对canvas中所有的图形生效)
ctx.globalAlpha = 0.3
ctx.fillStyle = 'green';
ctx.fillRect(0, 0, 100, 50)
ctx.fillStyle = 'red';
ctx.fillRect(200, 0, 100, 50)
ctx.fillStyle = 'rgb(0, 0, 255)';
ctx.beginPath()
ctx.rect(0, 100, 100, 50)
ctx.fill()
}
</script>
</body>
</html>
1.3 线型 Line styles
调用lineTo()函数绘制的线条,是可以通过一系列属性来设置线的样式。
◼ lineWidth = value: 设置线条宽度。(属性值必须为正数。默认值是 1.0px,不需单位。( 零、负数、Infinity和NaN值将被忽略))
◼ lineCap = type: 设置线条末端样式。(type: butt 截断(默认),round 圆形, square 正方形)
◼ lineJoin = type: 设定线条与线条间接合处的样式。(type: round 圆形,bevel 斜角, miter 斜槽规(默认))
◼ …
1.3.1设置lineWidth
<!DOCTYPE html>
<html lang="zh-CH">
<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>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
margin: auto;
}
canvas {
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<!-- 如果不给宽高 默认宽300px 高150px -->
<canvas id="box" width="300" height="300">
您的浏览器不兼容Canvas,请升级浏览器
</canvas>
<script>
window.onload = function() {
const canvasEl = document.getElementById('box')
if (!canvasEl.getContext) return
let ctx = canvasEl.getContext('2d')
ctx.lineWidth = 10
ctx.beginPath()
ctx.moveTo(20, 20)
ctx.lineTo(20, 100)
ctx.closePath()
ctx.stroke()
}
</script>
</body>
</html>
结合代码及上图:我们可以知道线宽是以原点向左右各取设置的宽度的一半的,这样当设置线宽为1的时候,你放大图形会发现,他会产生阴影,所以当设置为1时 你最好向下面代码那样设置
<!DOCTYPE html>
<html lang="zh-CH">
<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>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
margin: auto;
}
canvas {
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<!-- 如果不给宽高 默认宽300px 高150px -->
<canvas id="box" width="300" height="300">
您的浏览器不兼容Canvas,请升级浏览器
</canvas>
<script>
window.onload = function() {
const canvasEl = document.getElementById('box')
if (!canvasEl.getContext) return
let ctx = canvasEl.getContext('2d')
ctx.lineWidth = 1
ctx.beginPath()
ctx.moveTo(20.5, 20)
ctx.lineTo(20.5, 100)
ctx.closePath()
ctx.stroke()
}
</script>
</body>
</html>
1.3.2设置lineCap和lineJoin
<!DOCTYPE html>
<html lang="zh-CH">
<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>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
margin: auto;
}
canvas {
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<!-- 如果不给宽高 默认宽300px 高150px -->
<canvas id="box" width="300" height="300">
您的浏览器不兼容Canvas,请升级浏览器
</canvas>
<script>
window.onload = function() {
const canvasEl = document.getElementById('box')
if (!canvasEl.getContext) return
let ctx = canvasEl.getContext('2d')
ctx.lineWidth = 10
ctx.lineCap = 'round' // butt 截断(默认)/round 圆形/square 正方形
ctx.lineJoin = 'round' // round 圆形/bevel 斜角/miter 斜槽规(默认)
ctx.beginPath()
ctx.moveTo(0, 0)
ctx.lineTo(100, 100)
ctx.lineTo(200, 0)
ctx.stroke()
}
</script>
</body>
</html>
二、Canvas绘制文本
2.1 文本的样式(需在绘制文本前调用)
◼ font = value: 当前绘制文本的样式。这个字符串使用和 CSS font 属性相同的语法。默认的字体是:10px sans-serif。
◼ textAlign = value:文本对齐选项。可选的值包括:start, end, left, right or center. 默认值是 start
◼ textBaseline = value:基线对齐选项。可选的值包括:top, hanging, middle, alphabetic, ideographic, bottom。 默认值是 alphabetic。
2.2 fillText(text, x, y [, maxWidth])
◼ x, y:在 (x,y) 位置,填充指定的文本
◼ maxWidth:绘制的最大宽度(可选)。
<!DOCTYPE html>
<html lang="zh-CH">
<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>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
margin: auto;
}
canvas {
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<!-- 如果不给宽高 默认宽300px 高150px -->
<canvas id="box" width="300" height="300">
您的浏览器不兼容Canvas,请升级浏览器
</canvas>
<script>
window.onload = function() {
const canvasEl = document.getElementById('box')
if (!canvasEl.getContext) return
let ctx = canvasEl.getContext('2d')
ctx.font = '30px sen-serif'
// 可打开 查看效果
// ctx.textAlign = 'center'
// ctx.textBaseline = 'middle'
ctx.fillStyle = 'red'
ctx.fillText('xt', 100, 100)
}
</script>
</body>
</html>
2.3 strokeText(text, x, y [, maxWidth])
◼ x, y:在 (x,y) 位置,填充指定的文本
◼ maxWidth:绘制的最大宽度(可选)。
// 将fillText换为strokeText fillStyle 换strokeStyle
// ctx.fillStyle = 'red'
// ctx.fillText('xt', 100, 100)
ctx.strokeStyle = 'red'
ctx.strokeText('xt', 100, 100)
三、Canvas绘制图片
3.1 绘制图片,可以使用 drawImage 方法将它渲染到 canvas 里。drawImage 方法有三种形态:
3.1.1 drawImage(image, x, y) :其中 image 是 image 或者 canvas 对象,x 和 y 是其在目标 canvas 里的起始坐标
3.1.2 drawImage(image, x, y, width, height):这个方法多了 2 个参数:width 和 height,这两个参数用来控制 当向 canvas 画入时应该缩放的大小
3.1.3 drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight):第一个参数和其它的是相同的,都是一个图像或者另一个 canvas 的引用。前 4 个是定义图像源的切片位置和大小,后 4 个则是定义切片的目标显示位置和大小。
3.2 图片的来源,canvas 的 API 可以使用下面这些类型中的一种作为图片的源:
3.2.1 HTMLImageElement:这些图片是由Image()函数构造出来的,或者任何的元素。
3.2.2 HTMLVideoElement:用一个 HTML 的 元素作为你的图片源,可以从视频中抓取当前帧作为一个图像。
3.2.3 HTMLCanvasElement:可以使用另一个 元素作为你的图片源。
3.2.4 …
<!DOCTYPE html>
<html lang="zh-CH">
<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>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
margin: auto;
}
canvas {
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<!-- 如果不给宽高 默认宽300px 高150px -->
<canvas id="box" width="300" height="300">
您的浏览器不兼容Canvas,请升级浏览器
</canvas>
<script>
window.onload = function() {
const canvasEl = document.getElementById('box')
if (!canvasEl.getContext) return
let ctx = canvasEl.getContext('2d')
// 准备图片
let image = new Image()
image.src = '你自己的图片路劲'
image.onload = function() {
// 利用canvas绘制图片
ctx.drawImage(image, 0, 0, 200, 200)
// 在图片上绘制折线(如果出现层叠,后绘制的图形,会叠在前面的图形)
ctx.beginPath()
ctx.moveTo(40, 100)
ctx.lineTo(50, 70)
ctx.lineTo(60, 90)
ctx.lineTo(100, 30)
ctx.lineTo(170, 90)
ctx.stroke()
}
}
</script>
</body>
</html>
3.3 Canvas绘画状态-保存和恢复
3.3.1Canvas绘画状态
◼ 是当前绘画时所产生的样式和变形的一个快照。
◼ Canvas在绘画时,会产生相应的绘画状态,其实我们是可以将某些绘画的状态存储在栈中来为以后复用。
◼ Canvas 绘画状态的可以调用 save 和 restore 方法是用来保存和恢复,这两个方法都没有参数,并且它们是成对存在的。
3.3.2保存和恢复(Canvas)绘画状态
◼ save():保存画布 (canvas) 的所有绘画状态
◼ restore():恢复画布 (canvas) 的所有绘画状态
3.3.3保存和恢复(Canvas)绘画状态
◼ 当前应用的变形(即移动,旋转和缩放)
◼ 以及这些属性:strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit,
shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, font, textAlign, textBaseline …
◼ 当前的裁切路径(clipping path)
四、变形 Transform
◼ Canvas和CSS3一样也是支持变形,形变是一种更强大的方法,可以将坐标原点移动到另一点、形变可以对网格进行旋转和缩放
◼ Canvas的形变有4种方法实现:
- translate(x, y):用来移动 canvas 和它的原点到一个不同的位置(x 是左右偏移量,y 是上下偏移量(无需要单位),)
- rotate(angle):用于以原点为中心旋转 canvas,即沿着z轴旋转。(angle是旋转的弧度,是顺时针方向,以弧度为单位。)
- scale(x, y):用来增减图形在 canvas 中像素数目,对图形进行缩小或放大。(x 为水平缩放因子,y 为垂直缩放因子。如果比 1 小,会缩小图形,如果比 1 大会放大图形。默认值为 1,也支持负数。)
- transform(a, b, c, d, e, f): 允许对变形矩阵直接修改。这个方法是将当前的变形矩阵乘上一个基于自身参数的矩阵。
◼ 注意事项: - 在做变形之前先调用 save 方法保存状态是一个良好的习惯
- 大多数情况下,调用 restore 方法比手动恢复原先的状态要简单得多。
- 如果在一个循环中做位移但没有保存和恢复canvas状态,很可能到最后会发现有些东西不见了,因为它很可能已超出canvas画布
- 形变需要在绘制图形前调用。
4.1 移动-translate
可以看看如果我们不save初始状态 会发生什么?
<!DOCTYPE html>
<html lang="zh-CH">
<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>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
margin: auto;
}
canvas {
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<!-- 如果不给宽高 默认宽300px 高150px -->
<canvas id="box" width="300" height="300">
您的浏览器不兼容Canvas,请升级浏览器
</canvas>
<script>
window.onload = function() {
const canvasEl = document.getElementById('box')
if (!canvasEl.getContext) return
let ctx = canvasEl.getContext('2d')
// 形变
ctx.translate(100, 100)
ctx.fillRect(0, 0, 100, 50)
ctx.translate(100, 100)
ctx.strokeRect(0, 0, 100, 50)
}
</script>
</body>
</html>
如果我们没在一开始(坐标原点为0,0时)保存状态,经过多次变化后,可能我们就很难找到坐标原点了
可以看看如果我们save初始状态 又会发生什么?
<!DOCTYPE html>
<html lang="zh-CH">
<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>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
margin: auto;
background-image: url(../images/grid.png);
}
canvas {
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<!-- 如果不给宽高 默认宽300px 高150px -->
<canvas id="box" width="300" height="300">
您的浏览器不兼容Canvas,请升级浏览器
</canvas>
<script>
window.onload = function() {
const canvasEl = document.getElementById('box')
if (!canvasEl.getContext) return
let ctx = canvasEl.getContext('2d')
// 先保存最开始的状态
ctx.save()
// 形变
ctx.translate(100, 100)
ctx.fillRect(0, 0, 100, 50)
// 恢复到最开始的状态(原点没有改变时的状态)
ctx.restore()
ctx.save() // 形变前保存状态
ctx.translate(100, 0)
ctx.strokeRect(0, 0, 100, 50)
ctx.restore()// 完成后恢复状态
}
</script>
</body>
</html>
可以看到我们保存了原点后,每次重新执行变化时我们就可以使用restore()方法,确保他的原点在0,0位置不变
4.2 旋转-rotate
◼ rotate方法,它用于以原点为中心旋转 canvas,即沿着 z轴 旋转。
rotate(angle):
- 只接受一个参数:旋转的角度 (angle),它是顺时针方向,以弧度为单位的值。
- 角度与弧度的 JS 表达式:弧度=( Math.PI / 180 ) * 角度 ,即 1角度 = Math.PI/180 个弧度。
- 旋转的中心点始终是 canvas 的原坐标点,如果要改变它,我们需要用到 translate方法。
<!DOCTYPE html>
<html lang="zh-CH">
<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>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
margin: auto;
}
canvas {
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<!-- 如果不给宽高 默认宽300px 高150px -->
<canvas id="box" width="300" height="300">
您的浏览器不兼容Canvas,请升级浏览器
</canvas>
<script>
window.onload = function() {
const canvasEl = document.getElementById('box')
if (!canvasEl.getContext) return
let ctx = canvasEl.getContext('2d')
ctx.save() // 形变前保存状态
// 形变
ctx.translate(100, 100)
ctx.rotate(Math.PI / 4)
ctx.fillRect(0, 0, 50, 50)
// 如果在这里形变(那么坐标原点就是100,100点)
ctx.translate(100, 0)
ctx.fillRect(0, 0, 50, 50)
// 完成后恢复状态
ctx.restore()
// 如果在这里形变(那么坐标原点就是0,0点)(这就是使用save和restore的用途)
// ctx.save() // 形变前保存状态
// ctx.translate(100, 0)
// ctx.fillRect(0, 0, 50, 50)
// ctx.restore()// 完成后恢复状态
}
</script>
</body>
</html>
4.3 缩放-scale
scale方法可以缩放画布。可用它来增减图形在 canvas 中的像素数目,对图形进行缩小或者放大。
scale(x, y): x 为水平缩放因子,y 为垂直缩放因子,也支持负数。如果比 1 小,会缩小图形,如果比 1 大会放大图形。默认值为 1。
◼ 注意事项
- 画布初始情况下,是以左上角坐标为原点。如果参数为负实数,相当于以 x 或 y 轴作为对称轴镜像反转。(如,使用translate(0, canvas.height); scale(1,-1); 以 y 轴作为对称轴镜像反转。)
- 默认情况下,canvas 的 1 个单位为 1 个像素。如果我们设置缩放因子是 0.5,1 个单位就变成对应 0.5 个像素,这样绘制出
来的形状就会是原先的一半。同理,设置为 2.0 时,1 个单位就对应变成了 2 像素,绘制的结果就是图形放大了 2 倍。
<!DOCTYPE html>
<html lang="zh-CH">
<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>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
margin: auto;
}
canvas {
background-color: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<!-- 如果不给宽高 默认宽300px 高150px -->
<canvas id="box" width="300" height="300">
您的浏览器不兼容Canvas,请升级浏览器
</canvas>
<script>
window.onload = function() {
const canvasEl = document.getElementById('box')
if (!canvasEl.getContext) return
let ctx = canvasEl.getContext('2d')
ctx.save() // 形变前保存状态
// 形变
ctx.translate(100, 100)
ctx.scale(2, 2) // 对坐标轴放大2倍
ctx.translate(10, 0) // 缩放后,10px 会变为 20px
ctx.fillRect(0, 0, 50, 50)
ctx.restore()// 完成后恢复状态
}
</script>
</body>
</html>