Search code examples
javascriptloopscanvasrect

JS loop skips to last rectangle (using canvas) drawn on the screen


I'm fairly new with OOP and classes but was experimenting with it, while trying to create a method that would randomly create triangles on my HTML5 canvas.

The problem is that I can only see the last rectangle produced on the loop. All the other rectangles are not shown on the screen. Here is my code.

class Animations{       
   constructor(){}
    //Background animation
    backgroundAnimation(x,y,height,width){
        this._x       = x;
        this._y       = y;
        this._height  = height;
        this._width   = width;
        let canvas    = document.querySelector('canvas');
        canvas.width  = window.innerWidth;
        canvas.height = window.innerHeight; 

        let c         = canvas.getContext('2d');
        c.beginPath;
        c.rect(this._x,this._y,this._width,this._height);
        c.fillStyle = 'blue';
        c.fill()
        c.stroke();
    }        
}

var animations = new Animations();

window.addEventListener("load", ()=>{
    for(let i=0;i<10;i++){
        let x = Math.floor(Math.random()*100+50);
        let y = Math.floor(Math.random()*100+50);
        animations.backgroundAnimation(x,y,20,20);
    }
});
<canvas></canvas>

Any help would be greatly appreciated. Thanks in advance :)


Solution

  • The problem here is that you are resizing the canvas, each time you draw on it, which causes it to clear.

    See HTML5 responsive canvas: resizing the browser canvas draw disappear and Preventing Canvas Clear when Resizing Window

    If you really want to resize it each time, then you'll have to come up with a way to store the things you drew on it, and re-draw.

    Alternatively, if don't need to resize it, then simply create one instance of your Animations class, and do the resizing in the constructor:

    <body>
      <canvas></canvas>
      <script>
        class Animations{
          constructor(){
            let canvas    = document.querySelector('canvas');
            canvas.width  = window.innerWidth;
            canvas.height = window.innerHeight;
            this.c = canvas.getContext('2d');
          }
    
          //Background animation
          backgroundAnimation(x,y,height,width){
            this._x       = x;
            this._y       = y;
            this._height  = height;
            this._width   = width;
    
            this.c.beginPath();
            this.c.rect(this._x,this._y,this._width,this._height);
            this.c.fillStyle = 'blue';
            this.c.fill();
            this.c.stroke();
          }
        }
    
        window.addEventListener("load", ()=>{
          const animations = new Animations();
    
          for(let i=0;i<10;i++){
            let x = Math.floor(Math.random()*100+50);
            let y = Math.floor(Math.random()*100+50);
            animations.backgroundAnimation(x,y,20,20);
          }});
      </script>
    </body>
    

    Note you can then store a reference to the context as a property of the class this.c so that it can be accessed from the backgroundAnimation() method.