JavaScript-雨滴特效

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="Generator" content="EditPlus®">
        <meta name="Author" content="">
        <meta name="Keywords" content="">
        <meta name="Description" content="">
        <title>Canvas水滴</title>
		<style>
		    body{
		        margin:0;   
		    }
			#rain{
			    display:block;
			   
				background:"dark";
				/* width:100%;
				height:100%; */
			}
		</style>
 </head>



    <body>
        <canvas id="rain"></canvas>
        <script>
		    /*
			    程序逻辑:
				    1:设置canvas元素的宽高与浏览器一样
					    1.1:获取canvas元素
						1.2:获取浏览器宽高
						1.3:给canvas元素设置宽高
                    2:用canvas画图形
					    2.1:画一个矩形
						2.2:画一个圆形
                    3: 
			    */  
			    /* 1:设置canvas元素的宽高与浏览器一样*/
                //1.1:获取canvas元素
                var can=document.getElementById("rain");
			    //1.2:获取浏览器宽高
                var w=window.innerWidth;
			    var h=window.innerHeight;
			    //1.3:给canvas元素设置宽高
			    can.width=w;
			    can.height=h;
			    //1.4: 当窗口大小变化的时候自动调整canvas的宽高
			    window.οnresize=function(){
			        w=window.innerWidth;
				    h=window.innerHeight;
				    can.width=w;
				    can.height=h;
			    }
				
			    /*2:用canvas画图形*/
			    /*2.1 画一个矩形*/
			    //到画画的纸
			    var canContent=can.getContext("2d");
                //拿一支红色的实心笔
			    //canContent.fillStyle="dark";
			    //画一个矩形
			    //canContent.fillRect(150,150,100,100);
			    //这是画空心的笔
			    //canContent.strokeStyle="dark";
		        //canContent.strokeRect(150,150,100,100);	
				//先构思一个圆,其中0的意思是从哪个角度开始画(绘制起始点)(x,y,r,起始点,结束点)
				//canContent.arc(400,400,50,0,Math.PI*2);
				//这是画实心圆
				//canContent.fill();
				//这是画空心圆
			    //canContent.stroke();
				//y 用来实现动画过程
				//var x=0;
				//var y=0;
				//通过不断擦除和重画实现动态
				/*通过不断添加透镜实现覆盖,实现颜色渐变
				setInterval(function(){
					//一个矩形的向平擦,其实坐标和末端坐标
                    //canContent.clearRect(0,0,w,h);
					canContent.fillStyle="rgba(0,0,0,0.03)";
                    canContent.fillRect(0,0,w,h);
                    canContent.fillStyle="#fff";
					for(x=0;x<8;x++){
					canContent.fillRect(50*x,y++,10,10);}
					//canContent.fillRect(30*2,y++,10,10);
					//canContent.fillRect(30*3,y++,10,10);
				},1000/60)	*/
				//雨应该长什么样子
				function Rain(){};
				//var rain=new Rain();
				function random(min,max){
					//返回最大值和最小值之间的一个随机数
				    return Math.random()*(max-min)+min;
				}
				Rain.prototype={
					/*雨滴的基本配置*/
				    init:function(){
					    this.x=random(0,w);
						this.y=0;
						//移动速度堆积
						this.v=random(4,5);
						this.h=random(0.8*h,0.9*h)
						this.r=1;
						//this.vr=random(1,5);
						//调整速率可以是圆显得无缝一点
						this.vr=1;
						this.a=1;
						this.va=0.96;//透明变化系数
					},
					draw:function(){
						if(this.y<this.h){
					        canContent.fillStyle="#00cccc";
						    canContent.fillRect(this.x,this.y,2,10);
					    }else{
							
							canContent.strokeStyle="rgba(0,255,255,"+this.a+")";
							//重新拿起笔
							canContent.beginPath();
							canContent.arc(this.x,this.y,this.r,0,Math.PI*2);
							canContent.stroke();

						    
						
						}
					},
					move:function(){
					    /*this.y+=this.v;
						if(this.y>=this.h){
						    this.y=this.h;
						}
                        */
						//对比一下这两个代码,明显后面一个更简洁一点
						if(this.y<this.h){
						    this.y+=this.v;
						}else{
							if(this.a>0.02){
                               this.r+=this.vr;
							   if(this.r>50){
								   //半径到一定大小才开始变朦胧
							       this.a*=this.va;
								}
							}else{
							   //重新加载
							   
							   this.init();
							}
						}
						//this.y+=this.v;
						this.draw();
					}
				}
				var rainArray=[];
				function createRain(){
				    var rain=new Rain();
					rain.init();
					rain.draw();
					rainArray.push(rain);
				}
				//createRain();
				//for循环的速度比setTIimeout快的多,会造成先完成for循环之后再一起生成雨滴
				for(var i=0;i<30;i++){
					//这里creatRain不能加(),否则无法识别
				    setTimeout(createRain,200*i);
				}
				function moveRain(){
					canContent.fillStyle="rgba(0,0,0,0.1)";
					canContent.fillRect(0,0,w,h);
					for(var k=0;k<rainArray.length;k++){
					    rainArray[k].move();
					}				    
				}
				//似乎写成setInterval(move(),1000/6),加个括号似乎不行
				//setInterval(moveRain,1000/60);//16ms所有的计算和渲染必须在16ms内完成
				/*function run(){
				    moveRain();
					//会一直执行下去
					setTimeout(run,1000/60);
				}
				run();*/
 
				function timeOut(cb,time){
				    cb&&cb();
					setTimeout(function(){
					    timeOut.call(this,cb,time);
					}.bind(this),time)			
				}
				timeOut(moveRain,1000/60);
				/*补充知识点
				1:相比起setInterval来setTimeout更可控一点
				2:
				*/
			</script>
    </body>
</html>

以上代码采用EditPlus编辑的,我把学习过程中全部的代码都加进去了.
执行效果如图
这是我在b站上看一个视频写的,视频的名字是"世界上最强的语言JavaScript,10分钟写出逼真下雨特效,太厉害了",视频的讲师叫万章,讲的很好(虽然看得出也是一个推销课程的老师).看完了有一个比较深的感悟是JS绝对不是只搞特效的,代码的核心是算法.恩,加油!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值