Canvas实现雨滴效果

主要思路:

  1. 创建canvas元素;

    注意:

    canvas并不是所有部分都能绘制图形,它像一个国画卷轴一样,可绘制部分只有宣纸部分。如果需要canvas画布局域填充整个cnavas宽高,需要进行设置。

    canvas是行内元素。行内元素如果等于浏览器宽高的话,会使浏览器出现滚动条,因为行内元素有行高,设置为块级元素即可。

    canvas有默认的宽高(300*150)

  2. 获取canvas元素,并设置canvas宽高等于整个浏览器窗口宽高;

    • 获取浏览器窗口的大下(宽高)

      window.innerWidth;

      window.innerHeight;

    • 当浏览器窗口宽高发生改变时,也需要重新设置canvas宽高;

      window.onresize = function(){};监听浏览器窗口的变化,在浏览器窗口变化的时候,执行获取浏览器窗口大小的方法,并给canvas进行重新赋值。

  3. 实现会动的图形。

    • 向下播放多张静态的图片。一秒内要大于屏幕刷新的帧数(60) 也就是每隔1/60s执行一次函数

  4. 在每次绘制的正方形上添加一个背景色为白色蒙板。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Canvas雨滴效果</title>
    <style>
        body {
            margin: 0;
        }

        .rain {
            display: block;
            background-color: #000;
        }
    </style>
</head>

<body>
    <canvas class="rain"></canvas>
    <script>
        // 1.获取canvas并设置大小
        var canvas = document.querySelector('.rain');
        var ctxWidth, ctxHeight; // 定义画布的宽高
        ~~function setResize() { // 根据浏览器窗口的改变,实时改变canvas画布的宽高,和浏览器保持一致
            window.onresize = arguments.callee;
            ctxWidth = window.innerWidth;
            ctxHeight = window.innerHeight;
            canvas.width = ctxWidth;
            canvas.height = ctxHeight;
        }();
        var ctx = canvas.getContext('2d');

        // 2.绘制单个会动的雨滴,根据单个雨滴进行接下来的雨滴对象Rain处理
        /* var y = 10;
        setInterval(function () {
            // 添加雨滴蒙版,使用透明色,使雨滴向上看起来有逐渐透明的效果
            ctx.fillStyle = 'rgba(0,0,0,0.05)';
            ctx.fillRect(0, 0, ctxWidth, ctxHeight);
        
            //绘制雨滴小矩形
            ctx.fillStyle = 'blue';
            ctx.fillRect(10, y++, 4, 10);
        }, 1000 / 60); */

        function random(min, max) { // 生成从min到max之间的随机数
            return Math.random() * (max - min) + min;
        }

        // 3.设置雨滴对象
        function Rain() { };
        Rain.prototype = {
            init: function () {
                this.x = random(0, ctxWidth);
                this.y = 0;
                this.vY = random(4, 5); // 雨滴在Y轴上运动的速度
                this.h = random(0.8 * ctxHeight, 0.9 * ctxHeight); // 雨滴停止的Y轴位置,整个画布的80%-90%高度的地方
                this.r = 1; // 圆形半径
                this.vR = 1; // 圆形半径变化的速度
            },
            draw: function () {
                if (this.y <= this.h) {
                    //绘制雨滴小矩形
                    ctx.beginPath();
                    ctx.fillStyle = '#31f7f7';
                    ctx.fillRect(this.x, this.y, 4, 10);
                } else {
                    ctx.beginPath();
                    ctx.strokeStyle = '#31f7f7';
                    ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
                    ctx.stroke();
                }
            },
            move: function () {
                if (this.y <= this.h) {
                    this.y += this.vY;
                } else {
                    if (this.r <= 100) {
                        this.r += this.vR;
                    }
                    else {
                        this.init();
                    }
                }
                this.draw();
            }

        }

        // 创建多个雨滴的函数,将雨滴push进入arrRains中
        var arrRains = [];

        function createRain(num) {
            // 每200ms生成一滴雨滴
            for (var i = 0; i <= num; i++) {
                setTimeout(function () {
                    var rain = new Rain();
                    rain.init();
                    rain.draw();
                    arrRains.push(rain);
                }, 200 * i);
            }
        }

        createRain(50);

        setInterval(function () {
            // 添加雨滴蒙版,使用透明色,使雨滴向上看起来有逐渐透明的效果
            ctx.fillStyle = 'rgba(0,0,0,0.05)';
            ctx.fillRect(0, 0, ctxWidth, ctxHeight);
            for (item of arrRains) {
                item.move();
            }
        }, 1000 / 60); // 每1/60秒执行一次函数
    </script>
</body>

</html>

效果图,截了一张静态的图片,实际效果是动态的。

猜你喜欢

转载自www.cnblogs.com/banyouxia/p/12159472.html