美文网首页学习
canvas下雨效果

canvas下雨效果

作者: 写前端的大叔 | 来源:发表于2019-12-18 23:24 被阅读0次

为了加强一下对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>

个人博客

相关文章

网友评论

    本文标题:canvas下雨效果

    本文链接:https://www.haomeiwen.com/subject/aikpnctx.html