(三) 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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| <!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> * { margin: 0; padding: 0; box-sizing: border-box; }
body { overflow: hidden; background-color: black; }
#canvas1 { background-color: white; position: absolute; top: 0; left: 0; width: 100%; height: 100%; } </style> </head> <body> <canvas id="canvas"></canvas> <script>
const canvas = document.getElementById('canvas') const ctx = canvas1.getContext('2d') console.log(canvas1) console.log(ctx);
canvas.width = window.innerWidth canvas.height = window.innerHeight </script> </body> </html>
|
2. 绘制六角星形
- 多边形由线组成,先把第一根线画好,此处选择从中心点向上绘制
- 初始坐标为(0,0) 此时设置为画布Canvas的中心点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <script> const canvas = document.getElementById('canvas') const ctx = canvas.getContext('2d') canvas.width = window.innerWidth canvas.height = window.innerHeight
ctx.beginPath() ctx.translate(canvas.width/2, canvas.height/2) ctx.strokeStyle='red' ctx.lineWidth = 3 ctx.moveTo(0, 0) ctx.lineTo(0, -100) ctx.stroke()
</script>
|
效果如下图所示
- 下面再画第二根线,要注意的是不要closePath(),让第二根线从第一根线的结束点开始画,也就是从(0, -100)开始
- 绘制时需要旋转, 旋转会将整个坐标系旋转具体角度或弧度
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
| <script> const canvas = document.getElementById('canvas') const ctx = canvas.getContext('2d') canvas.width = window.innerWidth canvas.height = window.innerHeight
ctx.beginPath() ctx.translate(canvas.width/2, canvas.height/2) ctx.strokeStyle='red' ctx.lineWidth = 3 ctx.moveTo(0, 0) ctx.lineTo(0, -100) ctx.rotate(Math.PI/6) ctx.lineTo(0, -50) ctx.stroke() </script>
|
如下图所示,第二根线的开始点为(0, -100) 结束点为 (0, -50), 整个坐标系rotate (旋转) 了 Math.PI/6 个角度
rotate 前和rotate 后的坐标系如图所示,蓝色表示是rotate 前, 红色表示rotate后
- 接下来再用同样的方法,先rotate,然后再设定结束坐标
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
| <script> const canvas = document.getElementById('canvas') const ctx = canvas.getContext('2d') canvas.width = window.innerWidth canvas.height = window.innerHeight
ctx.beginPath() ctx.translate(canvas.width/2, canvas.height/2) ctx.strokeStyle='red' ctx.lineWidth = 3 ctx.moveTo(0, 0) ctx.lineTo(0, -100) ctx.rotate(Math.PI/6) ctx.lineTo(0, -50) ctx.rotate(Math.PI/6) ctx.lineTo(0, -100) 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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| <script> const canvas = document.getElementById('canvas') const ctx = canvas.getContext('2d') canvas.width = window.innerWidth canvas.height = window.innerHeight
ctx.beginPath() ctx.translate(canvas.width/2, canvas.height/2) ctx.strokeStyle='red' ctx.lineWidth = 3 ctx.moveTo(0, 0) ctx.lineTo(0, -100) ctx.rotate(Math.PI/6) ctx.lineTo(0, -50) ctx.rotate(Math.PI/6) ctx.lineTo(0, -100) ctx.rotate(Math.PI/6) ctx.lineTo(0, -50) ctx.rotate(Math.PI/6) ctx.lineTo(0, -100)
ctx.rotate(Math.PI/6) ctx.lineTo(0, -50) ctx.rotate(Math.PI/6) ctx.lineTo(0, -100)
ctx.rotate(Math.PI/6) ctx.lineTo(0, -50) ctx.rotate(Math.PI/6) ctx.lineTo(0, -100)
ctx.rotate(Math.PI/6) ctx.lineTo(0, -50) ctx.rotate(Math.PI/6) ctx.lineTo(0, -100)
ctx.rotate(Math.PI/6) ctx.lineTo(0, -50) ctx.rotate(Math.PI/6) ctx.lineTo(0, -100) ctx.stroke() </script>
|
结果如下图所示, 六边形就画成了,但是多了一根线,可以直接将这行代码ctx.moveTo(0, 0) 注释掉即可
3. 使用循环实现
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
| <script> const canvas = document.getElementById('canvas') const ctx = canvas.getContext('2d') canvas.width = window.innerWidth canvas.height = window.innerHeight
ctx.beginPath() ctx.translate(canvas.width/2, canvas.height/2) ctx.strokeStyle='red' ctx.lineWidth = 3 ctx.lineTo(0, -100)
for(let i=0;i<6;i++) { ctx.rotate(Math.PI/6) ctx.lineTo(0, -50) ctx.rotate(Math.PI/6) ctx.lineTo(0, -100) } ctx.stroke() ctx.stroke() </script>
|
效果和上面一样,还可以改成7角星或更多角,只需要改一个数字即可
将6更改为10
1 2 3 4 5 6
| for(let i=0;i<10;i++) { ctx.rotate(Math.PI/10) ctx.lineTo(0, -50) ctx.rotate(Math.PI/10) ctx.lineTo(0, -100) }
|
4. 定义函数绘制多边形或多角星
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| <!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> * { margin: 0; padding: 0; box-sizing: border-box; }
body { overflow: hidden; background-color: black; }
#canvas { background-color: white; position: absolute; top: 0; left: 0; width: 100%; height: 100%; } </style> </head> <body> <canvas id="canvas"></canvas> <script> const canvas = document.getElementById('canvas') const ctx = canvas.getContext('2d') canvas.width = window.innerWidth canvas.height = window.innerHeight let x = canvas.width/2 let y = canvas.height/2 drawShape(x, y, 50, 1.5, 8)
function drawShape(x, y, radius, inset, n) { ctx.fillStyle = 'hsl(3,100%,50%)' ctx.beginPath() ctx.save() ctx.translate(x,y) ctx.moveTo(0, 0-radius) for(let i=0;i<n;i++) { ctx.rotate(Math.PI/n) ctx.lineTo(0, 0-radius*inset) ctx.rotate(Math.PI/n) ctx.lineTo(0, 0-radius) } ctx.restore() ctx.closePath() ctx.stroke() ctx.fill() } </script> </body> </html>
|
- 调用时可传递不同的参数值,看看效果吧
- drawShape(x, y, 50, 1.5, 8)
- drawShape(x, y, 50, 1.5, 8)
- drawShape(x, y, 100, 2.8, 5)
以上均为绘图基础,为后续绘制复杂的图形和动画打好基础. 最后一个函数稍微复杂一点点。用到的技术也就是前面篇章里介绍的。