美文网首页学习
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