zoukankan      html  css  js  c++  java
  • 复杂下雨特效

    上次的下雨效果比较简单,这个要复杂很多

    对比:通过单个雨滴的位移达到下雨效果,上次是随机产生,然后刷新出来的,雨滴本身没有动

            雨滴碰到鼠标和地面会溅射

       鼠标能控制雨的速度和方向

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>rain</title>
    </head>
    <body>
    <canvas id="canvas" style="position: absolute; height: 100%; 100%;"></canvas>
        <script>
            window.onload=main;
    
            function getRgb(r,g,b){
                return "rgb("+ r+","+g+","+b+")";
            }
    
            function main(){
                //drop来存放溅射的雨滴
                var dropList=[];
                //重力因素,保持溅射的雨滴不会飞远
                var gravity=0.8;
                //保存雨滴
                var linelist=[];
    
    
                var canvasEl = document.getElementById('canvas');
                var ctx = canvasEl.getContext('2d');
    
                //鼠标的开始点为
                var mousePos = [0, 0];
                var backgroundColor = '#000';
                canvasEl.width=canvasEl.clientWidth;
                canvasEl.height=canvasEl.clientHeight;
    
                var speedx=0;
                var maxspeedx=0;
    
                //当改变浏览器窗口大小时
                window.onresize=function () {
                    canvasEl.width=canvasEl.clientWidth;
                    canvasEl.height=canvasEl.clientHeight;
                }
                //当鼠标移动时,获取坐标
                window.onmousemove=function (e) {
                    mousePos[0]=e.clientX;
                    mousePos[1]=e.clientY;
                    //最大速度-1到1个屏幕
                    maxspeedx=(e.clientX-canvasEl.clientWidth/2)/(canvasEl.clientWidth/2);
              
                }
    
                //给单个雨滴加属性
                function createLine(e){
                    //长度在12.5-37.5之间
                    var temp= 0.25*( 50+Math.random()*100);
                    //速度在16.5-50.5之间
                    var myline={
                        speed:5.5*(Math.random()*6+3),
                        die:false,
                        posx:e,
                        posy:-200,
                        h:temp,
                        //颜色在
                        color:(getRgb(Math.floor(temp*255/75),Math.floor(temp*255/75),Math.floor(temp*255/75)))
                    };
                    //添加到数组中
                    linelist.push(myline);
            }
             update();
    
             //生产小雨滴
            function createDrop(x,y){
                var mydrop={
                    die:false,
                    //溅射x坐标
                    posx:x,
                    //溅射的y坐标
                    posy:y,
                    //随机生成一个x轴速度
                    vx:(Math.random()-0.5)*8,
                    //随机生成一个y轴速度
                    vy:Math.random()*(-6)-3,
                    radius:Math.random()*1.5+1
                };
                return mydrop;
             }
            
            //溅射效果
            function madedrops(x,y){
                //溅射的雨滴数为5-10滴
                var maxi=Math.floor(Math.random()*5+5);
                for(var i=0;i<maxi;i++){
    
                     dropList.push(createDrop(x,y));
                }
            }
      
            function update() {
    
                //循环遍历小雨滴,显示溅射的雨滴,移除超出范围的雨滴
                if(dropList.length>0){
                    dropList.forEach(function (e) {
                        //小雨滴的x轴速度=随机速度+雨滴初始速度
                        e.vx=e.vx+(speedx)/2;
                        //小雨滴的新坐标
                        e.posx=e.posx+e.vx;
                        //小雨滴的y轴速度=随机速度+重力
                        e.vy=e.vy+gravity;
                        e.posy=e.posy+e.vy;
    
                            //雨滴超出屏幕高度,则消失
                        if(e.posy>canvasEl.clientHeight){
                             e.die=true;
                        }
                    });
                }
    
                //移除超出范围的雨滴
                for(var i=dropList.length-1;i>=0;i--){
                        if(dropList[i].die){
                            dropList.splice(i,1);
                    }
                }
                //鼠标的位置控制雨的速度
                //当鼠标在中间maxspeedx为0,不倾斜,速度不加快
                
                speedx=speedx+(maxspeedx-speedx)/50;
      
                if(Math.random()>0){
                    //雨滴的出生点的X轴坐标在-0.5到1.5倍的屏幕,这样雨滴倾斜的时候,最角落也会有雨滴
                    createLine(Math.random()*1.5*canvasEl.width -Math.random()*0.5*canvasEl.width);
                    createLine(Math.random()*1.5*canvasEl.width -Math.random()*0.5*canvasEl.width);
    
                    createLine(Math.random()*1.5*canvasEl.width -Math.random()*0.5*canvasEl.width);
                }
    
                //雨滴到达近地面时,近地面(1到0.8的屏幕高度)
                var mydeadline=canvasEl.clientHeight- Math.random()*canvasEl.clientHeight/5;
    
                //监听雨滴,雨滴距离鼠标的直线距离小于35时,两点之间的距离公式
                linelist.forEach(function (e) {
    
                    //雨滴距离鼠标的直线距离小于35时,两点之间的距离公式
                    var dis=Math.sqrt( ((e.posx+speedx*e.h)-mousePos[0])*((e.posx+speedx*e.h)-mousePos[0])+(e.posy+e.h-mousePos[1])*(e.posy+e.h-mousePos[1]));
                    if(dis<35){
                        //雨滴消失,产生小雨滴
                        madedrops(e.posx+speedx*e.h,e.posy+e.h);
                        e.die=true;
                     }
                    
                    //当雨滴到达地面时,每个雨滴的地面不同,0.8到1个屏幕高度
                    //如果每个
                    if((e.posy+e.h)>mydeadline){
    
                        //每个雨滴都出水花太多了。给个0.9的概率
                        if(Math.random() > 0.9){
                            madedrops(e.posx+speedx*e.h,e.posy+e.h);
                            e.die=true;
                        }
                    }
                    //水滴超出屏幕高度,设置为消失
                    if(e.posy>=canvasEl.clientHeight){
                        e.die=true;
                    }else{
                        e.posy=e.posy+e.speed;
                        e.posx=e.posx+(e.speed*speedx);
                    }
                });
    
                //消失雨滴
                for(var i=linelist.length-1;i>=0;i--){
                    if(linelist[i].die){
                        linelist.splice(i,1);
                    }
                }
                //清除界面
                render();
                //重绘页面
                window.requestAnimationFrame(update);
                }
                function  render() {
                    ctx.fillStyle = backgroundColor;
                    ctx.fillRect(0, 0, canvasEl.width, canvasEl.height);
    
                    linelist.forEach(
                        //绘制雨滴
                        function (line) {
                            ctx.strokeStyle =line.color;
    
                            ctx.lineWidth=4.5;
                            ctx.beginPath();
                            ctx.moveTo(line.posx,line.posy);
                            ctx.lineTo(line.posx+speedx*line.h,line.posy+line.h);
                            ctx.stroke();
                        });
    
                        ctx.lineWidth=1;
                        ctx.strokeStyle = "#fff";
    
                        //绘制溅射雨滴
                        dropList.forEach(function (e) {
                            ctx.beginPath();
                            ctx.arc(e.posx,e.posy,e.radius,Math.random()*Math.PI*2,1*Math.PI);
                            ctx.stroke();
                        });
                }
            }
    
    
    
        </script>
    </body>
    </html>
    
  • 相关阅读:
    Java 端口转发
    Tomcat笔记
    RocketMQ开启ACL后客户端连接报Algorithm HmacSHA1 not available的解决方式
    RSA签名与验签
    小米9升级MIUI11
    【转】linux awk命令详解
    进程和线程
    Jenkins笔记
    【转】Jenkins启动、停止脚本
    UiAutomator源码分析
  • 原文地址:https://www.cnblogs.com/anxiaoyu/p/6689853.html
Copyright © 2011-2022 走看看