How to avoid HTML Canvas auto-stretching
Asked Answered
K

5

28

I have the following piece of HTML:

<style type="text/css">
    #c{width:200px;height:500px}
</style>
<canvas id="c"></canvas>
<script type="text/javascript">
    var i = new Image();
    i.onload = function () {
        var ctx = document.getElementById('c').getContext('2d');
        ctx.drawImage(i, 0, 0);
    }
    i.width = i.height = 20; // actual size of square.png
    i.src = 'square.png';
</script>

The issue is that the drawn image is automatically stretched (resized) proportionally with the size of the canvas. I have tried using all available parameters (drawImage(i, 0, 0, 20, 20, 0, 0, 20, 20)) and that didn't help.

What is causing my drawing to stretch and how can I prevent that?

Thanks,
Tom

Koweit answered 23/5, 2010 at 14:8 Comment(2)
Found my answer #2588681Koweit
Promote your comment to a real answer for the good of the next person to come looking, and I'll give you a cookie (or an upvote, whichever I have on me).Trahan
S
38

You need the width and height attributes in the canvas element. They specify the coordinate space for the canvas. Apparently, it defaults to a canvas of a 2:1 aspect ratio, which your CSS is skewing into a square.

Salts answered 23/5, 2010 at 14:14 Comment(0)
A
28

It's worth noting that the Width and Height attributes of canvas are not like the old school <img> width and height attributes. They are not a substitute for CSS. They specify how many pixels the pixel buffer in the canvas itself should have, and if you don't apply a size to it with css, css will imply it's size from that shape of that pixel buffer. Setting the element's size in css does not set the size of the pixel buffer - it resizes it. From a CSS perspective, a <canvas> is entirely the same thing as an <img>.

Aquitaine answered 27/10, 2010 at 23:57 Comment(0)
D
11

Ok, a little bit simplier (and lighter) than JQuery is .. JAVASCRIP ITSELF of course !

If you need to change dynamicaly your canvas dimensions, just use:

document.getElementById('yourcanvasid').setAttribute('width', aWidth);
document.getElementById('yourcanvasid').setAttribute('height', aHeight);
Donnetta answered 5/2, 2013 at 14:45 Comment(1)
document.getElementById('yourcanvasid').width = aWidth also does thisJunno
P
8

If you're using JQuery, you shouldn't set the CSS (as the commenters above mentioned). You need to set the attribute so:

$("canvas").attr('width', aWidth);
$("canvas").attr('height', aHeight);

works great.

Poleaxe answered 5/8, 2012 at 10:10 Comment(0)
K
-1

I found it easier to just put a while loop waiting for timeout within my animation loop, For example:

function animate() {
    c.clearRect(0, 0, window.innerWidth, window.innerHeight);
    ryuji.draw();
    ryuji.update();
    let now = Date.now();
    then = now + (1000 / fps);
    while (Date.now() < then) {

    }
    requestAnimationFrame(animate);
}
Khania answered 7/6, 2017 at 17:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.