首页 > 网站 > WEB开发 > 正文

使用JavaScript和Canvas实现下雪动画效果

2024-04-27 14:06:41
字体:
来源:转载
供稿:网友

使用javaScript和Canvas实现下雪动画效果

该下雪动画效果使用了HTML5中Canvas画布实现,其中涉及了物理学中曲线运动的相关知识与运算。

index.html

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">    <meta content="yes" name="apple-mobile-web-app-capable">    <meta content="black" name="apple-mobile-web-app-status-bar-style">    <meta content="telephone=no" name="format-detection">    <meta content="email=no" name="format-detection">    <title>Snow</title>    <link rel="stylesheet" href="CSS/main.css"></head><body>    <canvas id="canvas"></canvas>    <script src="js/snow.js"></script>    <script>        window.addEventListener('load', function(){            this.snow = new Snow();            // 初始化snow对象并开始下雪动画            snow.init().start();        });    </script></body></html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

main.css

html, body{    width: 100%;    height: 100%;    overflow: hidden;    margin: 0;    padding: 0;    background-color: #000;    font-family: 微软雅黑, 华文细黑, 黑体;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Snow.js

(function(exports, undefined){    'use strict';    var document = exports.document;    function Snow(){        this.colors = ['#fff'];        this.balls = [];        this.windDirection = -1;        this.ballRadius = 3;        this.ballsPerFrame = 2;        this.timeInterval = 40;        this.windDirectionChangedInterval = 5000;        this.accumulativeTime = 0;        return this;    };    exports.Snow = Snow;    Snow.PRototype = {        init: function(args){            for(var p in args){                this[p] = args[p];            }            this.canvas = this.canvas || document.querySelector('#canvas');            this.context = this.context || this.canvas.getContext('2d');            this.canvasWidth = this.canvasWidth || document.body.offsetWidth || document.body.clientWidth;            this.canvasHeight = this.canvasHeight || document.body.offsetHeight || document.body.clientHeight;            this.canvas.width = this.canvasWidth;            this.canvas.height = this.canvasHeight;            return this;        },        start: function(){            this.timer = this.timer || setTimeout(this.frame.bind(this), this.timeInterval);            return this;        },        frame: function(){            this.accumulativeTime += this.timeInterval;            (this.accumulativeTime % this.windDirectionChangedInterval < this.timeInterval) && (this.windDirection *= -1);            this.render.call(this);            this.update.call(this);            this.timer = null;            this.timer = setTimeout(this.frame.bind(this), this.timeInterval);        },        update: function(){            this.addBalls.call(this);            this.updateBalls.call(this);        },        updateBalls: function(){            var balls = this.balls,                len = balls.length,                i = 0,                cnt = 0;            for(;i<len;i++){                balls[i].x += balls[i].vx * this.windDirection;                balls[i].y += balls[i].vy;                balls[i].vy += balls[i].g * balls[i].t;                balls[i].t += this.timeInterval;                if(balls[i].y - this.ballRadius < this.canvasHeight){                    balls[cnt++] = balls[i];                }            }            while(len>cnt){                balls.pop();                len--;            }        },        addBalls: function(){            var ball,                i = 0,                len = this.ballsPerFrame,                _this = this;            for(;i<len;i++){                ball = {                    x: Math.pow(-1, Math.ceil(Math.random() * 1000)) * Math.floor(Math.random() * _this.canvasWidth * 1.5),                    y: Math.floor(Math.random() * this.ballRadius) * -1,                    g: 0.00005,                    vx: 1 + Math.floor(Math.random() * 2),                    vy: 2 + Math.floor(Math.random() * 5),                    t: 0,                    color: _this.colors[Math.floor(Math.random() * _this.colors.length)]                }                this.balls.push(ball);            }        },        render: function(){            var cxt = this.context,                i = 0,                len = this.balls.length;            cxt.clearRect(0, 0, this.canvasWidth, this.canvasHeight);            for(;i<len;i++){                cxt.fillStyle = this.balls[i].color;                cxt.beginPath();                cxt.arc(this.balls[i].x, this.balls[i].y, this.ballRadius, 0, 2 * Math.PI, true);                cxt.closePath();                cxt.fill();            }        },        pause: function(){            clearTimeout(this.timer);            this.timer = null;        },        resume: function(){            this.start.call(this);        },        clear: function(){            clearTimeout(this.timer);            this.timer = null;            this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);        }    }})(window);


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表