setInterval and setTimeout of Canvas drawing raindrops (2)

Posted by Hepp on Sun, 24 May 2020 17:37:06 +0200

Thank you for your guidance.

In view of the bad nature of setInterval, modify it, implement setInterval with setTimeout, and put it in the move attribute of Rain prototype. Operation result: the screen is in disorder and the browser is stuck..

as a result of:
setTimeout and setInterval should not be written in the function as much as possible. Whether they are timers or delayers, they will seriously hinder the normal operation of the program.

This program calls the timer function many times, repeated execution, performance degradation.

In addition, setting the timer belongs to the business code, while the properties defined in the prototype belong to the logic code. The two should be written separately. Easy to debug and organize.

As for how to distinguish between business code and logic code, we need to learn more about it

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <title>Raindrops falling2</title>
  <style>
  body{margin:0;}
  #rain{display:block;
  background-color:black;}
  </style>
 </head>
 <body>
 <!--Stuck code->
  <canvas id="rain"></canvas>
  <script>
  /*
    1.obtain
        1.1 Set canvas width and height
        1.2 Get window width and height
        1.3 When the window size changes, change the canvas width and height
    2.Draw raindrops
    3.Multiple raindrops
    3.Raindrops fall
        */
    //1. Set canvas size
    var can=document.getElementById("rain");//Set the width and height for the can element instead of the canvas getcontext
    //var can=document.getContext(canva);
    var w=window.innerWidth;//Use global variables to save width and height, reduce access and facilitate call
    var h=window.innerHeight;//Property name is inner width / height
    can.width=w;
    can.height=h;
    window.onresize=function(){
        w=window.innerWidth;
        h=window.innerHeight;//w,h need to be assigned again
        can.width=w;
        can.height=h;
        }
    //2. Draw raindrops
    //Draw a drop
    /*
    function random(min,max){
        return Math.random()*(max-min)+min;
    }
    var x=random(0,w);
    var y=0;//starting point
    var canContent=can.getContext("2d");//canvas
    //Initial position drawing
    canContent.fillStyle="rgb(0,255,255)";
    canContent.fillRect(x,y,5,20);//raindrop
    //Move - Animation
    function draw(){
        canContent.fillStyle="rgba(0,0,0,0.01)";
        canContent.fillRect(0,0,w,h);//Ground glass
        canContent.fillStyle="rgb(0,255,255)";
        canContent.fillRect(x,y++,5,20);//Raindrop position change
    }
    setInterval(draw,1000/60);

    */


    function random(min,max){
        return Math.random()*(max-min)+min;
    }

    function Rain(){};
    var canContent=can.getContext("2d");
    Rain.prototype={
        init:function(){
            //parameter
            this.x=random(0,w);
            this.y=0;//starting point
            this.l=random(0.8*h,0.9*h);//Falling height
            this.v=random(4,5);//Falling speed
            this.r=1;//The initial radius of the water bloom
            this.vr=random(1,2);//Speed of radius expansion
            this.rmax=random(50,60);//Radius to start transparency
            this.a=1;//Initial transparency
            this.va=0.98;//Changes in transparency
            this.amin=0.2;
        },
        draw:function(){
            //draw
            //. 1 draw drop
            if(this.y<this.l){
                canContent.fillStyle="rgb(0,255,255)";
                canContent.fillRect(this.x,this.y,2,20);//Raindrop position change
            }else{
            //. 2 draw water
                canContent.strokeStyle="rgba(0,255,255,"+this.a+")";//
                //"RGBA (0255255, this. A)"; / / an error will occur. Read the string and cannot get the variable change value
                canContent.beginPath();
                canContent.arc(this.x,this.y,this.r,0,2*Math.PI,false);
                canContent.stroke();
            }

        },
        update:function(){
            //Update coordinate values and draw
            //. 1 coordinate update during descent
            if(this.y<this.l){
                this.y+=this.v;
            }else{
            //. 2 coordinate update of water bloom process (coordinate unchanged, radius changed, transparency changed)
            //Paint raindrops after update:

                /*
                ////Transparency changes depending on radius
                this.r+=this.vr;
                if(this.r<this.rmax){
                    this.a*=this.va;
                }else{
                    this.init();
                }
                }
                */
                //The change of transparency depends on the size of radius, and the size of radius depends on the size of transparency
                if(this.a>this.amin){
                        this.r+=this.vr;
                        if(this.r>this.rmax){
                            this.a*=this.va;//Ride more naturally
                        }
                    }
                    else{
                        this.init();//If transparency changes, go back to the sky
                    }
                }
                this.draw();
                console.log("update:")
                console.log(this);

        },
        move:function(){
        //Mobile display: it covers different layers of opacity, and constantly draws raindrops in new locations
            canContent.fillStyle="rgba(0,0,0,0.05)";
            canContent.fillRect(0,0,w,h);//Ground glass
            console.log("move:")
            console.log(this);
            this.update();

            //setTimeout(arguments.callee,1000/60);
            // requestAnimationFrame( this.move ); / / not executed
            // console.log("222");
            moveRain.call(this);//Realization of timer with time delayer
            /*//Move outside to reduce memory usage
            function moveRain(){
                 this.move();
                  setTimeout(moveRain,1000/60);
            }
            */
        }
    }
//Realization of timer with time delayer
function moveRain(){
         this.move();
         setTimeout(moveRain,1000/60);
            }

//Create 30
for(var i=0;i<30;i++){
    setTimeout(createRain,300*i);//createRain every 300*i ms
}//30 settimeouts are created at the same time, but the execution time of each setTimeout is different

function createRain(){
    var rain=new Rain();
    rain.init();
    rain.draw();
    rain.update();
    rain.move();
    //setInterval(rain.move,1000/60); / / there is no rain at this time
    //Start at 0 second
}
  </script>
 </body>
</html>

Topics: Attribute Mobile