(八) JavaScript-Canvas旋转的图片
JavaScript 是前端核心, 掌握这门语言是步入前端高手行列必经之路,噢,别忘了还有TypeScript, 学习它还需要OOP知识, 底层的浏览器原理、HTTP协议也必不可少, 此系列文章记录使用JavaScript和Canvas进行游戏开发, 有游戏才有趣!!!
旋转的图片
(八) JavaScript-Canvas旋转的图片
使用 Image类型创建图片对象, 自定义类 Picture
1. 设计网页代码
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
| <!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>旋转的图片</title> <style> canvas { position: absolute; background: black; width: 100%; height: 100%; top: 0; left: 0; } </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 </script> </body> </html>
|
2. 创建一个Image对象
- 使用 Image 创建一个对象,设置对象的src属性,表示图片的路径,此处将图片和页面放置在同一目录下,所以只需图片名称
1 2 3
| const cherry = new Image() cherry.src = 'cherry.png'
|
3. 在Canvas Context上 画图
- 图片是异步加载所以需要监听图片加载事件load, 加载完成后才能将图片画到Canvas上
- 使用translate平移坐标到(100,100), 为了清楚的了解后续图片的旋转
- 使用rotate 旋转 canvas 0度,也就是不旋转
- 再增加一个填充矩形,清楚图片位置,无其它作用
- drawImage 画图,第1个参数为图片对象,第2,3个参数表示图片的坐标,第4,5个参数表示图片宽和高
1 2 3 4 5 6 7 8
| cherry.addEventListener('load', function(){ ctx.translate(100,100) ctx.rotate(0 * Math.PI/360) ctx.fillStyle= 'black' ctx.fillRect(0,0,500,500) ctx.drawImage(cherry, 0, 0, 80, 80) })
|
效果如图
4. 再画一个位置不同的图
- 图片的位置还是平移100,但此时会发现,平移是相对于上面的图片位置
1 2 3 4 5 6 7 8 9 10 11 12 13
| cherry.addEventListener('load', function(){ ctx.translate(100,100) ctx.rotate(0 * Math.PI/360) ctx.fillStyle= 'black' ctx.fillRect(0,0,500,500) ctx.drawImage(cherry, 0, 0, 80, 80)
ctx.translate(100,100) ctx.rotate(0 * Math.PI/360) ctx.fillStyle= 'orange' ctx.fillRect(0,0,500,500) ctx.drawImage(cherry, 0, 0, 80, 80) })
|
效果如图
5. 使用save和restore方法
- 使用这两个方法后,恢复之前的状态,其实就是将save()之后的绘图操作入栈,调用restore()后出栈,也就是恢复到当前绘图之前的状态,后续画图会使用save()之前的状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| cherry.addEventListener('load', function(){ ctx.save() ctx.translate(100,100) ctx.rotate(0 * Math.PI/360) ctx.fillStyle= 'black' ctx.fillRect(0,0,500,500) ctx.drawImage(cherry, 0, 0, 80, 80) ctx.restore()
ctx.translate(100,100) ctx.rotate(30 * Math.PI/360) ctx.fillStyle= 'orange' ctx.fillRect(0,0,500,500) ctx.drawImage(cherry, 0, 0, 80, 80) })
|
效果如图: 桔色背景的图片旋转了30度,平移的位置相对于最开始时的状态; 如果桔色背景下方还要画图,也可以加上save和restore,使得桔色图形的属性设置不会影响后续图形
6. 让图片旋转起来
- 将绘图代码封装成函数,然后利用window.requestAnimationFrame函数让图片旋转起来
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
| const cherry = new Image() cherry.src = 'cherry.png'
let angle1 = 1 let angle2 = 10
function draw() { ctx.save() ctx.translate(canvas.width/2,canvas.height/2) ctx.rotate(angle1 * Math.PI/360) ctx.fillStyle= 'black' ctx.fillRect(0,0,300,300) ctx.drawImage(cherry, 0, 0, 80, 80) ctx.restore()
ctx.save() ctx.translate(canvas.width/2,canvas.height/2) ctx.rotate(angle2 * Math.PI/360) ctx.fillStyle= 'orange' ctx.fillRect(0,0,300,300) ctx.drawImage(cherry, 0, 0, 80, 80) ctx.restore() }
cherry.addEventListener('load', function(){ draw()
})
function animate() { ctx.clearRect(0,0,canvas.width, canvas.height) draw() angle1+=1 angle2+=10 window.requestAnimationFrame(animate) } animate()
|
效果如图, 也可以去掉矩形填充
7. 旋转的中心点改成图片中心
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
| let angle1 = 1 let angle2 = 10 function draw() { ctx.save() ctx.translate(canvas.width/2,canvas.height/2) ctx.rotate(angle1 * Math.PI/360) ctx.fillStyle= 'black' ctx.fillRect(0,0,300,300) ctx.drawImage(cherry, 0-80/2, 0-80/2, 80, 80) ctx.restore()
ctx.save() ctx.translate(canvas.width/2,canvas.height/2) ctx.rotate(angle2 * Math.PI/360) ctx.fillStyle= 'orange' ctx.fillRect(0,0,300,300) ctx.drawImage(cherry, 0-80/2, 0-80/2, 80, 80) ctx.restore() }
cherry.addEventListener('load', function(){ draw() })
function animate() { ctx.clearRect(0,0,canvas.width, canvas.height) draw() angle1+=1 angle2+=10 window.requestAnimationFrame(animate) } animate()
|
效果如图, 尝试去掉填充矩形
再用save() 和 restore() 函数 ,尝试使用面向对象的方法绘图