// Calculate the BBox of a text through an svg Element
function getTextBox(txt, x, y) {
var svg = document.createElementNS("http://www.w3.org/2000/svg", 'svg');
var text = document.createElementNS("http://www.w3.org/2000/svg", 'text');
// so we don't see the svg element in page
svg.style = 'position: absolute; z-index:-1; width:0; height: 0';
text.setAttribute('x', x || 0);
text.setAttribute('y', y || 0);
text.setAttribute('text-anchor', getAlignment(this.textAlign));
text.setAttribute('alignment-baseline', this.textBaseline);
text.style.font = this.font;
text.textContent = txt;
svg.appendChild(text);
document.body.appendChild(svg);
var box = text.getBBox();
document.body.removeChild(svg);
return box;
// convert CSS text-align notation to correpsonding SVG text-anchor
function getAlignment(css) {
return {
'left': 'start',
'right': 'end',
'center': 'middle'
}[css] || '';
}
}
// attach it to the proto so it's easier to grab context's current status
Object.defineProperty(CanvasRenderingContext2D.prototype, 'getTextBox', {get: function() {return getTextBox;}});
var x = 20,
y = 100;
var ctx = canvas.getContext('2d');
ctx.font = 'bolder italic 100px serif';
var txt = 'Right';
ctx.fillText(txt, x, y);
// red => ctx.measureText
var m_width = ctx.measureText(txt).width;
ctx.strokeStyle = 'red';
ctx.strokeRect(x, 0, m_width, y);
ctx.strokeStyle = 'green';
// green => svg.getBBox
var box = ctx.getTextBox(txt, x, y);
ctx.strokeRect(box.x, box.y, box.width, box.height);
<canvas id="canvas"></canvas>