`context.textBaseline = 'middle'` is not working when trying to align text vertically in canvas

Viewed 572

Why in my simple example textBaseline = 'middle' is not working? Why my text is shifted to the top?

  const size = 100;
  const canvas = document.getElementById('canvas');
  
  canvas.width = size;
  canvas.height = size;
  
  const context = canvas.getContext('2d');

  context.font = "bold " + (size * 0.95) + "px Arial";
  context.fillStyle = 'blue';
  context.textAlign = "center";
  context.textBaseline = 'middle';

  context.fillText('SO', size / 2, size / 2);
canvas {
  border: 1px solid red;
}
<canvas id="canvas"></canvas>

2 Answers

Ok, after figuring out what the cap height is, I managed to find a solution which suits my needs(center uppercase characters vertically in the canvas). I calculated cap height ratio using this tool.

const size = 100;
const canvas = document.getElementById('canvas');
canvas.width = canvas.height = size;
const context = canvas.getContext('2d');

context.font = "bold " + (size) + "px Arial";
context.fillStyle = 'blue';
context.textAlign = "center";
context.textBaseline = 'hanging';
const capHeightRatio = 0.72; // for Arail
context.fillText('SO', size / 2, (size - (size * capHeightRatio)) / 2);
canvas {
  border: 1px solid red;
}
<canvas id="canvas"></canvas>

I assume that you want to vertical align text in canvas

.Alignment in canvas is purely based on the x and y values. textBaseline will just align the text in the position specified near the y co-ordinate only.

Run this snippet to understand

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

const baselines = ['top', 'hanging', 'middle', 'alphabetic', 'ideographic', 'bottom'];
ctx.font = '36px serif';
ctx.strokeStyle = 'red';

baselines.forEach(function (baseline, index) {
  ctx.textBaseline = baseline;
  let y = 75 + index * 75;
  ctx.beginPath();
  ctx.moveTo(0, y + 0.5);
  ctx.lineTo(550, y + 0.5);
  ctx.stroke();
  ctx.fillText('Abcdefghijklmnop (' + baseline + ')', 0, y);
});
<canvas id="canvas" width="550" height="500"></canvas>

Reference

Related