为了加强一下对canvas
知识和requestAnimationFrame
的理解和应用,特意实现了一个下雨的效果,下面一步一步来实现下雨。
1.绘制一滴雨
首先需要将雨给绘制出来,雨的形状是上头小,下边像个圆形一样的。其实就类似一个锥形,绘制出来的后的效果如下所示:
雨.png
绘制图形的代码如下所示:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgba(255,255,255,1)';
ctx.moveTo(90,90);//起点
ctx.lineTo(95,110);//绘制线条
var radius = 5;//圆形半径
ctx.arc(90,110,radius,0,180* Math.PI / 180);//绘制一个半圆
ctx.closePath();//闭合路径
ctx.fill();//填充
var img = new Image();
img.src = canvas.toDataURL("image/png");//保存图片
2.让雨往下掉
绘制好雨后,就要让它动起来,让雨动起来很简单,首先将绘制好的形状保存为图片,绘制在画布上,然后再使用requestAnimationFrame
方法,每执行一次requestAnimationFrame
就改变图像的'y'坐标,将图片进行重绘,具体代码如下所示:
//下落的方法
function dropDown(){
imgY += 10;//往下掉10个像素
ctx.clearRect(0,0,canvas.width,canvas.height);//清除画布
ctx.drawImage(img,0,imgY);//绘制图片
if(imgY > canvas.height){//超过屏幕时,重新从上往下掉
imgY = 10;
}
window.requestAnimationFrame(dropDown);
// setTimeout(dropDown,1000/60)
}
这里为什么用requestAnimationFrame
,而不用setTimeout
,因为setTimeout
并不适合做动画,系统对setTimeout
处理动画时没有做优化,当出现阻塞时,间隔时间并不一定准确。系统对requestAnimationFrame
处理动画做过一些优化,可以最大化的利用系统的性能。
3.绘制更多的雨
绘制完一滴雨并让它动起来之后,接下来就是让更多的雨往下掉了,让整个屏幕都在下雨,下面是所有实现的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>canvas下雨</title>
<style>
html,body{
width: 100%;
height: 100%;
background: black;
}
canvas{
background: black;
}
</style>
</head>
<body>
<canvas id="canvas" width="200" height="200"></canvas>
</body>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var count = window.innerWidth / 10,
imgCount = 3;
imgList = [],
yList = [];
ctx.fillStyle = 'rgba(255,255,255,1)';
for(var x = 0;x < imgCount;x++){
ctx.clearRect(0,0,canvas.width,canvas.height);//清除画布
for(var i = 0;i<count;i++){
var imgX = Math.random() * canvas.width;
var imgY = Math.random() * canvas.height;
ctx.beginPath();
ctx.moveTo(imgX,imgY);//起点
ctx.lineTo(imgX + 3,imgY + 15);//绘制线条
var radius = 3;//圆形半径
ctx.arc(imgX,imgY + 15,radius,0,180* Math.PI / 180);//绘制一个半圆
ctx.closePath();//闭合路径
ctx.fill();//填充
var img = new Image();
img.src = canvas.toDataURL("image/png");//保存图片
}
imgList[x] = img;
yList[x] = 0;
}
dropDown();
//下落的方法
function dropDown(){
ctx.clearRect(0,0,canvas.width,canvas.height);//清除画布
for(var i = 0;i<imgCount;i++){
yList[i] += (i + 1.5) * 5;
if (yList[i] > canvas.height) {
yList[i] = yList[i] - canvas.height;
}
ctx.drawImage(imgList[i], 0, yList[i]);
ctx.drawImage(imgList[i], 0, yList[i] - canvas.height);
}
window.requestAnimationFrame(dropDown);
// setTimeout(dropDown,1000/60)
}
</script>
</html>
网友评论