0

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 :)

turivishal
  • 34,368
  • 7
  • 36
  • 59

1 Answers1

0

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.

antun
  • 2,038
  • 2
  • 22
  • 34
  • thank you very much for the clear explanation and recommendations for defining the context and cavas in the constructor. It makes a lot of sense to do so. Once again thank you :) –  Jun 03 '20 at 19:18
  • You're very welcome! Glad I could help. – antun Jun 03 '20 at 19:48