js+canvas实现雨滴特效

给大家分享一下如何用js和canvas实现炫酷的雨滴特效

思路

先准备好开发工具,我用的是HBuilderX,当然也可以用Notepad等其它代码编辑器。还要了解一下canvas标签,其实就是一张画布,而js可以做到在上面画画并且实现动态效果

新建一张画布,铺满页面

canvas新建画布

<canvas class="rain"></canvas>

设置样式

		<style>
			body{
				margin: 0;
			}
			canvas{
				display: block;
				background: black;
			}
		</style>

js代码让画布铺满页面

			//获取canvas元素,浏览器窗口宽高
			var canvas = document.querySelector(".rain");
			var aRain=[];//存放雨滴
			var w,h;//画布宽度高度
			//立即执行方法
			(function setSize(){
				window.onresize = arguments.callee;
				w = window.innerWidth;
				h = window.innerHeight;
				canvas.width = w;
				canvas.height = h;
			})();

通过上面的准备已经得到一张画布,接下来就是核心部分,用js在画布上作画,实现想要的效果

画雨滴

实现雨滴效果,首先你得有雨滴对吧,而这里的雨滴其实是一段细长的矩形,
所以考虑怎么画出这样的矩形,核心操作如下

			//获取能操作画布的对象,可以说是画笔
			var canCon = canvas.getContext("2d");
			//开始一条路径,可以说是下笔
			canCon.beginPath();
			//设置颜色
			canCon.fillStyle = "aqua";
			//四个参数分别是矩形x,y坐标和宽度高度
			canCon.fillRect(x,y,4,10);

雨滴下降

现在考虑怎么让雨滴有下降效果,其实就是用一个定时器来不断改变y的大小,但这样其实就会造成是从上往下画一条长线的效果,这时候就要考虑蒙版的使用,每次y的改变,就把上面的雨滴遮掉,思路就是画一个矩形去覆盖,利用rgba改变透明度

				//加蒙版
				canCon.fillStyle="rgba(0,0,0,0.05)";
				canCon.fillRect(0,0,w,h);

制作源源不断的雨滴

我们的目的是画出源源不断的雨滴,所以得考虑每个雨滴的特性,包括生成的位置(总不能在同一个位置生成吧),雨滴下降以及每秒下降的距离等等,这时候就可以用面向对象的思想去表示雨滴,包括雨滴的一些初始属性,怎么去画雨滴,怎么让雨滴下降,将这些属性和方法封装成一个类

实现雨滴生成位置随机,写一个随机函数

			//返回最小值到最大值之间的值
			function random(min,max){
				return Math.random()*(max-min)+min;
			}

写一个雨滴类,实现初始属性以及函数,可以进一步考虑雨滴落到某个位置时产生绽放效果,主要是画半径不断变化的空心圆来实现

			//构造函数
			function Rain(){
				
			}
			//相当于一个雨滴类
			Rain.prototype = {
				//初始化雨滴
				init:function(){
					//生成雨滴位置
					this.x = random(0,w);//从0到w
					this.y = 0;
					this.vY = random(4,5);//每秒下降的距离
					this.h = random(0.8*h,0.9*h);//地板高度
					this.r =1;//雨滴绽放的初始半径
					this.vr = 1;//雨滴半径扩大的速度
				},
				//画出雨滴
				draw:function(){
					//让雨滴
					if(this.y<this.h){
						//开始一条路径,可以说是下笔
						canCon.beginPath();
						//设置颜色
						canCon.fillStyle = "aqua";
						//四个参数分别是矩形x,y坐标和宽度高度
						canCon.fillRect(this.x,this.y,4,10);
					}
					else{
						//画空心圆
						canCon.beginPath();
						canCon.strokeStyle = "aqua";
						//参数分别是x,y坐标,半径,0-360度
						canCon.arc(this.x,this.y,this.r,0,Math.PI*2);
						canCon.stroke();
					}
				},
				//雨滴下降
				move:function(){
					if(this.y<this.h){
						this.y+= this.vY;//雨滴每秒下降4-5
					}
					else{
						if(this.r<80){
							this.r+=this.vr;
						}
						else{
							this.init();
						}
						
					}
					this.draw();//画移动雨滴
				}
			}

写一个函数不断创造雨滴,这里现在前面声明一个数组用来储存雨滴对象,还要考虑到for循环的速度贼快,生成雨滴时要给它一个递增的延时效果

			function createRain(num){
				for(var i =0;i<num;i++){
					setTimeout(function(){
							var rain = new Rain();
							rain.init();
							rain.draw();
							aRain.push(rain);
						},200*i);
				}
			}
			createRain(66);

接下来就是写定时器让雨滴下落,把前面的蒙版部分也加进来写在一个计时器

			setInterval(function(){
				
				//加蒙版
				canCon.fillStyle="rgba(0,0,0,0.05)";
				canCon.fillRect(0,0,w,h);
				//item指数组的每一个变量
				for(var item of aRain){
					item.move();
				}
			},1000/60);

整个代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>雨滴效果</title>
		<style>
			body{
				margin: 0;
			}
			canvas{
				display: block;
				background: black;
			}
		</style>
	</head>
	<body>
		<canvas class="rain"></canvas>
		<script>
			//获取canvas元素,浏览器窗口宽高
			var canvas = document.querySelector(".rain");
			var aRain=[];//存放雨滴
			var w,h;
			//立即执行方法
			(function setSize(){
				window.onresize = arguments.callee;
				w = window.innerWidth;
				h = window.innerHeight;
				canvas.width = w;
				canvas.height = h;
			})();
			
			//获取能操作画布的对象,可以说是画笔
			var canCon = canvas.getContext("2d");
			canCon.fillStyle = "aqua"//设置画笔颜色
			
			//返回最小值到最大值之间的值
			function random(min,max){
				return Math.random()*(max-min)+min;
			}
			
			//构造函数
			function Rain(){
				
			}
			//相当于一个雨滴类
			Rain.prototype = {
				//初始化雨滴
				init:function(){
					//生成雨滴位置
					this.x = random(0,w);//从0到w
					this.y = 0;
					this.vY = random(4,5);//每秒下降的距离
					this.h = random(0.8*h,0.9*h);//地板高度
					this.r =1;//雨滴绽放的初始半径
					this.vr = 1;//雨滴半径扩大的速度
				},
				//画出雨滴
				draw:function(){
					//让雨滴
					if(this.y<this.h){
						//开始一条路径,可以说是下笔
						canCon.beginPath();
						//设置颜色
						canCon.fillStyle = "aqua";
						//四个参数分别是矩形x,y坐标和宽度高度
						canCon.fillRect(this.x,this.y,4,10);
					}
					else{
						canCon.beginPath();
						canCon.strokeStyle = "aqua";
						canCon.arc(this.x,this.y,this.r,0,Math.PI*2);
						canCon.stroke();
					}
				},
				move:function(){
					if(this.y<this.h){
						this.y+= this.vY;//雨滴每秒下降4-5
					}
					else{
						if(this.r<80){
							this.r+=this.vr;
						}
						else{
							this.init();
						}
						
					}
					this.draw();//画移动雨滴
				}
			}
			function createRain(num){
				for(var i =0;i<num;i++){
					setTimeout(function(){
							var rain = new Rain();
							rain.init();
							rain.draw();
							aRain.push(rain);
						},200*i);
				}
			}
			createRain(66);
			setInterval(function(){
				
				//加蒙版
				canCon.fillStyle="rgba(0,0,0,0.05)";
				canCon.fillRect(0,0,w,h);
				//item指数组的每一个变量
				for(var item of aRain){
					item.move();
				}
			},1000/60);
		</script>
	</body>
</html>

最终效果图

在这里插入图片描述
如果光看文章还是有疑问,可以点击链接

看视频,讲的贼详细,希望对各位有帮助,有空的时候做点特效打发打发时间

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值