30

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...

Anthony Elliott
  • 2,941
  • 5
  • 29
  • 42
  • Maybe you can add CSS in your html element, like : ``. – Fabien Sa Sep 08 '13 at 01:10
  • @FabSa, I just tried that and it did something, but not as expected. See update above. – Anthony Elliott Sep 08 '13 at 01:24
  • as you have noticed, when you set the style, the browser just stretches/shrinks the canvas but does not change the dots per inch value for the canvas. you need to set the dimensions (along with the style) from script. you can take a look at a impactjs doc: http://impactjs.com/documentation/impact-on-mobile-platforms (see the "Always Render in the Native Resolution" section, it might help you to better understand the problem). – akonsu Sep 08 '13 at 03:49

5 Answers5

30

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.

John Smith
  • 81
  • 7
  • 2
    FYI, if using jQuery you cannot use `width()` and `height()` as that will just set the CSS style. You need to use `.attr('width', 10)` and `.attr('height', 10)`. – Joshua Pinter Jun 06 '15 at 23:46
  • 1
    Haven't heard about getComputedStyle before. It works like a charm, thank you very much. If only I colud upvote more than once. – tafa May 12 '16 at 22:23
  • Thanks! this post was very efficient for me :) – Ori Arbes Aug 28 '19 at 18:49
11

Resize Your canvas to fit Window/Browser Size :

<script>
function resizeCanvas() {
    var canvs = document.getElementById("snow");
    canvs.width = window.innerWidth;
    canvs.height = window.innerHeight;
}
</script>

<body onload="resizeCanvas();">
    <canvas id="snow" ></canvas>
</body>
Irshad Khan
  • 5,670
  • 2
  • 44
  • 39
6

Set the canvas height to the window's innerHeight and the width to the window's innerWidth:

canvas.height = window.innerHeight;
canvas.width = window.innerWidth;

If you want a specific percentage, multiply them by the percentage. Example:

//25% of width and height
canvas.height = window.innerHeight * 0.25;
canvas.width = window.innerWidth * 0.25;
//And so on for other percentages
C12
  • 79
  • 1
  • 2
  • 7
0

You could resize the canvas to fit the width of the image in pixels via JavaScript. Since you're using a canvas you are probably using JavaScript already so this should not be a problem.

See Resize HTML5 canvas to fit window, although not identical, a similar solution should work.

Community
  • 1
  • 1
Jochem Kuijpers
  • 1,770
  • 3
  • 17
  • 34
-2

Instead of using width="", use style="" as such

<canvas id="sketchpad" style="width:70%; height:60%" >Sorry, your browser is not supported.</canvas>

EDIT:

<div class="needPic" id="container" style="width:70%; height:60%; min-width:__px; min-height:__px">
    <img id="image" src="" style="width:70%; height:60%; min-width:__px; min-height:__px"/>
    <!-- Must specify canvas size in html -->
    <canvas id="sketchpad" style="width:70%; height:60%; min-width:__px; min-height:__px>Sorry, your browser is not supported.</canvas>
</div>
Harrison Gibbs
  • 143
  • 2
  • 9
  • I just tried that and it did *something*, but not as expected. See update above. – Anthony Elliott Sep 08 '13 at 01:25
  • @Xenocideae try setting the minwidth of your div lower: style="min-width:75px; min-height:75px" or whatever you wish the minimum to be – Harrison Gibbs Sep 08 '13 at 01:32
  • thx for your help - I set the min-width and min-height to 60% for the div and canvas in the css then set the canvas to `style="width:70%; height:60%"` in my html. It actually fixed another issue but the canvas still says it is 150x300 px and stretches to fit the much larger image. – Anthony Elliott Sep 08 '13 at 01:44
  • @Xenocideae What if you set the img with the same min and % settings? – Harrison Gibbs Sep 08 '13 at 01:51
  • I used your code and set all min-width/height to 400px. The other elements on my screen moved accordingly but the canvas still says it is 150x300 px and stretches to fit the much larger image. – Anthony Elliott Sep 08 '13 at 02:03