玩别人玩剩下的:canvas大雪纷飞

canvas大雪纷飞

前言:正好业务触及到canvas,看完api顺手写个雪花效果,因为之前看到过很多次这个,主要看思路,想象力好的可以慢慢去创作属于自己的canvas效果

思路:

  • 利用画圆arc()和环形渐变色createRadialGradient()画一个雪花的模型(想要更好看的模型可以用图片代替)
    var grd = this.canvas.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.r);
    grd.addColorStop(0, "rgba(255,255,255,1)");
    grd.addColorStop(1, "rgba(255,255,255,0.2)");
    this.canvas.fillStyle = grd;
    this.canvas.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
    this.canvas.fill();

效果图clipboard.png

  • 如何让canvas画布上的点移动

动画其实就是一帧一帧的画面的组合,在一定时间内把画面从第一帧切换到第二帧到第n帧这个过程就是动画
弄懂这个道理,让雪花动起来就很简单了,重绘。
改变雪花的x,y坐标,在短时间内重绘一次,然后不断重复此过程,为了照顾浏览器爸爸的感受,x,y超出画布边界的时候把雪花清除掉。

    setInterval(() => {
        arr[0].canvas.clearRect(0, 0, maxW, maxH);
        for(var i = 0; i < arr.length; i++) {
            if(arr[i].y >= maxH){
                //清除超出下边界的雪花
                continue;
            }
            arr[i].play();
        }
    }, 30);

    play: function() {
        this.x += this.speedX;
        this.y += this.speedY;
        if(this.x < this.r) {
            this.speedX = Math.abs(this.speedX);
        }
        if(this.y < this.r) {
            this.speedY = Math.abs(this.speedY);
        }
        this.canvas.beginPath();
        var grd = this.canvas.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.r);
        grd.addColorStop(0, "rgba(255,255,255,1)");
        grd.addColorStop(1, "rgba(255,255,255,0.2)");
        this.canvas.fillStyle = grd;
        this.canvas.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
        this.canvas.fill();
    }
  • 最后一步就是创建一个个雪花实例去执行动画了
    var snow = function() {
        this.x = this.rand(maxW);
        this.y = 0;
        this.r = this.rand(10);
        this.speedX = this.getRanNum(-5, 5);
        this.speedY = this.getRanNum(10, 20);
        this.width = 0;
        this.height = 0;
        this.canvas = {};
        this.init();
    }
    var arr = [];
    setInterval(() => {
        for(let i = 0; i < 10; i++) {
            arr.push(new snow());
        }
    }, 30);

效果预览

完整代码

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            * {
                margin: 0;
                padding: 0;
            }
            body {
                background-color: '#fff';
            }
            canvas {
                background-color: rgba(0, 0, 0, 1);
            }
        </style>
    </head>

    <body>
        <canvas id="canvas" width="1000px" height="500px"></canvas>

        <script type="text/javascript">
            var myCanvas = document.getElementById('canvas')
            var ctx = myCanvas.getContext('2d');
            var clientW = window.innerWidth;
            var clientH = window.innerHeight;
            myCanvas.width = clientW;
            myCanvas.height = clientH;
            var maxW = clientW;
            var maxH = clientH;
            
            //雪花实例构造函数
            var snow = function() {
                this.r = this.rand(10);
                this.x = this.rand(maxW);
                this.y = 0;
                this.speedX = this.getRanNum(-5, 5);
                this.speedY = this.getRanNum(10, 20);
                this.width = 0;
                this.height = 0;
                this.canvas = {};
                this.init();
            }
            snow.prototype = {
                //初始化
                init: function() {
                    var snow = document.getElementById('canvas');
                    this.canvas = snow.getContext('2d');
                    this.width = snow.width;
                    this.height = snow.height;
                },
                //获取0-num之间的随机数
                rand: function(num) {
                    return Math.floor(Math.random() * num + 1);
                },
                //获取n-m之间的随机数
                getRanNum: function (n, m) {
                    return Math.floor(Math.random() * (m - n) + n);
                },
                //雪花移动
                play: function() {
                    //改变坐标位置   连续重绘形成动画效果
                    this.x += this.speedX;
                    this.y += this.speedY;
                    this.canvas.beginPath();
                    //定义雪花UI  渐变色+圆
                    var snowColor = this.canvas.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.r);
                    snowColor.addColorStop(0, "rgba(255,255,255,1)");
                    snowColor.addColorStop(1, "rgba(255,255,255,0.2)");
                    this.canvas.fillStyle = snowColor;
                    this.canvas.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
                    this.canvas.fill();
                }
            };

            var arr = [];
            //生成新雪花的速度  每30ms生成10个
            setInterval(() => {
                for(let i = 0; i < 10; i++) {
                    arr.push(new snow());
                }
            }, 30);
            
            //雪花重绘(即帧,多帧即移动动画) 30ms重绘一次
            setInterval(() => {
                arr[0].canvas.clearRect(0, 0, maxW, maxH);
                for(let i = 0; i < arr.length; i++) {
                    if(arr[i].y >= maxH){
                        //清除超出下边界的雪花
                        arr.splice(i,1);
                        continue;
                    }
                    arr[i].play();
                }
            }, 30);
        </script>
    </body>
</html>

最后,每几个canvas的方法组合一下做个小效果,慢慢的就可以做大型炫酷效果了,当然,炫酷效果离不开一些常用或生僻的数学知识,各类算法,方法,相关插件(我说的插件是用来计算一些东西或者图形之类的,不是用插件画canvas)作为铺垫
敲黑板,希望路过的大神能介绍一些canvas进阶需要学习的一些知识点,小弟不胜感激~

版权所有,转载请注明出处~

原文地址:https://www.cnblogs.com/10manongit/p/12843354.html