示例代码:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<meta charset="utf-8" />
<style>
body {
background:#333;
}
</style>
</head>
<body>
<button id="start-snowFall">开始</button>
<button id="stop-snowFall">停止</button>
<button id="pause-snowFall">暂停</button>
<button id="resume-snowFall">回复</button>
<script>
window.onload = function () {
//绑定事件
var snow = new snowFall({ maxFlake: 200 });
var start = document.getElementById('start-snowFall'),
stop = document.getElementById('stop-snowFall'),
pause = document.getElementById('pause-snowFall'),
resume = document.getElementById('resume-snowFall');
//开始
start.onclick = function () {
snow.start();
}
//停止
stop.onclick = function () {
snow.stop();
}
//暂停
pause.onclick = function () {
snow.pause();
}
//回复
resume.onclick = function () {
snow.resume();
}
}
//控制对象封装
function snowFall(snow) {
//可配置属性
snow = snow || {};
this.maxFlake = snow.maxFlake || 200; //最多骗术
this.flakeSize = snow.flakeSize || 10;// 雪花形状
this.fallSpeed = snow.fallSpeed || 2;//坠落速度
this.status = 0; //0-初始化、1-开始下雪 、2--停止下雪 、3--暂停下雪、4--继续下雨
}
//兼容写法
requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame ||
function (callback) { setTimeout(callback, 1000 / 60) };
cancelAnimationFrame = window.cancelAnimationFrame ||
window.mozCancelAnimationFrame ||
window.webkitCancelAnimationFrame ||
window.msCancelAnimationFrame ||
window.oCancelAnimationFrame; //开始下雪
snowFall.prototype.start = function () {
if (this.status == 1 || this.status == 4)
return false;
this.status = 1;
//创建画布
snowCanvas.apply(this);
//创建雪花形状
createFlakes.apply(this);
//画学
drawSnow.apply(this);
}
//停止下雪
snowFall.prototype.stop = function () {
if (this.status == 2 || this.status == 0 || !this.canvas) {
return false;
}
//定制动画循环
this.pause();
this.status = 2;
//删除画布
this.canvas.parentNode.removeChild(this.canvas);
this.canvas = null;
};
//暂停下雪
snowFall.prototype.pause = function () {
if (this.status == 3) {
return false;
}
this.status = 3;
cancelAnimationFrame(this.loop);
}
//继续下雪
snowFall.prototype.resume = function () {
if (this.status == 3 && this.canvas) {
this.status = 4;
//动画的计时控制
this.loop = requestAnimationFrame(function () {
drawSnow.apply(that);
});
}
}
//创建画布
function snowCanvas() {
//添加Dom节点
var snowcanvas = document.createElement('canvas');
snowcanvas.id = 'snowfall';
snowcanvas.width = window.innerWidth;
snowcanvas.height = window.innerHeight;
snowcanvas.setAttribute('style', 'position:fixed;top:0;left:0;z-index:2999;pointer-events:none;'); document.getElementsByTagName('body')[0].appendChild(snowcanvas);
this.canvas = snowcanvas;
this.ctx = snowcanvas.getContext('2d');
//窗口大小改变处理
window.onresize = function () {
snowcanvas.width = window.innerWidth;
snowcanvas.height = window.innerHeight;
}
}
//创建雪花
function createFlakes() {
var maxFlake = this.maxFlake,
flakes = this.flakes = [],
canvas = this.canvas;
for (var i = 0; i < maxFlake; i++) {
flakes.push(new flakeMove(canvas.width, canvas.height, this.flakeSize, this.fallSpeed));
}
}
//雪运动对象
function flakeMove(canvasWidth, canvasHeight, flakeSize, fallSpeed) {
this.x = Math.floor(Math.random() * canvasWidth); //x坐标
this.y = Math.floor(Math.random() * canvasHeight); //y坐标
this.size = Math.random() * flakeSize + 2; //形状
this.masSize = flakeSize; //最大形状
this.speed = Math.random() * 1 + fallSpeed; //坠落速度
this.fallSpeed = fallSpeed; //坠落速度
this.velY = this.speed; //y方向速度
this.velX = 0; //x方向速度
this.stepSize = Math.random() / 30; //步长
this.step = 0; //步数
}
//重置当前雪花的位置
flakeMove.prototype.update = function () {
var x = this.x,
y = this.y;
//左右摆动(余弦)
this.velX *= 0.98;
if (this.velY <= this.speed) {
this.velY = this.speed;
}
this.velX += Math.cos(this.step += 0.05) * this.stepSize; this.y += this.velY;
this.x += this.velX;
//飞出边界处理
if (this.x >= canvas.width || this.x <= 0 || this.y >=canvas.height || this.y <= 0) {
this.reset(canvas.width,canvas.height);
}
}
//飞出边界--放置最顶端继续坠落
flakeMove.prototype.reset = function (width, height) {
this.x = Math.floor(Math.random() * width);
this.y = 0;
this.size = Math.random() * this.masSize + 2;
this.speed = Math.random() * 1 + this.fallSpeed;
this.velY = this.speed;
this.velX = 0;
}
//渲染雪花--随机形状
flakeMove.prototype.render = function (ctx) {
var snowFlake = ctx.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.size);
snowFlake.addColorStop(0, 'rgba(255,255,255,0.9)');
snowFlake.addColorStop(0.5, 'rgba(255,255,255,0.5)');
snowFlake.addColorStop(1, 'rgba(255,255,255,0)');
ctx.save();
ctx.fillStyle = snowFlake;
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
}
//滑雪
function drawSnow() {
var maxFlake = this.maxFlake,
flakes = this.flakes;
ctx = this.ctx,
canvas = this.canvas,
that = this;
//清空
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < maxFlake; i++) {
flakes[i].update();
flakes[i].render(ctx);
}
//一折一帧的画
this.loop = requestAnimationFrame(function () {
drawSnow.apply(that);
});
}
</script>
</body>
</html>

显示结果:

1.主要代码

this.step = 0;
this.stepSize = Math.random() / 30;
this.velX += Math.cos(this.step += .05) * this.stepSize;
this.x += this.velX;

step从0开始,每一帧增加0.05,相当于上图的横轴(X坐标)随着时间向右走

Math.cos(this.step += .05)则为上图对应的数轴(Y坐标),会随着step的增加,呈现1到-1的抛物线变换,正负值使得velX有左右方向

stepSize为步长,因为一帧有几十毫秒,很快,所以这个值为小于1/30的一个随机数

x为雪花的X坐标位置,就会在界面左右摆动

使用Canvas实现下雪功能的更多相关文章

  1. html5 canvas 实现倒计时 功能

    function showTime(a) { var b = { id: "showtime", //canvasid x: 60, //中心点坐标 X轴; y: 60, //中心 ...

  2. canvas实现画板功能(渐变、动画、阴影...)

    刚刚在博客园落户了,希望能在这认识更多大神,希望能和大家交好朋友. 闲来无事,把以前用canvas写的画板代码改进了一番,用Html5提供的表单标签给其 加了一个选择颜色的功能,因此发现了该标签的一个 ...

  3. Canvas的下雪效果

    cfs.snow.js canvas 下雪场景 不会影响页面使用 使用方式非常简单 利用这个js文件,我们就能很快的让页面出现下雪的动画效果. 例如 <script type="tex ...

  4. 【分享】用Canvas实现画板功能

    前言 PC端测试:QQ浏览器全屏绘画完成.缩小时内容会被清空,切换背景颜色内容会被重置,其他暂无发现: 手机端测试:微信内置浏览器不通过:Safari 浏览器使用画笔时没固定页面会有抖动效果,使用橡皮 ...

  5. H5利用canvas实现海报功能

    最近接到一个需求,微信中用户上传图片生成海报.这个需求比较常规,实现思路也比较简单,通过利用用户的input输入,对所上传的图片进行处理,最后通过第三方库html2canvas合成对应的图片即可.思路 ...

  6. canvas实现验证码功能

    我们在做一些后台系统登录功能的时候,一般都会用到验证码,最多的就是后台生成的验证码图片返回给前端的.也可以不调用后端接口,前端使用canvas直接生成验证码. 由于功能过于简单,不需要多少代码和文字说 ...

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

    该下雪动画效果使用了HTML5中Canvas画布实现,其中涉及了物理学中曲线运动的相关知识与运算. index.html <!DOCTYPE html> <html lang=&qu ...

  8. 通过jcrop和canvas的画布功能完成对图片的截图功能与视频的截图功能实现

    最近因为工作需要,做了视频截图和图截图的功能.大概需求是,用户点击某个按钮,可以对图片区域进行部分截取,然后进行进一步的业务操作. 首先说图片截图功能的思路, (1)下载Jcrop插件,添加css和j ...

  9. Canvas现实画板功能

    先看图片 HTML <!doctype html> <html lang="en"> <head> <meta charset=" ...

随机推荐

  1. ext.apply和ext.applyIf

    apply的用法: Ext中apply及applyIf方法的应用 apply及applyIf方法都是用于实现把一个对象中的属性应用于另外一个对象中,相当于属性拷贝. 不同的是apply将会覆盖目标对象 ...

  2. WebAPI接口测试之matthewcv.WebApiTestClient

    WebAPI接口测试之matthewcv.WebApiTestClient matthewcv.WebApiTestClient 1.安装matthewcv.WebApiTestClient包 打开v ...

  3. WEB编码事项

    标准 WEB开发标准是一系列标准的集合, 包含HTML结构标准.CSS表现标准.JS行为标准.代码标准.标准测试. 目标 WEB开发流程统一标准化,实现页面结构.表现.行为适当分离,提高页面易维护性, ...

  4. 嵌入式学习笔记(虚拟机共享文件夹配置-Ubuntu系统中)

    最近在学习Linux的操作系统,使用的是虚拟机.由于一些文件需要在主机和虚拟机中都要编辑,如果可以使得文件共享,可以极大的提高工作效率! 配置共享文件的步骤如下: [第一步] 在虚拟机软件中设置 [第 ...

  5. (转) IsPostBack的用法

    某一天在网上看到有人写了这样一段代码: protected void Page_Load(object sender, EventArgs e)     {         if (!IsPostBa ...

  6. 如何改变dreamweaver的编码方式

  7. Tomat部署Web运用

    在Tomcat部署Web运用的方式主要有如下几种 >利用Tomcat的自动部署 >利用控制台部署    >增加自定义的Web部署文件 >修改server.xml问价部署Web运 ...

  8. Qt_chartdirector图形开发

    ChartDirector 是一款商业的图表库,有多种语言的版本,使用它做的图表非常的精 细漂亮,提供免费版本,但会出现logo信息.网上有很多关于它的破解方法. 一.产品优点 高效快捷 采用多线程结 ...

  9. BZOJ 1027 [JSOI2007]合金

    1027: [JSOI2007]合金 Time Limit: 4 Sec  Memory Limit: 162 MBSubmit: 2605  Solved: 692[Submit][Status][ ...

  10. COJ 0332 The Flash

    传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=302 The Flash 难度级别:B: 运行时间限制:1000ms: 运行 ...