[js高手之路]html5 canvas动画教程 - 下雪效果
利用canvas,实现一个下雪的效果,我们先预览下效果:
我们先分析下这个效果:
1,随机产生雪花
2,雪花的产生不是同时产生,而是有先后顺序的
3,雪花怎么表示
4,怎么源源不断的下雪
5,雪花有大有小
搞清楚上面几个问题之后,这个效果基本上就实现了,
首先,由于这个是全屏效果,我采用动态创建canvas,把整个浏览器的宽与高赋值给canvas
         var Canvas = function (w, h) {
                 this.width = w;
                 this.height = h;
             }
             Canvas.prototype = {
                 init: function () {
                     var oC = document.createElement("canvas");
                     oC.setAttribute('width', this.width);
                     oC.setAttribute('height', this.height);
                     oC.setAttribute('id', 'canvas');
                     oC.style.backgroundColor = '#000';
                     document.body.appendChild(oC);
                 }
             }
             var curWinWidth = window.innerWidth,
                 curWinHeight = window.innerHeight;
             var oCanvas = new Canvas(curWinWidth, curWinHeight);
             oCanvas.init();
调用oCanvas对象的init方法之后,就会在body的最后面追加一个canvas,id为canvas,宽、高与浏览器的宽、高相同,背景为黑色,晚上下雪的效果
接下来,有了舞台,演员该上场了,怎么产生雪花呢?这里把下雪相关的操作,封装成一个类,他的基本结构如下:
var Snow = function(){}
Snow.prototype = {
init : function(){},
draw : function( cxt ) {},
update : function(){}
}
这个类一共有三个方法( init, draw, update ).
init:初始化雪花的位置( x, y 坐标 )、速度、半径( 雪花的大小,在这里我们把雪花用半径不同的圆表示 )
            function random(min, max) {
                return Math.random() * (max - min) + min;
            }
            init: function () {
                    this.x = random(0, width);
                    this.y = 0;
                    this.r = random(1, 5);
                    this.vy = random(3, 5);
                }
那么init 加上 这个random函数 就可以完成雪花的初始化
1,雪花出来的时候,一般是在屏幕的最上方出现的,所以雪花的y坐标都是0, 其次,雪花的x坐标是随机的,他的范围是从屏幕的左边到右边,那么就是 0 ~ width. 这个width就是canvas的宽度,也就是浏览器的宽度
2,雪花的半径r, 设置为1 ~ 5之间的任意值
3,雪花下降的速度设置为3 ~ 5之间的随机速度,这里我做的下雪是垂直方向往下飘,你可以拓展,考虑风力影响( 这个时候肯定有水平方向的速度 )
有了这些初始化的参数之后,我们完善draw方法,绘制雪花:
                 draw: function (cxt) {
                     cxt.beginPath();
                     cxt.fillStyle = 'white';
                     cxt.arc(this.x, this.y + this.r, this.r, 0, Math.PI * 2, false);
                     cxt.fill();
                     cxt.closePath();
                     this.update(cxt);
                 },
参数cxt就是canvas的上下文,这个函数很简单,就是一个arc方法调用init中设置的值来画圆(雪花),在该方法的最后调用了一个update方法,他是干嘛的?他是更新雪花在垂直方向的速度
             update: function (cxt) {
                    if (this.y < height - this.r) {
                        this.y += this.vy;
                    } else {
                        this.init();
                    }
                }
在update方法中,我们做了边界判断: 雪花往下飘落的时候,肯定会消失,消失之后怎么处理?没有到达边界怎么处理?
canvas的高度减去雪花的半径,这就是雪花要消失时候的边界,所以this.y < height - this.r 如果这个条件成立,那么说明雪花一直在飘着,我们就要把雪花的y方向的位置更新,雪花看起来(‘正在下雪’),当一个雪花快要消失的时候,我们再把他移动到初始的位置,这样看起来就是在圆圆不断的下雪,而不需要重新绘制雪花(如果这样做,肯定会影响性能,这个特效最后肯定会被卡死,这个小技巧很多类似的特效都会用到)。至此核心的流程已经搞定,接下来,我们就要大量的生成雪花了。
var snow = [];
for (var i = 0; i < 500; i++) {
setTimeout(function () {
var oSnow = new Snow();
oSnow.init();
snow.push(oSnow);
}, 10 * i);
}
生成500个雪花,不是同时生成的,然后把这些雪花保存到数组snow中.
然后,开启定时器,让雪花不断的飘落吧,
关于requestAnimationFrame的使用,可以参考我的这篇文章:[js高手之路] html5新增的定时器requestAnimationFrame实战进度条
              (function move() {
                 oGc.clearRect(0, 0, width, height);
                 for (var i = 0; i < snow.length; i++) {
                     snow[i].draw(oGc);
                 }
                 requestAnimationFrame(move);
             })();
完整的demo代码:
<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>雪花效果 - by ghostwu</title>
<!-- <script src="lib.js"></script> -->
<style>
* {
margin: 0;
padding: 0;
} body {
overflow: hidden;
}
</style>
</head> <body>
<script>
window.onload = function () {
var Canvas = function (w, h) {
this.width = w;
this.height = h;
}
Canvas.prototype = {
init: function () {
var oC = document.createElement("canvas");
oC.setAttribute('width', this.width);
oC.setAttribute('height', this.height);
oC.setAttribute('id', 'canvas');
oC.style.backgroundColor = '#000';
document.body.appendChild(oC);
}
}
var curWinWidth = window.innerWidth,
curWinHeight = window.innerHeight;
var oCanvas = new Canvas(curWinWidth, curWinHeight);
oCanvas.init(); var oC = document.querySelector('#canvas');
var width = oC.width, height = oC.height, oGc = oC.getContext('2d'); function random(min, max) {
return Math.random() * (max - min) + min;
}
var Snow = function () { }
Snow.prototype = {
init: function () {
this.x = random(0, width);
this.y = 0;
this.r = random(1, 5);
this.vy = random(3, 5);
},
draw: function (cxt) {
cxt.beginPath();
cxt.fillStyle = 'white';
cxt.arc(this.x, this.y + this.r, this.r, 0, Math.PI * 2, false);
cxt.fill();
cxt.closePath();
this.update(cxt);
},
update: function (cxt) {
if (this.y < height - this.r) {
this.y += this.vy;
} else {
this.init();
}
}
} var snow = [];
for (var i = 0; i < 500; i++) {
setTimeout(function () {
var oSnow = new Snow();
oSnow.init();
snow.push(oSnow);
}, 10 * i);
} (function move() {
oGc.clearRect(0, 0, width, height);
for (var i = 0; i < snow.length; i++) {
snow[i].draw(oGc);
}
requestAnimationFrame(move);
})();
}
</script>
</body>
[js高手之路]html5 canvas动画教程 - 下雪效果的更多相关文章
- [js高手之路]html5 canvas动画教程 - 边界判断与小球粒子模拟喷泉,散弹效果
		备注:本文后面的代码,如果加载了ball.js,那么请使用这篇文章[js高手之路] html5 canvas动画教程 - 匀速运动的ball.js代码. 本文,我们要做点有意思的效果,首先,来一个简单 ... 
- [js高手之路]html5 canvas动画教程 - 边界判断与反弹
		备注:本文后面的代码,如果加载了ball.js,那么请使用这篇文章[js高手之路] html5 canvas动画教程 - 匀速运动的ball.js代码. 边界反弹: 当小球碰到canvas的四个方向的 ... 
- [js高手之路] html5 canvas动画教程 - 实时获取鼠标的当前坐标
		有了前面的canvas基础之后,现在开始就精彩了,后面写的canvas教程都是属于综合应用,前面已经写了常用的canvas基础知识,参考链接如下: [js高手之路] html5 canvas系列教程 ... 
- [js高手之路]html5 canvas动画教程 - 跟着鼠标移动消失的一堆炫彩小球
		综合利用前面所学,实现一个绚丽的小球动画,这个实例用到的知识点,在我的博客全部都有,可以去这里查看所有的canvas教程 <head> <meta charset='utf-8' / ... 
- [js高手之路] html5 canvas动画教程 - 匀速运动
		匀速运动:指的是物体在一条直线上运动,并且物体在任何相等时间间隔内通过的位移都是相等的.其实就是匀速直线运动,它的特点是加速度为0,从定义可知,在任何相等的时间间隔内,速度大小和方向是相同的. < ... 
- [js高手之路]html5 canvas动画教程 - 自己动手做一个类似windows的画图软件
		这个绘图工具,我还没有做完,不过已经实现了总架构,以及常见的简易图形绘制功能: 1,可以绘制直线,圆,矩形,正多边形[已完成] 2,填充颜色和描边颜色的选择[已完成] 3,描边和填充功能的选择[已完成 ... 
- [js高手之路]html5 canvas动画教程 - 重力、摩擦力、加速、抛物线运动
		上节,我们讲了匀速运动,本节分享的运动就更有意思了: 加速运动 重力加速度 抛物线运动 摩擦力 加速运动: <head> <meta charset='utf-8' /> &l ... 
- [js高手之路] html5 canvas系列教程 - 状态详解(save与restore)
		本文内容与路径([js高手之路] html5 canvas系列教程 - 开始路径beginPath与关闭路径closePath详解)是canvas中比较重要的概念.掌握理解他们是做出复杂canvas动 ... 
- [js高手之路] html5 canvas系列教程 - 掌握画直线图形的常用API
		我们接着上文[js高手之路] html5 canvase系列教程 - 认识canvas以及基本使用方法继续. 一.直线的绘制 cxt.moveTo( x1, y1 ): 将画笔移动到x1, y1这个点 ... 
随机推荐
- 201521123085 《JAVA程序设计》第6周学习总结
			1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 2. 书面作业 1.clone方法 1.1 Object对 ... 
- 201521123119《Java程序设计》第4周学习总结
			1. 本周学习总结 2.书面作业 1.注释的应用 使用类的注释与方法的注释为前面编写的类与方法进行注释,并在Eclipse中查看.(截图) 2.面向对象设计(大作业1,非常重要) 2.1 将在网上商城 ... 
- 201521123017 《Java程序设计》第12周学习总结
			1. 本周学习总结 2. 书面作业 Q1.字符流与文本文件:使用 PrintWriter(写),BufferedReader(读) 1.1 生成的三个学生对象,使用PrintWriter的printl ... 
- SharePoint备份文件
			stp文件:SharePoint的.stp文件 在做一个和SharePoint有关的项目时,由于对SharePoint的unfamiliar,所以客户发了几个后缀为.stp的文件将我纳闷了半天,不 ... 
- 《Java从入门到放弃》JavaSE入门篇:文件操作
			Java中的文件操作还有点小复杂··· 不过没关系,我会把它讲得很简单,嘿嘿嘿!!! 在讲Java中的文件操作前,先了解一个概念--"流",比如我们把一个杯子的水倒到另一个同样大小 ... 
- 读取指定excel,修改并某个值并另存到指定路径
			HSSFWorkBook是解析excel2007以前的版本(xls)之后的版本使用XSSFWrokBook(xlsx) 附:处理excel2007之后的版本代码: package gbyp.autoQ ... 
- Oracle单引号的用法-转义
			在ORACLE中,单引号有两个作用: 1:字符串是由单引号引用 2:转义. 单引号的使用是就近配对.而在单引号充当转义角色时相对不好理解 1.从第二个单引号开始被视为转义符,如果第二个单引号后面还 ... 
- JDBC数据库之添加数据
			通过JDBC向数据库中添加数据,可以使用INSERT语句实现插入数据SQL语句,对于SQL语句中的参数可以只用占位符"?"代替,然后通过PreparedStatement对其赋值以 ... 
- java最全时间类及用法
			对于时间类,这篇主要说明各种现实情况下如何取值,怎么定向取值,得到自己想要的时间参数.在java中时间类主要有Date.Calendar,暂时只介绍 java.util.*下的时间类,对于java.s ... 
- RocketMQ之双Master方式部署以及简单使用
			1.1.服务器环境 192.168.100.24 root nameServer1,brokerServer1 Master1 192.168.100.25 root nameServer2,brok ... 
