Anthony Elliott Anthony Elliott - 4 months ago 17
HTML Question

How put percentage width into html canvas (no css)

I have an image and have overlaid a canvas on top of it so that I can draw 'on' the image without modifying the image itself.

<div class="needPic" id="container">
<img id="image" src=""/>
<!-- Must specify canvas size in html -->
<canvas id="sketchpad" width="70%" height="60%">Sorry, your browser is not supported.</canvas>
</div>


I can specify the width and height in pixels in the above canvas line and it works great, however I need this to dynamically sized based on screen size (has to work on small smartphones as well as tablets). When I try to put the percentage in as shown above, it interprets it as pixels. Thus, the canvas will be 70px wide and 60 px tall.

For some reason I can't size the canvas in the CSS so looks like I have to do it in the html. To clarify, when I try to specify the canvas dimensions in the CSS they don't actually change the size of the canvas. It seems as if the image is interfering in some way.

Any help would be appreciated.

Update: If I do
<canvas id="sketchpad" style="width:70%;height:60%;"></canvas>
then it defaults to a height of 150px and width of 300px (regardless of device) and then stretches the canvas to fit the div. I set the div to be 60% width and 60% height in the css, thus the canvas stretches to fill that. I confirmed this by logging the canvas.width vs canvas.style.width -- canvas.width was 300px and canvas.sytle.width was '60%' (from the parent div). This causes some really strange pixelation and drawing effects...

K3N K3N
Answer

You need to set the size of the canvas in pixels or you will not only reduce the quality of its content but if you want to draw on it the mouse-coordinates will be off as well. Don't use CSS to scale canvas if you're gonna use it interactively.

I would recommend you adjust your image then adopt the canvas to whatever size the image is. You can do this by using getComputedStyle(element) which gives you whatever size the element is set to in pixels.

After image's onload (as you need to be sure the image is actually loaded to get its size) or later if you change the image (CSS) size on the go, you can do this:

/// get computed style for image
var img = document.getElementById('myImageId');
var cs = getComputedStyle(img);

/// these will return dimensions in *pixel* regardless of what
/// you originally specified for image:
var width = parseInt(cs.getPropertyValue('width'), 10);
var height = parseInt(cs.getPropertyValue('height'), 10);

/// now use this as width and height for your canvas element:
var canvas = document.getElementById('myCanvasId');

canvas.width = width;
canvas.height = height;

Now the canvas will fit image but with canvas pixel ratio 1:1 to help you avoid problems when you're gonna draw on the canvas. Otherwise you will need to convert/scale the mouse / touch coordinates as well.