zoukankan      html  css  js  c++  java
  • 玩别人玩剩下的: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进阶需要学习的一些知识点,小弟不胜感激~

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

  • 相关阅读:
    理解事件驱动select,poll,epoll三种模型
    谈谈对线程与进程的理解
    5-3.首行缩进
    5-2.行高
    5-1.字间距
    4-6.字体样式重置
    4-5.字体风格
    4-4.字体粗细
    4-3.字体颜色设置
    4-2.字体设置
  • 原文地址:https://www.cnblogs.com/10manongit/p/12843354.html
Copyright © 2011-2022 走看看