Shambo Basu
Shambo Basu

Reputation: 13

Drawing a series of rectangles in HTML5 canvas to completely fill the canvas

I am new to HTML and javascript and trying to fill a HTML5 canvas with a series of rectangles each with increasing height and each of them next to previous. I want to my code to run on a variety of screen sizes hence i am finding the width and height of canvas dynamically from javascript. I want the number of bars 'n' to be input by the user in the future. This is what i've tried.

  //fucntion to draw the rectangles
 function draw(ctx,x,y,b,l){
    ctx.beginPath();
    ctx.rect(x,y,b,l);
    ctx.fill();
}

const c = document.querySelector("#my-canvas");
const ctx = c.getContext("2d");

//getting the height and widdth of the canvas
const cWidth = c.getBoundingClientRect().width;
const cHeight = c.getBoundingClientRect().height;

//number of bars/rectangles to be drawn
let n=10;

//calculating the width of each rectangle
let width = cWidth/n;
for(i=0;i<n;i++){
    draw(ctx,i*width,0,width,5*(i+1));
}
<!DOCTYPE html> 
<html> 
    <head> 
        <style> 
            #my-canvas{
                position:relative;
                background: coral;
                height:70vh;
                width:70vw;
                top:15vh;
                left:15vw;
    
            }
        </style> 
    </head> 
      
    <body> 
        <canvas id="my-canvas"></canvas>
        <script src="tempCodeRunnerFile.js"></script>
    </body> 
</html>

This is not giving all the the bars at all, sometimes it gives me 3 other times 5 or 8 and it changes with the browser and platform( JS-fiddle gives me 5 on chrome and 7.5 on firefox here is the code https://jsfiddle.net/8b9a4de5/) and on my computer it gives 2-3.

I have two questions:

  1. What is the problem here and how to solve the problem?
  2. Is there a better way to do this in vanilla javascript since i do not know any other libraries/frameworks

PS: Sorry if this is a repeat question i couldn't find any with my limited english.

Upvotes: 1

Views: 899

Answers (1)

julien.giband
julien.giband

Reputation: 2619

The CanvasRenderingContext2D object obtained with c.getContext("2d") uses the canvas' width and height attributes for its drawing surface dimensions. They're not defined in your code.

You could just add the following before drawing anything:

c.width = c.offsetWidth;
c.height = c.offsetHeight;

And then the problem's fixed.

I've simplified your js code a little here

window.addEventListener('load', _e => {
    //function to draw the rectangles
    function draw(ctx, x, y, b, l) {
        ctx.fillRect(x, y, b, l);
    }

    const c = document.querySelector("#my-canvas");
    c.width = c.offsetWidth;
    c.height = c.offsetHeight;

    //number of bars/rectangles to be drawn
    const n = 10;

    //calculating the width of each rectangle
    const width = c.width / n;
    console.log(`${n} rects on w=${c.width} => ${width}`)
    const ctx = c.getContext("2d");
    for (let i = 0; i < n; i++) {
        draw(ctx, i * width, 0, width, 5 * (i + 1));
    }
});
#my-canvas{
    position: relative;
    background: coral;
    height: 70vh;
    width: 70vw;
    top: 15vh;
    left: 15vw;
}
<!DOCTYPE html>
<html>
    <head></head>

    <body>
        <canvas id="my-canvas"></canvas>
    </body>

</html>

Edit: more explanations

I'm referring to MDN documentation here https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Basic_usage

Canvas has a default size (w*h) of 300x150. This is the also the pixel size of its rendering context, no matter what is set using CSS. If it differs, then the rendering will be scaled to fit the element's size.

In this example, I used Javascript to align the width and height attributes of the <canvas> to the DOM element's actual size on screen. I did it in a handler for window.load to be sure the CSS was rendered before the script was executed

Upvotes: 0

Related Questions