使用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);
时间: 2024-10-13 02:41:13

使用JavaScript和Canvas实现下雪动画效果的相关文章

必备的Canvas接口和动画效果大全

1.概述 <canvas>元素用于生成图像.它本身就像一个画布,JavaScript 通过操作它的 API,在上面生成图像.它的底层是一个个像素,基本上<canvas>是一个可以用 JavaScript 操作的位图(bitmap).它与 SVG 图像的区别在于,<canvas>是脚本调用各种方法生成图像,SVG 则是一个 XML 文件,通过各种子元素生成图像.使用 Canvas API 之前,需要在网页里面新建一个<canvas>元素. <canvas

javascript仿天猫加入购物车动画效果

  注意:首先需要声明的是:代码原思路不是我写的,是在网上找的这种效果,自己使用代码封装了下而已:代码中都有注释,我们最主要的是理解抛物线的思路及在工作中完成这样的任务,最近需要做类似于天猫加入购物车动画效果,所以就在网上搜索了下,就看到类似的效果,就把代码截下来自己封装了下~~ 如果想要了解抛物线的细节,我建议大家先 看下 张鑫旭 讲解的抛物线的文章,再来看如下JS代码,可能理解更深点~~ http://www.zhangxinxu.com/wordpress/2013/12/javascri

canvas粒子文字动画教程

1,什么是canvas粒子动画 canvas粒子文字动画效果绚丽,实现的方法和难点主要是根据缓动函数来确定粒子的轨迹. 2.主要实现步骤 创建一个canvas,在canva上绘制文字或图片,然后获取像素的信息并生成一个粒子数组 var imageData = ctx.getImageData(0,0,canvas.width,canvas.height); ... var dotList = []; for(var x=0; x<imageData.width; x+=mass) { for(v

使用JavaScript和Canvas打造真实的雨滴效果

使用JavaScript和Canvas打造真实的雨滴效果 寸志 · 1 年前 我最近搞了一个有趣的项目——rainyday.js .我认为这个项目并不怎么样,而且,事实上这是我第一次尝试接触一些比弹窗更复杂的JavaScript.幸好,你们觉得它还有点意思.rainyday.js想创建一个轻量的JavaScript类库,利用HTML5的canvas,来实现雨滴在玻璃上滑落的效果.很简单,不过有时候还是很有挑战的,尤其是在我们既要尽力避免动画区别于通常JavaScript的动画,又要保证动画流畅运

【BOOM】一款有趣的Javascript动画效果

实践出真知,有的时候看到一些有趣的现象就想着用自己所学的知识复现一下.    缘起 前几天在 github 上看到同事的一个这样的小项目,在 IOS 上实现了这样一个小动画效果,看上去蛮炫的,效果图: 我就寻思着,在浏览器环境下,用 Javascript 怎么实现呢? 在浓烈的好奇心驱使下,最终利用 Javascript 和 CSS3 完成了模仿上面的效果,通过调用方法,可以将页面上的图片一键爆炸,我给它起了个 boomJS 的名字,贴两张效果图:           实现 我感觉效果还是可以的

基于canvas实现物理运动效果与动画效果(一)

一.为什么要写这篇文章 某年某月某时某种原因,我在慕课网上看到了一个大神实现了关于小球的抛物线运动的代码,心中很是欣喜,故而写这篇文章来向这位大神致敬,同时也为了弥补自己在运动效果和动画效果制作方面的不足 二.几种简单的直线运动 这一部分主要讲解的是简单的运动效果的实现原理,其实所有的canvas动画效果的实现在核心思想是一致的:都是先定义个初始的状态,然后定义一个定时器,定时器内执行一个方法,记得在这个方法中要对当前的画面清除,然后在这个方法中重新绘制需要变化的效果,由于人眼存在残影,所以短时

7个惊艳的HTML5 Canvas动画效果及源码

HTML5非常强大,尤其是现在大部分浏览器都支持HTML5和CSS3,用HTML5制作的动画也多了起来.另外,Canvas上绘制图形非常简单,本文就分享了一些强大的HTML5 Cnavas动画,一起来看看. 1.HTML5 Canvas瀑布动画 超逼真 这是一个很逼真的HTML5瀑布动画,基于Canvas实现的,效果相当酷. 在线演示   /   源码下载 2.HTML5 Canvas彩色像素进度条动画 这也是一款基于HTML5 Canvas的动画特效,它是一个很有创意的HTML5进度条,大家可

javascript动画效果之缓冲动画(修改版)

在编写多块同时触发运动的时候,发现一个BUG, timer = setInterval(show, 30);本来show是一个自定义函数,当设为timer = setInterval(show(one,two), 30);时,发现show里面的参数one和two无法被导入,所以需要做以下代码改进和优化 原版的html和css代码在这里javascript动画效果之缓冲动画 js代码如下 1 <script> 2 function $(id) { 3 return typeof id === &

Javascript动画效果(四)

Javascript动画效果(四) 前面我们自己写了一个小小的关于js动画的插件,下面我们来使用之前的框架来完成我们想要的动画效果.我们经常在淘宝网中看到,鼠标经过某一图片时,该图片有从上滚出而又从下滚入的效果,那么那种效果是如何实现的呢? 首先我们我们完成该效果的html和css代码,代码如下: html部分代码: <div id="move"> <a href="#"><i><img src="images/1