Search code examples
javascripthtmlcanvashtml5-canvas

HTML Canvas : text doesn't appear at center of circle


I am trying to insert a text at the middle of a circle drawn with HTML Canvas, but its always appearing a little above the center. (I tried baseline, but it didn't work). I don't want to hard-coded the fillText co-ordinates.

var canvas = document.getElementById('completionStatus');

var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 200;

context.beginPath();
context.fillStyle = '#B8D9FE';
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fill();
context.strokeStyle = '#ffffff';
context.font = 'bold 130pt Calibri';
context.textAlign = 'center';
context.fillStyle = 'white';
context.fillText('70%', centerX, centerY);
context.stroke();
<canvas id="completionStatus" width="400" height="400"></canvas>

Here's a fiddle : http://jsfiddle.net/wku0j922/2/


Solution

  • Simply use the textBaseline property on the context. When both textBaseline is set to middle and textAlign is set to center you can place it exactly at the position of your circle center and it will be centered across the board.

    var c1 = document.getElementById('c1');
    var c2 = document.getElementById('c2');
    var ct1 = c1.getContext('2d');
    var ct2 = c2.getContext('2d');
    
    c1.width = c2.width = 200;
    c1.height = c2.height = 200;
    
    ct1.font = ct2.font = '20px Helvetica';
    
    ct1.textAlign = ct2.textAlign = 'center';
    ct2.textBaseline = 'middle';
    
    ct1.beginPath();
    ct1.arc(100,100,99,0,Math.PI * 2);
    ct1.stroke();
    ct1.closePath();
    
    ct2.beginPath();
    ct2.arc(100,100,99,0,Math.PI * 2);
    ct2.stroke();
    ct2.closePath();
    
    ct1.fillText('textBaseline not set', 100, 100);
    ct2.fillText('textBaseline middle', 100, 100);
    <canvas id="c1"></canvas>
    <canvas id="c2"></canvas>

    Here is it implemented in your snippet:

    var canvas = document.getElementById('completionStatus');
    
    var context = canvas.getContext('2d');
    var centerX = canvas.width / 2;
    var centerY = canvas.height / 2;
    var radius = 200;
    
    context.beginPath();
    context.fillStyle = '#B8D9FE';
    context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
    context.fill();
    context.strokeStyle = '#ffffff';
    context.font = 'bold 130pt Calibri';
    context.textAlign = 'center';
    context.textBaseline = 'middle';
    context.fillStyle = 'white';
    context.fillText('70%', centerX, centerY);
    context.stroke();
    <canvas id="completionStatus" width="400" height="400"></canvas>

    Docs: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline