不知从什么时候我们已经没有了淋雨的勇气、不知从什么时候我们已经不敢享受雨水的甘甜、不知从什么时候我们感受不到那雨声的清脆。桃花已开但我们却嗅不到他的清香、春雨已来但我们却想方设法将其遮挡、湖水已涨但我们却失去了赏鱼的闲情雅致。时光让我们学到了很多、时光也让我们失去了很多。成天奔波的我们从来不舍得停下脚步,因为今天的我们已经意识到了一寸光阴一寸金的真正内涵。为了冰箱里的那块面包,我们每天就这样奔波着、忙碌着......

停止牢骚,言归正题。

这篇blog描写的是一个动态水波的效果,主要是通过HTML5里面的canvas来实现。整片文章属于原创若有相同纯属有缘,但是里面的核心水波原理并非本人原创是参考网上很多关于水波原理进行综合而成,所以在这里要谢谢网上那些贡献知识的人。闲话少说,先看实现的效果如图一:

图一

考虑到性能问题,建议图片不要太大,本例子用400*300的图片在chrome和firefox下还算流畅,但是safari相对较卡。把图片扩大2倍至800*600就比较卡,效果不是很好。下面将代码贴出共大家一起交流学习。

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>春天,陪你一起去赏雨——HTML5下雨效果</title><style type="text/css">#box{ border:2px solid #f60; margin:0 auto;}</style><script>var floor = Math.floor;//向下取整var canvas;//画布var context;//画布上下文var width;//背景图片、画布宽var height;//背景图片、画布宽var size;//像素点个数、width*heightvar nextPoint = [];//下一振幅var prePoint = [];//上一振幅var tempPoint = [];//临时存储var imgData;//背景图片数据var speed = 100;//下雨大小,默认是一秒钟一个雨滴var weight = 1000;//雨滴的大小/**author:qingfeileedate:2012-03-24description:开始启动程序**/function start() {initImage("background.jpg");}/**author:qingfeileedate:2012-03-24description:初始化图片信息**/function initImage(src) {var img = new Image();img.src = src;img.onload = function() {init(img);};}/**author:qingfeileedate:2012-03-24description:初始化系统函数**/function init(img){initSize(img);initPoint();initCanvas();loadImage(img);}/**author:qingfeileedate:2012-03-24description:绘制图片函数**/function loadImage(img){context.drawImage(img, 0, 0);imgData = context.getImageData(0, 0, width, height);setInterval(spread, 1000/60);setInterval(rain, speed);}/**author:qingfeileedate:2012-03-24description:初始化画布信息**/function initCanvas(){canvas = document.getElementById('ripper');context =canvas.getContext('2d');canvas.width = width;canvas.height = height;canvas.onclick = function(e) {setDropPoint(floor(e.clientX-(document.body.clientWidth  - width)/2), floor(e.clientY - (document.body.clientHeight  - height) / 2), 15000);}}/**author:qingfeileedate:2012-03-24description:设置画布宽高及画布像素数**/function initSize(img){width = img.width;height = img.height;document.getElementById("box").style.width = width+"px";document.getElementById("box").style.height = height+"px";size = width*height;}/**author:qingfeileedate:2012-03-24description:初始化存储图像前一个和后一个点的数组**/function initPoint(){for (var i = 0; i < size; i++) {nextPoint.push(0);prePoint.push(0);}              }/**author:qingfeileedate:2012-03-24description:一石激起千层浪,设置波动点及注入的能量其中x表示物体进入水面的X坐标,Y表示物体进入水面的Y坐标,power表示物体的能量大小**/function setDropPoint(x, y, power) {if (x < 2 || x > width - 2 || y < 1 || y > height - 2) return;var i = x + y * width;nextPoint[i] += power;nextPoint[i - 1] -= power;}/**author:qingfeileedate:2012-03-24description:核心算法,处理像素的波动效果PS:该算法非原创,借鉴网络上多个版本算法综合**/function spread() {var img = context.getImageData(0, 0, width, height),data = img.data;//平均一下各个点的能量for (var i = width + 1; i < size - width - 1; i += 2) {for (var x = 1; x < width - 1; x++, i++) {nextPoint[i] = (nextPoint[i] + nextPoint[i + 1] + nextPoint[i - 1] + nextPoint[i - width] + nextPoint[i + width]) / 5;}}//渲染除了第一行、最后一行、第一列、最后一列外的所有点for (var i = width + 1; i < size - width - 1; i += 2) {for (var x = 1; x < width - 1; x++, i++) {//水波振幅线性公式参考的是网络上的一些研究文献得出的prePoint[i] = (nextPoint[i - 1] + nextPoint[i + 1] + nextPoint[i + width] + nextPoint[i - width])/2 - prePoint[i];var ti = i + floor((prePoint[i - 2] - prePoint[i]) * 0.08) + floor((prePoint[i - width] - prePoint[i]) * 0.08) * width;ti = ti < 0 ? 0 : ti > size ? size: ti;var light = prePoint[i] * 2.0 - prePoint[i - 2] * 0.6;light = light < -10 ? -10 : light > 100 ? 100 : light;//之所以是i*4是因为canvas获取的data数据每四个值表示一个像素包括分别是红/绿/蓝/透明,要想了解更多关于canvas的请参看我的另一篇blog:http://blog.csdn.net/qingfeilee/article/details/7233683data[i * 4] = imgData.data[ti * 4] + light;data[i * 4 + 1] = imgData.data[ti * 4 + 1] + light;data[i * 4 + 2] = imgData.data[ti * 4 + 2] + light;//波能渐渐衰减prePoint[i] -= prePoint[i]>>5;}}tempPoint = nextPoint;nextPoint = prePoint;prePoint = tempPoint;context.putImageData(img, 0, 0);}function rain(){setDropPoint(floor(Math.random()*width), floor(Math.random()*height), floor(Math.random()*weight));}function setWeight(weight){this.weight = weight;}window.addEventListener("load", start, true);</script></head><body><div id="box"><canvas id="ripper" style="width:100%;height:100%; "></canvas><div align="center"><button onclick = "setWeight('1000')">小雨</button><button onclick = "setWeight('10000')">中雨</button><button onclick = "setWeight('20000')">大雨</button></div></div><div><h5 style = "text-align:center"><a href = 'http://blog.csdn.net/qingfeilee/'>阿飞blog</a></h5></div></div></body></html>

       核心算法的解释,在我们利用这个水波原理解析图像的时候我们只需要获取除了第一行、最后一行、第一列、最后一列的像素点即可,如图二:

图二
本Demo中还需要一张背景图片,注:图片不能太大、否则画面将比较不流畅。本文的背景图片如图三:

图三
       由代码注释较详细,具体就不再赘述。倘若对Canvas不太了解希望我的另外一篇blog《通过小画板认识Canvas》能够帮助到你。哪位大牛有好的算法实现希望能够多多交流,共同学习,共同进步,欢迎拍砖










												

春天,陪你一起去赏雨——HTML5下雨效果相关推荐

  1. 那些你很冒险的梦 我们陪你一起去疯

    那些你很冒险的梦 我们陪你一起去疯 6月9日,是在这漫长假期中普通的一天. 我依然是7点起床,洗脸刷牙,煮鸡蛋吃早餐,然后开始数学复习.但是在学校的他们,却是离校倒计时.我在想,如果我当初没有去选择复 ...

  2. 10款让你心动的 HTML5 CSS3 效果

    这里集合的这组 HTML5 & CSS3 效果,有的是网站开发中常用的.实用的功能,有的是先进的 Web 技术的应用演示.不管哪一种,这些案例中的技术都值得我们去探究和学习. 1.超炫的 HT ...

  3. 黑客帝国中代码雨如何实现?用 canvas 轻松实现代码雨炫酷效果!

    目录 1 效果 2 用到的知识点 2.1  什么是 canvas标签? 2.1.1 创建一个画布(Canvas) 2.1.2 使用 JavaScript 来绘制图像 2.1.3 Canvas 坐标 2 ...

  4. css3网站代码 html5_让你心动的 HTML5 CSS3 效果【附源码下载】

    这里集合的这组 HTML5 & CSS3 效果,有的是网站开发中常用的.实用的功能,有的是先进的 Web 技术的应用演示.不管哪一种,这些案例中的技术都值得我们去探究和学习. 超炫的 HTML ...

  5. 用JQ去实现一个轮播效果

    前提:用JQ去实现轮播效果一步步的做一个梳理. 首先肯定是轮播的HTML和CSS样式了: <body><div class="pic"><div cl ...

  6. html炫酷在线,小伙伴们都会惊呆的10个超炫的HTML5+CSS3效果作品

    在CodePen(CodePen 是一个在线的 HTML.CSS 和 JavaScript 代码编辑器,能够编写代码并即时预览效果)上看到许多非常炫的html+css3效果示例.这些炫酷的技术真是让我 ...

  7. 百叶窗设计原理 html5,Html5百叶窗效果的示例代码_html5教程技巧

    本篇文章主要介绍了Html5百叶窗效果的示例代码,小编觉得挺不错的,现在分享给大家HTML5源码和解释,也给大家做个参考.对HTML5感兴趣的小伙伴可以一起跟随小编过来看看吧 本文介绍了Html5百叶 ...

  8. 8个前沿的 HTML5 CSS3 效果【附源码下载】

    作为一个前沿的 Web 开发者,对于 HTML5 和 CSS3 技术或多或少都有掌握.前几年这些新技术刚萌芽的时候,开发者们已经使用它们来小试牛刀了,如今这些先进技术已经遍地开发,特别是在移动端大显身 ...

  9. 简直要逆天!超炫的 HTML5 粒子效果进度条

    我喜欢粒子效果作品,特别是那些能够应用于实际的,例如这个由 Jack Rugile 基于 HTML5 Cavnas 编写的进度条效果.看着这么炫的 Loading 效果,即使让我多等一会也无妨:)你呢 ...

最新文章

  1. 达摩院浙大上海人工智能实验室推出洛犀平台:大小模型端云协同进化
  2. java redis 命名空间_redis里通过命名空间存储缓存,根据结构生成树型
  3. CentOS中用top命令CPU负载
  4. 【Python】反转列表 list 的几种方法
  5. JPA模糊查询(表中的某些数据)
  6. __declspec(naked)和__asm编写实践总结
  7. 设计师妹子问:字体颜色渐变,你能实现?
  8. 如何提高码农产量,基于ASP.NET MVC的敏捷开发框架之移动端开发随笔二
  9. Cause: java.sql.SQLException: Unknown initial character set index ‘255‘ received from server. Initia
  10. 2018-05-02 os.path
  11. 目前总结最新最系统的Java程序员未来职业规划路线,请收藏
  12. [WPF]图片裁切功能(鼠标绘制)
  13. 最新唯美520表白纪念网页HTML源码+UI超级好看
  14. 智能睡眠监控APP开发有哪些好处?
  15. RedHat7.4配置免费yum源
  16. 使用“快剪辑”软件自定义修改视频尺寸
  17. Java 描述,数字转换为罗马数字。
  18. ActivityManagerService之进程管理(四)
  19. css3字体闪烁炫酷,css3 scale动画 字体、输入框等会闪烁,怎么解决?
  20. 华为1+X网络系统建设与运维(中级)——生成树协议(STP)

热门文章

  1. The road to learning English-Writing
  2. 文末有惊喜 | 开通微信公众号留言功能,只需3步!
  3. cf手游3月22日最全更新内容:恐怖博物馆、凤凰武器、血月模式上线
  4. 分层和分段用什么符号_PPT中如何利用符号做出分层显示效果
  5. flutter 自定义进度条progress
  6. 前端性能优化常用代码
  7. JS 控制文本框只能输入中文、英文、数字与指定特殊符号(屏蔽表情输入)
  8. 火星人敏捷开发手册免费培训 By 火星人陈勇
  9. 索尼visca协议封装
  10. hu丫丫收集到的web测试方法总结