1

I tried to declare the size of html canvas in css, rather than javascript, and this somehow causes the sizes and objects drawn with js to appear all weird. Here is my HTML code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Computing Animatie</title>
    <style>
        body {
            overflow: hidden;
            background-color: black;
            background-image: url('./pictures/project_bg.jpg');
            background-size: 1375px;
        }

        canvas {
            position: absolute;
            top: 0px;
            left: 0px;
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <canvas id="can"></canvas>
    <script src="animation.js"></script>
</body>
</html>

and here is my javascript code:

const can = document.getElementById('can');
const ctx = can.getContext('2d');

(function test(){
    ctx.beginPath();
    ctx.fillStyle = 'red';
    ctx.fillRect(100, 100, 50, 50);
    ctx.closePath();
})();

When i run this, the rectangle gets weirdly stretched. I hope anyone knows anything...

Coenicorn
  • 37
  • 1
  • 6
  • Change the canvas CSS property `position: relative;` – nad Mar 24 '21 at 12:20
  • If you're looking to dynamically resize the canvas without scaling issues, you'll have to do it with JS. You can create a `resize` event listener to detect the page width, then set the `width` and `height` attributes of the ``. Then redraw all the objects on it accordingly. CSS cannot set these attributes. – General Grievance Mar 24 '21 at 12:40
  • 1
    Here's a related question: https://stackoverflow.com/questions/1664785/resize-html5-canvas-to-fit-window – General Grievance Mar 24 '21 at 12:44

2 Answers2

0

You should set the height and width of the canvas in JavaScript instead of CSS. You can do this with window.innerWidth and window.innerHeight.

This is how your code should look like:

const can = document.getElementById('can');
const ctx = can.getContext('2d');

function myFunction() {
  can.width = window.innerWidth;
  can.height = window.innerHeight;
  ctx.beginPath();
  ctx.fillStyle = 'red';
  ctx.fillRect(100, 100, 50, 50);
  ctx.closePath();
}

(function test(){
    ctx.beginPath();
    ctx.fillStyle = 'red';
    ctx.fillRect(100, 100, 50, 50);
    ctx.closePath();
})();
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Computing Animatie</title>
    <style>
        body {
            overflow: hidden;
            background-color: black;
            background-image: url('./pictures/project_bg.jpg');
            background-size: 1375px;
        }

        canvas {
            position: absolute;
            top: 0px;
            left: 0px;
        }
    </style>
</head>
<body onresize="myFunction()">
    <canvas id="can"></canvas>
    <script src="animation.js"></script>
</body>
</html>

I only removed the height and width set in CSS and applied it in JavaScript.

Emil
  • 107
  • 2
  • 12
  • It absolutely does! The thing is, I was trying to do it in css because that way it naturally updates when the window is resized (for instance, when the console is opened/closed), which doesn't happen in javascript unless you add code which does that. Is there any way it works with css instead of javascript? – Coenicorn Mar 24 '21 at 18:39
  • I am pretty sure you can't do that in css as far as I know, but you can in JavasScript. I made some changes to the code in the answer to make it resize. I used the function onresize on the body. I also had to make it so your rectangle gets redrawn every time the window is resized, or else the rectangle would disappear. Hope this helps! – Emil Mar 24 '21 at 19:21
  • Wow, it sure does, I thought there would be an event regarding resizing, but now I know the name also! Very helpful dear sir :) – Coenicorn Mar 29 '21 at 11:03
-1

Defining width and height of canvas as a relative size 100% is generally a bad idea. You should set the attributes of canvas width and height in the markup to avoid this type of behaviour.

Christian
  • 3,503
  • 1
  • 26
  • 47
  • `is generally a bad idea` - why? – Mr T Mar 24 '21 at 12:30
  • 1
    @MrT Because the raster graphics are drawn to the canvas, then the CSS is applied, which causes scaling issues. – General Grievance Mar 24 '21 at 12:31
  • (sorry, beginner here) What is the markup? And what DO you suggest I do instead... – Coenicorn Mar 24 '21 at 12:32
  • @Calculuswhiz I get that. The way the answer has been worded is opening other questions (at least it did to me). – Mr T Mar 24 '21 at 12:34
  • Why should it be a bad idea?! – GucciBananaKing99 Mar 24 '21 at 12:35
  • Because scaling can lead to not wanted effects. – Christian Apr 08 '21 at 08:30
  • @MrT As said, to avoid the type of behavior, the opener of this question described ("the rectangle gets weirdly stretched"). I don't know what to elaborate more on this. And above is about the same thing, not to use any relative sizes. – Christian Apr 08 '21 at 09:07
  • @Christian I think if you would back up your saying `is generally a bad idea` with some sources, your answer would be fine. – Mr T Apr 08 '21 at 09:11
  • @Coenicorn Calculate your desired width and height and set it via JS. For example use a div around the canvas, let it stretch, getBoundingClientRect, set width and height on the canvas. Use a resize listener on the div (MutationObserver) or window. – Christian Apr 08 '21 at 09:12
  • @MrT The openere describes the weird behavior already. And the reason is relative sizing. What proof do you need? – Christian Jan 12 '22 at 21:18
  • @Coenicorn The markup is the HTML (Hyper Text Markup Language). – Christian Jan 12 '22 at 21:19