Я пытаюсь создать несколько кнопок с текстом в javascript, используя библиотеку Rahpael. Я хотел бы знать размер стилизованного текста, прежде чем рисовать, чтобы избежать этого, чтобы я мог создать правильный фон (кнопка). Также я хотел бы избежать рисования текста за пределами холста/бумаги (позиция текста - это положение его центра).
Я могу использовать метод Raphaels getBBox(), но мне нужно создать (нарисовать) текст на первом месте, чтобы сделать это. Поэтому я рисую текст, чтобы получить размер, чтобы он мог нарисовать его в правильном положении. Это уродливо. Поэтому я ищу общий метод оценки метрик стилизованного текста для заданного шрифта, размера шрифта, семейства...
Есть возможность сделать это, используя холст HTML5 http://www.html5canvastutorials.com/tutorials/html5-canvas-text-metrics/, но Raphael не использует холст. Есть ли возможность получить текстовые показатели с помощью Raphael или простого Javascript?
Я знаю, что это кажется небрежным, но у вас не должно возникнуть проблемы с рисованием текста, его измерением, затем рисованием кнопки и перемещением метки. Чтобы быть в безопасности, просто снимите его с экрана:
var paper = Raphael(0, 0, 500, 500);
var text = paper.text(-100, -100, "My name is Chris");
//outputs 80 12
console.log(text.getBBox().width, text.getBBox().height);
Если это ДЕЙСТВИТЕЛЬНО оскорбляет ваши чувства, однако - и я пойму! - вы можете легко создать объект, чтобы запомнить ширину каждого символа для данного шрифта:
var paper = Raphael(0, 0, 500, 500),
alphabet = "abcdefghijklmnopqrstuvwxyz";
font = "Arial",
charLengths = {},
ascii_lower_bound = 32,
ascii_upper_bound = 126;
document.getElementById("widths").style.fontFamily = font;
for (var c = ascii_lower_bound; c <= ascii_upper_bound; c += 1) {
var letter = String.fromCharCode(c);
var L = paper.text(-50, -50, letter).attr("font-family", font);
charLengths[letter] = L.getBBox().width;
}
//output
for (var key in charLengths) if (charLengths.hasOwnProperty(key)) {
var row = document.createElement("tr");
row.innerHTML = "<td>" + key + "</td><td>" + charLengths[key] + "</td>";
document.getElementById("widths").appendChild(row);
}
Есть несколько способов разрезать эту кошку. Два очевидных легко прийти на ум.
Внештатная техника линейки
Этот самый простой. Просто создайте текстовый элемент за пределами canvas viewBox, заполните его информацией и текстом шрифта и измерьте его.
// set it up -- put the variable somewhere globally or contextually accessible, as necessary
var textRuler = paper.text( -10000, -10000, '' ).attr( { fill: 'none', stroke: 'none' } );
function getTextWidth( text, fontFamily, fontSize )
{
textResult.attr( { text: text, 'font-family': fontFamily, 'font-size': fontSize } );
var bbox = textResult.getBBox();
return bbox.width;
}
Это не изящно ни с какой протяженностью воображения. Но вам это потребуются с относительно небольшими накладными расходами и без сложностей.
Cufonized Font
Если бы вы захотели использовать шрифт cufonized, вы могли бы рассчитать размер данной текстовой строки без необходимости связываться с DOM вообще. На самом деле это, вероятно, примерно то, что делает элемент canvas measureText
за кулисами. Учитывая импортированный шрифт, вы просто сделаете что-то вроде этого (подумайте об этом протокоде!)
// font should be the result of a call to paper.[getFont][2] for a cufonized font
function getCufonWidth( text, font, fontSize )
{
var textLength = text.length, cufonWidth = 0;
for ( var i = 0; i < textLength; i++ )
{
var thisChar = text[i];
if ( ! font.glyphs[thisChar] || ! font.glyphs[thisChar].w )
continue; // skip missing glyphs and/or 0-width entities
cufonWidth += font.glyphs[thisChar].w / font.face['units-per-em'] * fontSize;
}
return cufonWidth;
}
Мне очень нравится работать с cufonized fonts - с точки зрения их способности к анимации интересными способами, они гораздо полезнее, чем текст. Но этот второй подход может быть более сложным, чем вам нужно или хотите.