Why is my canvas not working properly?

Asked

Viewed 115 times

3

let canvas = document.querySelector('#canvas');
let ctx = canvas.getContext('2d');

ctx.fillStyle = 'green';
ctx.fillRect(10, 10, 50, 50);
#canvas {
    width: 500px;
    height: 500px;
    background: red;
}
<canvas id="canvas"></canvas>

In the code above I own a <canvas> 500px x 500px and on it a 50px x x 50px square, but what happens is that the square is larger than it should and is distorted because this is happening and how to fix it?

1 answer

1


This problem happens because, as specifications of <canvas>:

The canvas element has two attributes to control the size of the element bitmap: width and height. These attributes, when specified, must have values that are integers not valid negatives. Rules for parsing integers negative values must be used to obtain their numerical values. If a attribute is missing or if the analysis of its value returns a error, the default value should be used. The attribute width is standardized in 300 and the attribute height is standardized in 150.

In your case, it’s like taking the canvas 300x150 and stretching to stay 500x500. You can see this "in practice" by clicking on the example button below (Change CSS).

For your code to work correctly, simply specify the attributes height and width in HTML or via JS (Change attributes).

let canvas = document.querySelector('#canvas');
let ctx = canvas.getContext('2d');

ctx.fillStyle = 'green';
ctx.fillRect(10, 10, 50, 50);

function mudarCss() {
  canvas.style.height = "500px";
  canvas.style.width = "500px";
}

function mudarAtributos() {
  canvas.style.height = "";
  canvas.style.width = "";
  canvas.setAttribute('height', '100');
  canvas.setAttribute('width', '200');
  
  ctx.fillStyle = 'green';
  ctx.fillRect(10, 10, 50, 50);
}
#canvas {
  background-color: red;
}
<div>
    <button onClick="mudarCss()">Mudar CSS</button>
    <button onClick="mudarAtributos()">Mudar atributos</button>
</div>
<canvas id="canvas" width="500" height="500">

Note that if you modify this via Javascript, it is necessary to "redesign" what was in the <canvas>. The reason can be found in the specifications themselves, I am adapting below:

Whenever width and height content attributes are defined, removed, altered or redundantly with the value they already have have, the user agent must perform the corresponding action:

2d Follow the steps to define the dimensions of the bitmap with numerical values of width and height content attributes.

And step 1 of these steps in defining the dimensions of the bitmap is:

Redefines the render context for its default state.

And this redefinition, by definition means:

When the user’s agent must reset the render context to its default state, it must clear the stack of drawing states and all that this drawing state consists of the initial values.

  • But how would I leave in the width and height specified in the question, without being the default?

  • As I said, via HTML (specifying attributes width and height) or Javascript (function mudarAtributos()). Example of html: <canvas id="canvas" width="500" height="500">

  • But it’s not working with the above sizes.

  • I modified the Snippet. If you run it, it will start 500x500 correctly, what’s the problem in your case? You have removed the CSS that modifies the height and width?

  • Now it’s worked out, thank you! :)

  • Only another question because the fillStyle should come before the fillRect()?

  • The method fillRect() draws your "object". So what happens is that you are indicating the color before to draw, if you try to indicate later it will have already drawn and then the color will not be applied

  • True! makes sense kk but thank you so much again.

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.