4

From what I understand about canvas ,

  1. Define a board with size
  2. Then we only can draw on it

But I am trying to achieve

  1. Draw the text
  2. Measure the text size
  3. Define the canvas size

HTML

<div style="background:grey;display:inline-block;">
   <canvas id="samplecanvas" style="background:red;"></canvas>
</div>

Javascript

var c = document.getElementById("samplecanvas");
var ctx = c.getContext("2d");
ctx.font = "30px Arial";
ctx.fillText("Hello World" ,10, 50);

Is there any way to measure the text size and dynamically adjust the canvas size?

This is my demostration , I define the canvas without any size and draw on it , but the canvas size is big and have many extra white space.I am trying to make the div and canvas expand accordingly to the content size

http://jsfiddle.net/5877a4aq/2/

Leon Armstrong
  • 1,285
  • 3
  • 16
  • 41
  • This is a link to my working demo www.nazarttpreview.com/mini-test/ , I need to wrap a div around a canvas and make it resizable , I have tried many css to remove it but failed , hope this do help you understand more why I am doing this – Leon Armstrong Jul 04 '15 at 18:04
  • 1
    You could use [measureText](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/measureText) and then only after set the width of your canvas, then redraw the text, since the resizing will clear your canvas. Ps: measureText is only able to get the width of text, to also get the height, you can refer to [this answer](http://stackoverflow.com/questions/17627893/use-javascript-to-get-maximum-font-size-in-canvas/17631567#17631567) – Kaiido Jul 05 '15 at 03:16
  • @Kaiido Thanks for your help , I have figure how to measure text using this http://jsfiddle.net/philfreo/MqM76/ , and height I can use font size and number of newline to calculate , and now I think I have properly create canvas that fit my content , But I can't draw text properly on it , do you have any clue? You may look into www.nazarttpreview.com/mini-test/ line 127 – Leon Armstrong Jul 05 '15 at 03:52
  • 1
    @Kaiido Thanks ! I got it to work with http://stackoverflow.com/questions/17627893/use-javascript-to-get-maximum-font-size-in-canvas/17631567#17631567 – Leon Armstrong Jul 05 '15 at 04:37
  • If you're using this for font substitution I highly recommend you use webfonts instead. Better SEO and usability and all that jazz – Jan Jul 07 '15 at 01:18

2 Answers2

4

So here is a function to do this, which uses an approximation for the line height and which will need some adjustements if you need more than one line of text.

Note that you don't have to draw the text before you measureText(), but when you change the canvas' height and width, its context will reset (clear). So you then need to reset its font property then draw your text.

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

function drawTextAndResize(text, fontSize, font){
  text = text || "hello world";
  fontSize =  fontSize || 48;
  font = font || "serif";
  // First we set the font to the context
  ctx.font = fontSize + 'px '+ font;
  // We set the size of our canvas accordingly to the width of our text
  canvas.width = ctx.measureText(text).width;
  // 1.3*fontSize is an approximation of the line height, for a complete way to get the height, refer to this answer : http://stackoverflow.com/a/17631567/3702797
  canvas.height = fontSize*1.3;
  // Since our context has been reset, we have to reset its font as well
  ctx.font = fontSize + 'px '+ font;
  // Finally we draw the text, approximately vertically centered
  ctx.fillText(text, 0,canvas.height/1.3);
  }

drawTextAndResize("This is some text", 32, "arial");
setTimeout(drawTextAndResize, 4000);
canvas{border:1px solid}
<canvas/>
Kaiido
  • 123,334
  • 13
  • 219
  • 285
-1

Just for Reference:

1:

ctx.fillText(<text>, <pos-x>, <pos-y>);

2:

var x = ctx.measureText(<text>).width;

3:

ctx.canvas.width = x * <scale>;
ctx.canvas.height = x * <scale>;
user2072826
  • 528
  • 1
  • 5
  • 12
  • 2
    No, **1** should be last and `measureText()` returns a TextMetrics object with a `width` property, but no height so you can't rely on this to calculate the height of the canvas and `x*scale` will return `NaN` – Kaiido Jul 07 '15 at 03:32