一、邂逅Canvas
1. 什么是Canvas
- HTML5新增元素。
- Canvas提供了非常多的JavaScript绘图API,与canvas元素可以绘制各种2D图形。
2. Canvas的应用场景
- 可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。
3. Canvas优点
- Canvas提供的功能更原始,适合像素处理,动态渲染和数据量大的绘制,如:图片编辑、热力图、炫光尾迹特效等。
- Canvas非常适合图像密集型的游戏开发,适合频繁重绘许多的对象。
- Canvas能够以.png或.jpg格式保存结果图像,适合对图片进行像素级的处理。
4. Canvas缺点
- 在移动端可能会因为Canvas数量多,而导致内存占用超出了手机的承受能力,导致浏览器崩溃。
- Canvas绘图只能通过JavaScript脚本操作。
- Canvas是由一个个像素点构成的图形,放大会使图形变得颗粒状和像素化,导致模糊。
5. Canvas的使用
- canvas标签只有两个属性:width和height。当没有设置宽度和高度时,canvas会初始化宽为300px和高为150px。
- 测试canvas.getContext()方法的存在,可以检测浏览器是否支持Canvas。
二、Canvas绘图
1. Canvas网格和坐标空间
- canvas元素默认被网格所覆盖。
- 通常来说网格的一个单元相当于canvas元素中的一像素。
- 该网格的原点位于坐标(0,0)的左上角。所有元素都相对于该原点位置。
- 网格也可以理解为坐标空间,坐标原点位于canvas元素的左上角,被称为初始坐标系。
2. 绘制形状
- 绘制矩形
- rect(x, y, width, height):单纯的画出一个矩形框,调用stroke() 或 fill()后才会真正作用于画布。
- fillRect(x, y, width, height):绘制一个填充的矩形。
- strokeRect(x, y, width, height):绘制一个矩形的边框。
- clearRect(x, y, width, height):清除指定矩形区域,让清除部分完全透明。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> body { margin: 0; padding: 0; } 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") // 1. 绘制了一个填充的矩形 ctx.fillRect(0, 100, 100, 50) // 2. 绘制一个边框的矩形 ctx.strokeRect(0, 200, 100, 50) // 3. 清除指定区域的矩形 ctx.clearRect(0, 0, 100, 50) } </script> </body> </html> - 绘制路径
- 使用路径绘制图形的步骤
- 首先需要创建路径起始点(beginPath);
- 然后使用画图命令去画路径(arc、lineTo);
- 之后把路径闭合(closePath,不是必须);
- 一旦路径生成,就能通过描边(stroke)或填充路径区域(fill)来渲染图形。
- 绘制直线
- moveTo:移动画笔
- lineTo:绘制直线
window.onload = function() { let canvasEl = document.getElementById("tutorial") if (!canvasEl.getContext) { return } let ctx = canvasEl.getContext("2d") ctx.lineWidth = 10 // 1. 创建一个新的路径 ctx.beginPath() // 2. 使用的绘图的命名(ctx对象中的属性和API) ctx.moveTo(10, 10) ctx.lineTo(100, 10) // 3. 闭合路径 // ctx.closePath() // 不是必须的 // 4. 描边或填充 ctx.stroke() // 绘制线条只能用stroke填充,不能用fill } - 绘制三角形
window.onload = function() { let canvasEl = document.getElementById("tutorial") if (!canvasEl.getContext) { return } let ctx = canvasEl.getContext("2d") ctx.beginPath() ctx.moveTo(50, 0) ctx.lineTo(100, 50) ctx.lineTo(50, 100) ctx.closePath() ctx.stroke() ctx.beginPath() ctx.moveTo(150, 0) ctx.lineTo(200, 50) ctx.lineTo(150, 100) ctx.fill() // 它会自动闭合路径 } - 绘制圆
- arc(x, y, radius, startAngle, endAngle, anticlockwise)
- x、y:为绘制圆弧所在圆上的圆心坐标。
- radius:为圆弧半径。
- startAngle、endAngle:该参数用弧度定义了开始以及结束的弧度。这些都是以x轴为基准.
- anticlockwise:为一个布尔值。为 true ,是逆时针方向,为false,是顺时针方向,默认为false。
window.onload = function() { let canvasEl = document.getElementById("tutorial") if (!canvasEl.getContext) { return } let ctx = canvasEl.getContext("2d") ctx.beginPath() // x, y, R, startRad, endRad, 顺时针方向 ctx.arc(50, 50, 25, 0, Math.PI * 2, false) ctx.stroke() } - 绘制圆弧
window.onload = function() { let canvasEl = document.getElementById("tutorial") if (!canvasEl.getContext) { return } let ctx = canvasEl.getContext("2d") ctx.beginPath() ctx.arc(150, 150, 25, 0, Math.PI) ctx.stroke() } - 绘制矩形
- rect(x, y, width, height)
window.onload = function() { let canvasEl = document.getElementById("tutorial") if (!canvasEl.getContext) { return } let ctx = canvasEl.getContext("2d") // 1. 创建一个路径 ctx.beginPath() // 2. 绘图指令 ctx.moveTo(0, 0) ctx.rect(100, 100, 100, 50) // 3. 闭合路径 ctx.closePath() // 4. 填充或描边 ctx.fill() }
- 使用路径绘制图形的步骤
- 样式属性
- 色彩 Colors
- fillStyle = color:设置图形的填充颜色,需在fill()函数前调用。
- strokeStyle = color:设置图形轮廓颜色,需在stroke()。
一旦设置了fillStyle或者strokeStyle的值,那么这个新值就会成为新绘制的图形的默认值。
- 透明度 Transparency
- globalAlpha
- rgba:fillStyle和strokeStyle属性结合rgba
- 线型 Line styles
- lineWidth = value:设置线条宽度。
- lineCap = type:设置线条末端样式。
- butt —— 截断,默认是butt
- round —— 圆形
- square —— 正方形
- lineJoin = type:设定线条与线条间接合处的样式。
- round —— 圆形
- bevel —— 斜角
- miter —— 斜槽规,默认是miter
- setLineDash() —— 设置虚线样式
- lineDashoffset —— 虚线偏移
- 色彩 Colors
- 绘制文本
- fillText(text, x, y [, maxWdith])
- strokeText(text, x, y [, maxWdith])
- 有样式的文本(需在绘制文本前调用)
- font = value:当前绘制文本的样式。默认的字体是 10px sans-serif。
- textAlign = value:文本对齐选项,可选的值包括start,end,left,right和center。默认值是start。
- textBaseline = value:基线对齐选项。可选的值包括top,hanging,middle,alphabetic,ideographic,bottom。默认值是alphabetic
- 绘制图片
- drawImage(image, x, y, width, height)
三、Canvas状态的保存和恢复
- save():保存画布(canvas)的所有绘画状态
- restore():恢复画布(canvas)的所有绘画状态
绘画状态存储在栈中
四、Canvas变换坐标系统
- Canvas和CSS3一样支持形变,可以将坐标原点移动到另一点,形变可以对网络进行旋转和缩放。
1. translate
- translate(x, y)
2. rotate
- rotate(deg)
3. scale
- scale(x, y)
4. transform
- transform(a, b, c, d, e, f)
五、Canvas动画
1. 认识canvas动画
- canvas可能最大的限制就是图像一旦绘制了,就一直保持那样了。
- 如需要执行动画,不得不对画布上所有图形进行一帧一帧的重绘。
- 为了实现动画,Canvas有三种方法可以定期执行指定函数实现定时执行重绘的方法:setInterval、setTimeout和requestAnimationFrame。
2. 动画使用的基本步骤
- 用clearRect方法清空canvas;
- 保存canvas状态;
- 绘制动画图形;
- 恢复canvas状态。
3. 操控动画
- setInterval
- setTimeout
- requestAnimationFrame
- 告诉浏览器:你希望执行一个动画,并且要求浏览器在下次重绘之前调用该函数的回调函数来更新动画。
- 该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。
- 若想在浏览器下次重绘之前继续更新下一帧动画,那么在回调函数自身必须再次调用requestAnimationFrame()。
- 通常每秒钟回调函数执行60次左右,也有可能会被降低。