Мне сложно разобраться: у меня есть эти функции, которые я использую для того, чтобы вписать текст в одну строку в заданные размеры.
function getFontSize(width, height, text, font, callback) {
var n = 100;
var ctxfont = n + 'px ' + font;
var result = measureTextHeight(ctxfont, text);
while (result.width > width || result.height > height) {
n--;
var ctxfont = n + 'px ' + font;
var result = measureTextHeight(ctxfont, text);
}
callback({
'width': result.width,
'height': result.height,
'size': n
});
}
function measureTextHeight(ctxFont, text) {
var width = 1500;
var height = 500;
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.save();
ctx.font = ctxFont;
ctx.clearRect(0, 0, width, height);
ctx.fillText(text, parseInt(width * 0.1, 10), parseInt(height / 2, 10));
ctx.restore();
document.body.appendChild(canvas);
var data = ctx.getImageData(0, 0, width, height).data;
var topMost = false;
var bottomMost = false;
var leftMost = false;
var rightMost = false;
for (var x = 0; x < width; x++) {
for (var y = 0; (y < height) && (!leftMost); y++) {
//console.log("x: %s y: %s index: %s", x,y, getAlphaIndexForCoordinates(x,y,width,height).toString() );
if (data[getAlphaIndexForCoordinates(x, y, width, height)] != 0) {
leftMost = x;
}
}
}
for (var y = 0; y < height; y++) {
for (var x = 0; (x < width) && (!topMost); x++) {
//console.log("x: %s y: %s index: %s", x,y, getAlphaIndexForCoordinates(x,y,width,height).toString() );
if (data[getAlphaIndexForCoordinates(x, y, width, height)] != 0) {
topMost = y;
}
}
}
for (var x = width - 1; x >= 0; x--) {
for (var y = height - 1; (y >= 0) && (!rightMost); y--) {
//console.log("x: %s y: %s index: %s", x,y, getAlphaIndexForCoordinates(x,y,width,height).toString() );
if (data[getAlphaIndexForCoordinates(x, y, width, height)] != 0) {
rightMost = x;
}
}
}
for (var y = height - 1; y >= 0; y--) {
for (var x = width - 1; (x >= 0) && (!bottomMost); x--) {
//console.log("x: %s y: %s index: %s", x,y, getAlphaIndexForCoordinates(x,y,width,height).toString() );
if (data[getAlphaIndexForCoordinates(x, y, width, height)] != 0) {
bottomMost = y;
}
}
}
canvas.remove();
return ({
width: (rightMost - leftMost) + 1
, height: (bottomMost - topMost) + 1
});
}
function getAlphaIndexForCoordinates(x, y, width, height) {
return (((width * 4 * y) + 4 * x) + 3);
}
Я передаю нужные размеры и шрифт в функцию getFontSize, и она возвращает реальную ширину и высоту текста, а также размер шрифта, необходимый для его выполнения. Таким образом, я могу нарисовать текст на холсте, используя функцию ctx.filltext (), насколько это возможно, и выровнять его по центру, основываясь на его ширине и высоте. Я не уверен, что это самый эффективный способ достижения желаемого результата, но он работает.
То, что я хочу сделать сейчас, это вместо того, чтобы сделать его однострочным, я могу установить заданную ширину и высоту для div, а затем, давая текст, он будет идеально соответствовать этим размерам, добавляя разрывы строк, если это необходимо, и по-прежнему возвращать реальная ширина и высота текста, чтобы я мог правильно нарисовать его на холсте, как эта скрипка: http://jsfiddle.net/vkgjrd3e/, хотя в скрипте у него все еще есть место в нижней части div.
То, чего я пытаюсь добиться, - это наилучшее соответствие текста, учитывая его шрифт и размеры контейнера; добавление разрывов строк при необходимости.