线型 Line styles
lineCap: 属性的值决定了线段端点显示的样子。它可以为下面的三种的其中之一:
- butt 截断,默认是 butt。
- round 圆形
- square 正方形
lineJoin: 属性的值决定了图形中线段连接处所显示的样子。它可以是这三种之一: - round 圆形
- bevel 斜角
- miter 斜槽规,默认是 miter。
<!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 = 10
ctx.lineCap = 'butt'
ctx.beginPath()
ctx.moveTo(20, 20)
ctx.lineTo(20, 100)
ctx.stroke()
}
</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
ctx.lineWidth = 10
ctx.lineCap = 'butt' // butt round square
ctx.lineJoin = 'bevel' // miter round bevel
ctx.beginPath()
ctx.moveTo(0, 0)
ctx.lineTo(100, 100)
ctx.lineTo(200, 0)
ctx.stroke()
}
</script>
</body>
</html>
绘制文本
canvas 提供了两种方法来渲染文本:
- fillText(text, x, y [, maxWidth])
- 在 (x,y) 位置,填充指定的文本
- 绘制的最大宽度(可选)。
- strokeText(text, x, y [, maxWidth])
- 在 (x,y) 位置,绘制文本边框
- 绘制的最大宽度(可选)。
文本的样式(需在绘制文本前调用)
- 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。
<!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.font = '60px sen-serif'
ctx.textAlign = 'center'
ctx.textBaseline = 'middle'
ctx.strokeStyle ="red"
ctx.fillStyle ="red"
// 将字体绘制在 100, 100 这个坐标点
ctx.fillText('Ay', 100, 100)
// ctx.strokeText('Ay', 100, 100)
}
</script>
</body>
</html>
绘制图片
绘制图片,可以使用 drawImage 方法将它渲染到 canvas 里。drawImage 方法有三种形态:
- drawImage(image, x, y)
- 其中 image 是 image 或者 canvas 对象,x 和 y 是其在目标 canvas 里的起始坐标。
- drawImage(image, x, y, width, height)
- 这个方法多了 2 个参数:width 和 height,这两个参数用来控制 当向 canvas 画入时应该缩放的大小
- drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
- 第一个参数和其它的是相同的,都是一个图像或者另一个 canvas 的引用。前 4 个是定义图像源的切片位置和大小,后 4 个则是定义切片的目标显示位置和大小。
图片的来源,canvas 的 API 可以使用下面这些类型中的一种作为图片的源:
- HTMLImageElement:这些图片是由Image()函数构造出来的,或者任何的< img >元素。
- HTMLVideoElement:用一个 HTML 的 < video >元素作为你的图片源,可以从视频中抓取当前帧作为一个图像。
- HTMLCanvasElement:可以使用另一个 < canvas > 元素作为你的图片源。
<!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="300">
你的浏览器不兼容Canvas,请升级您的浏览器!
</canvas>
<script>
window.onload = function() {
let canvasEl = document.getElementById('tutorial')
if(!canvasEl.getContext){
return
}
let ctx = canvasEl.getContext('2d') // 2d | webgl
// 1.准备一张图片
var image = new Image()
image.src = '../images/backdrop.png'
image.onload = function() {
// 2.开始用Canvas来绘制图片
ctx.drawImage(image, 0, 0, 180, 130)
// 3.绘制折线
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>
Canvas绘画状态-保存和恢复
Canvas绘画状态
- 是当前绘画时所产生的样式和变形的一个快照。
- Canvas在绘画时,会产生相应的绘画状态,其实我们是可以将某些绘画的状态存储在栈中来为以后复用。
- Canvas 绘画状态的可以调用 save 和 restore 方法是用来保存和恢复,这两个方法都没有参数,并且它们是成对存在的。
保存和恢复(Canvas)绘画状态 - save():保存画布 (canvas) 的所有绘画状态
- restore():恢复画布 (canvas) 的所有绘画状态
Canvas绘画状态包括: - 当前应用的变形(即移动,旋转和缩放)
- 以及这些属性:strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit,shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, font, textAlign, textBaseline …
- 当前的裁切路径(clipping path)
<!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.fillStyle ='red'
ctx.fillRect(10, 10, 30, 15)
ctx.save()
ctx.fillStyle = 'green'
ctx.fillRect(50, 10, 30, 15)
ctx.save()
ctx.fillStyle = 'blue'
ctx.fillRect(90, 10, 30, 15)
ctx.save()
ctx.restore() // blue
// ctx.fillStyle = 'blue'
ctx.fillRect(90, 40, 30, 80)
ctx.restore() // green
// ctx.fillStyle = 'green'
ctx.fillRect(50, 40, 30, 80)
ctx.restore() // red
// ctx.fillStyle = 'red'
ctx.fillRect(10, 40, 30, 80)
}
</script>
</body>
</html>
变形 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画布以外了。
- 形变需要在绘制图形前调用。
移动-translate
translate方法,它用来移动 canvas 和它的原点到一个不同的位置。
- translate(x, y)
- x 是左右偏移量,y 是上下偏移量(无需单位)。
移动 canvas 原点的好处
- x 是左右偏移量,y 是上下偏移量(无需单位)。
- 如不使用 translate方法,那么所有矩形默认都将被绘制在相同的(0,0)坐标原点。
- translate方法可让我们任意放置图形,而不需要手工一个个调整坐标值。
移动矩形案例 - 第一步:先保存一下canvas当前的状态
- 第二步:在绘制图形前translate移动画布
- 第三步:开始绘制图形,并填充颜色
<!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.translate(100, 100)
// ctx.fillRect(0,0, 100, 50) // 单位也是不用写 px
// ctx.translate(100, 100)
// ctx.strokeRect(0, 0, 100, 50)
// 1.形变(保存形变之前的状态)
ctx.save()
ctx.translate(100, 100)
ctx.fillRect(0,0, 100, 50) // 单位也是不用写 px
ctx.restore() // 恢复了形变之前的状态( 0,0)
ctx.save() // (保存形变之前的状态)
ctx.translate(100, 100)
ctx.fillStyle = 'red'
ctx.fillRect(0, 0, 50, 30)
ctx.restore()
}
}
</script>
</body>
</html>
旋转-rotate
rotate方法,它用于以原点为中心旋转 canvas,即沿着 z轴 旋转。
- rotate(angle)
- 只接受一个参数:旋转的角度 (angle),它是顺时针方向,以弧度为单位的值。
- 角度与弧度的 JS 表达式:弧度=( Math.PI / 180 ) * 角度 ,即 1角度 = Math.PI/180 个弧度。
- 比如:旋转90°:Math.PI / 2; 旋转180°:Math.PI ; 旋转360°:Math.PI * 2; 旋转-90°:-Math.PI / 2;
- 旋转的中心点始终是 canvas 的原坐标点,如果要改变它,我们需要用到 translate方法。
旋转案例
- 第一步:先保存一下Canvas当前的状态,并确定旋转原点
- 第二步:在绘制图形前旋转画布(坐标系会跟着旋转了)
- 第三步:开始绘制图形,并填充颜色
<!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.save()
// 1.形变
ctx.translate(100, 100)
// 360 -> Math.PI * 2
// 180 -> Math.PI
// 1 -> Math.PI / 180
// 45 -> Math.PI / 180 * 45
ctx.rotate(Math.PI / 180 * 45)
ctx.fillRect(0, 0, 50, 50)
// ctx.translate(100, 0)
// ctx.fillRect(0, 0, 50, 50)
// 绘图结束(恢复形变之前的状态)
ctx.restore()
ctx.save()
ctx.translate(100, 0)
ctx.fillRect(0, 0, 50, 50)
ctx.restore()
// ....下面在继续写代码的话,坐标轴就是参照的是原点了
}
</script>
</body>
</html>
缩放-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 倍。
缩放案例实战 - 第一步:先保存一下Canvas当前的状态,并确定缩放原点
- 第二步:在绘制图形前缩放画布
- 第三步:开始绘制图形,并填充颜色
<!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.save();
// 1.形变
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>