我正在寻找一种更有效的方法来限制/设置Raphael中的文本。
我的文字可以写在一个盒子里。该文本应该居中(基于如果用户想要左/右移动文本可能会改变的数字),文本不能超出论文的界限。
这就是我现在所做的,而且性能不明显
// Build a path
var path = this.paper.print(x, x, text, font, size, 'middle')
// Center line by getting bounding box and shifting to half of that
var bb = path.getBBox()
path.transform('...T' + [-bb.width / 2, 0])
// Compare paper size vs bb
// if it goes beyond I adjust X and Y accordingly and redo the above
理想情况下,我想在打印之前预测文本的大小 - 我不确定这是否可行,因为它可能与字体有关。我已经找了一个禁止文字的命令,却看不到一个?
另一个想法是创建某种不会在屏幕上打印的影子纸,并在我呈现给用户之前使用它来确定尺寸。我不知道滞后在哪里 - 如果它在屏幕上呈现良好但如果它在创建svg的一般逻辑中那么那将不会有帮助。
我很感激建议
答案 0 :(得分:0)
您可以使用opentype.js来测量文本,也可以使用Path.toPathData方法获取svg路径。不需要cufon编译的js字体。 对于文本度量,在DOM中的某处创建一个canvas元素。
<canvas id="canvas" style="display: none;"></canvas>
此函数将加载文本并计算宽度,高度
function measureText(text, font_name, size) {
var dfd = $.Deferred();
opentype.load('/fonts/' + font_name + '.ttf', function (err, font) {
if (err) {
dfd.reject('Font is not loaded');
console.log('Could not load font: ' + err);
} else {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
var tmp_path = font.getPath(text, 100, 100, size);
tmp_path.draw(ctx); // Draw path on the canvas
var ascent = 0;
var descent = 0;
var width = 0;
var scale = 1 / font.unitsPerEm * size;
var glyphs = font.stringToGlyphs(text_string);
for (var i = 0; i < glyphs.length; i++) {
var glyph = glyphs[i];
if (glyph.advanceWidth) {
width += glyph.advanceWidth * scale;
}
if (i < glyphs.length - 1) {
var kerningValue = font.getKerningValue(glyph, glyphs[i + 1]);
width += kerningValue * scale;
}
ascent = Math.max(ascent, glyph.yMax);
descent = Math.min(descent, glyph.yMin);
}
return dfd.resolve({
width: width,
height: ascent * scale,
actualBoundingBoxDescent: descent * scale,
fontBoundingBoxAscent: font.ascender * scale,
fontBoundingBoxDescent: font.descender * scale
});
}
});
return dfd.promise();
},
然后使用此函数获取文本尺寸:
$.when(measureText("ABCD", "arial", 48)).done(function(res) {
var height = res.height,
width = res.width;
...
});