(二) JavaScript Canvas 画矩形
JavaScript 是前端核心, 掌握这门语言是步入前端高手行列必经之路,噢,别忘了还有TypeScript, 学习它还需要OOP知识, 底层的浏览器原理、HTTP协议也必不可少, 此系列文章记录使用JavaScript和Canvas进行游戏开发, 有游戏才有趣!!!
(二) JavaScript Canvas 画矩形
1. 准备HTML页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <!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> canvas { position: absolute; background: white; width: 100%; height: 100%; top: 0; left: 0; } canvas { background: linear-gradient(120deg, #4a3934, #e6d5b9); } </style> </head> <body> <canvas id="canvas"></canvas> <script> </script> </body>
|
2. 画矩形
- 掌握几个函数
- translate() 平移坐标原点到指定坐标位置
- moveTo(0, 0) 移动到坐标位置(0, 0)
- beginPath() 开始路径
- closePath() 关闭路径
- rotate() 旋转
- save()
- 在中心点画一个矩形
- 使用平移函数 translate() 和 绘制矩形函数rect()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <script> const canvas = document.getElementById('canvas') const ctx = canvas.getContext('2d') canvas.width = window.innerWidth canvas.height = window.innerHeight ctx.translate(canvas.width/2, canvas.height/2) ctx.moveTo(0, 0) ctx.strokeStyle = 'black' ctx.rect(0,0,200,200) ctx.stroke() </script>
|
效果如下图:
- 在上一个矩形之后再画一个矩形,改变一下颜色和旋转的角度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <script> const canvas = document.getElementById('canvas') const ctx = canvas.getContext('2d') canvas.width = window.innerWidth canvas.height = window.innerHeight ctx.translate(canvas.width/2, canvas.height/2) ctx.moveTo(0, 0) ctx.strokeStyle = 'black' ctx.rect(0,0,200,200) ctx.stroke() ctx.rotate(30 * Math.PI/180) ctx.strokeStyle = 'red' ctx.rect(0,0,200,200) ctx.stroke() </script>
|
看看效果, 你会发现,两个矩形边框的颜色是最后一次设定的红色, 怎么解决? 其实和画线那篇类似,使用beginPath()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <script> const canvas = document.getElementById('canvas') const ctx = canvas.getContext('2d') canvas.width = window.innerWidth canvas.height = window.innerHeight ctx.translate(canvas.width/2, canvas.height/2) ctx.moveTo(0, 0) ctx.strokeStyle = 'black' ctx.rect(0,0,200,200) ctx.stroke() ctx.beginPath() ctx.rotate(30 * Math.PI/180) ctx.strokeStyle = 'red' ctx.rect(0,0,200,200) ctx.stroke() ctx.closePath() </script>
|
如下图所示
- 再画第三个矩形,同时的旋转角度, 边框颜色设定为 blue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <script> const canvas = document.getElementById('canvas') const ctx = canvas.getContext('2d') canvas.width = window.innerWidth canvas.height = window.innerHeight ctx.translate(canvas.width/2, canvas.height/2) ctx.moveTo(0, 0) ctx.strokeStyle = 'black' ctx.rect(0,0,200,200) ctx.stroke() ctx.beginPath() ctx.rotate(30 * Math.PI/180) ctx.strokeStyle = 'red' ctx.rect(0,0,200,200) ctx.stroke() ctx.closePath() ctx.beginPath() ctx.rotate(30 * Math.PI/180) ctx.strokeStyle = 'blue' ctx.rect(0,0,200,200) ctx.stroke() ctx.closePath() </script>
|
可以看到,旋转的角度是相对于上一个矩形,如果不使用save() restore()方法,那么旋转时将相对于上次绘制的形状
- 在绘制中间的那个矩形时使用save() 和 restore()包裹起来,看看有什么不一样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| <script> const canvas = document.getElementById('canvas') const ctx = canvas.getContext('2d') canvas.width = window.innerWidth canvas.height = window.innerHeight ctx.translate(canvas.width/2, canvas.height/2) ctx.moveTo(0, 0) ctx.strokeStyle = 'black' ctx.rect(0,0,200,200) ctx.stroke() ctx.save() ctx.beginPath() ctx.rotate(30 * Math.PI/180) ctx.strokeStyle = 'red' ctx.rect(0,0,200,200) ctx.stroke() ctx.closePath() ctx.restore() ctx.beginPath() ctx.rotate(30 * Math.PI/180) ctx.strokeStyle = 'blue' ctx.rect(0,0,200,200) ctx.stroke() ctx.closePath() </script>
|
绘制结果如下,第二个矩形和第三个矩形重合了,可以这样理解,第三个矩形认为第二个矩形不存在一样,绘制时旋转角度就依赖于第一个矩形
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <script> const canvas = document.getElementById('canvas') const ctx = canvas.getContext('2d') canvas.width = window.innerWidth canvas.height = window.innerHeight drawRect() function drawRect() { ctx.translate(canvas.width/2, canvas.height/2) ctx.moveTo(0, 0) ctx.translate(canvas.width/2, canvas.height/2) ctx.moveTo(0, 0) for(let i=0;i<8;i++) {
ctx.strokeStyle = 'hsl(' + Math.random()*360 + ",100%,50%)" ctx.rect(0,0,200,200) ctx.rotate(30*Math.PI/180) ctx.stroke() } } </script>
|
效果如图,注意没有增加save()和restore()方法
save()和restore()经常在矩阵变换 translate()、缩放 scale()、旋转rotate()中使用, 因为一个Canvas只有一个2d上下文,当执行转换操作时,整个上下文的坐标系都将改变。改变后,如果我们需要将坐标系恢复到原来正常的状态,这时就需要用到save() 和 restore(), 下图中第一次绘制矩形的坐标系和旋转后绘制矩形的坐标系
以上均为绘图基础,为后续绘制复杂的图形和动画打好基础