maddogandnoriko
maddogandnoriko

Reputation: 1002

html5 canvas placing text too low?

I am playing with the element and found when I place text on the canvas it is too low.

  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');

  var imageObj = new Image();

  imageObj.onload = function() {
    context.drawImage(imageObj, 0, 0);
    context.textBaseline = 'top';
    context.font = 'normal 50px Arial';
    context.fillText("1AFG", 0, 0);
  };
  imageObj.src = 'http://planttagmaker.herobo.com/images/tag_templates/hibiscus_template.png';

The text is being placed 10-20 pixels below the top of the canvas. Can someone explain why? I am sure I am probably misunderstanding baseline. Essentially I want the text to be right at the top of the canvas. The X and Y coordinates are dynamic so just using subtracting 10 or 20 px from the y coordinate is not a viable solution.

Thanks again for your time, Todd

Upvotes: 1

Views: 982

Answers (2)

Kris
Kris

Reputation: 286

I had success by converting the font-size in pixels to points, which gives the pixel height of the text (http://www.html5canvastutorials.com/tutorials/html5-canvas-text-metrics/). I then used that value for the y-position, keeping the textBaseline at its default, alphabetic.

Here is the code:

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');

var imageObj = new Image();

imageObj.onload = function () {
    var fontSize = 50;
    context.drawImage(imageObj, 0, 0);
    context.font = 'normal ' + fontSize + 'px Arial';
    context.fillText("1AFG", 0, pixelsToPoints(fontSize));
};
imageObj.src = 'http://planttagmaker.herobo.com/images/tag_templates/hibiscus_template.png';

function pixelsToPoints(pixels) {
    return pixels * 72 / 96;
}

You can see an example at http://jsfiddle.net/5Mxez/, which should work as you scale the font-size.

Upvotes: 3

ThinkingStiff
ThinkingStiff

Reputation: 65341

It's placing it in the right place. Text does not take up the entire height defined by font size (i.e. it won't be 50px tall). The height of what is displayed is defined by line-height. So to make the text right at the top, you need to define a line-height smaller than your font size.

Normally this is done like this:

normal 50px/45px Arial

Where the second number is line-height. I see this in the specs for <canvas>, but I am not able to get it working.

But line-height is what you're after. Here's a demo that shows it working with a <div>. I'm still trying to get it working with a <canvas>.

Demo: jsFiddle

HTML:

<div id="myDiv">1AFG</div>
<canvas id="myCanvas"></canvas>

CSS:

#myDiv {
    background-image: url( 'http://placekitten.com/100' );
    width: 100px;
    height: 100px;
    font: 50px/40px Arial;
}

Script:

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');

var imageObj = new Image();

imageObj.onload = function() {
    context.drawImage(imageObj, 0, 0);
    context.textBaseline = 'top';
    context.font = '50px/40px Arial';
    context.fillText("1AFG", 0, 0);
};
imageObj.src = 'http://placekitten.com/100';

Upvotes: 1

Related Questions