我编写了一个实用程序函数来获取字符串的像素宽度。我希望该函数可以选择在特定元素上使用字体集,因此无论该元素的样式是什么,我都会自动使用该字体进行测量。
问题是Firefox不想告诉我元素使用的是什么字体。以下代码适用于其他浏览器:
wget https://atom.io/download/deb && dpkg -i deb
问题是export function getTextWidth(items: string | string[], font: string | HTMLElement, fallbackFont?: string): number {
const canvas = ((getTextWidth as any).canvas as HTMLCanvasElement ||
((getTextWidth as any).canvas = document.createElement('canvas') as HTMLCanvasElement));
const context = canvas.getContext('2d');
let maxWidth = 0;
if (typeof font === 'string')
context.font = (font ? font : 'normal 12px sans-serif');
else if (typeof font === 'object') {
const elementFont = window.getComputedStyle(font).getPropertyValue('font');
if (elementFont)
context.font = elementFont;
else if (fallbackFont)
context.font = fallbackFont;
else
context.font = 'normal 12px sans-serif';
}
if (!Array.isArray(items))
items = [items];
for (const item of items) {
const width = context.measureText(item).width;
maxWidth = Math.max(maxWidth, width);
}
return maxWidth;
}
在Firefox上返回一个空字符串,因此我无法将window.getComputedStyle(font).getPropertyValue('font')
设置为匹配的字体,以便context
正常工作。
我在我的函数measureText
中添加了可选参数,所以我可以传递一个显式字体,但这不是一个非常令人满意的解决方案。
答案 0 :(得分:0)
必须以这种方式获取字体有点痛苦,但我发现Firefox将分别返回元素当前字体的各个方面,例如font-size
和font-family
。它们都可以被查询并组装成一个字体字符串:
if (typeof font === 'string')
context.font = (font ? font : 'normal 12px sans-serif');
else if (typeof font === 'object') {
let style = window.getComputedStyle(font);
let elementFont = style.getPropertyValue('font');
if (elementFont)
context.font = elementFont;
else {
const fontStyle = style.getPropertyValue('font-style');
const fontVariant = style.getPropertyValue('font-variant');
const fontWeight = style.getPropertyValue('font-weight');
const fontSize = style.getPropertyValue('font-size');
const fontFamily = style.getPropertyValue('font-family');
elementFont = (fontStyle + ' ' + fontVariant + ' ' + fontWeight + ' ' + fontSize + ' ' + fontFamily)
.replace(/ +/g, ' ').trim();
if (elementFont)
context.font = elementFont;
else if (fallbackFont)
context.font = fallbackFont;
else
context.font = 'normal 12px sans-serif';
}
}
答案 1 :(得分:0)
这是我用来从getComputedStyle()返回的对象中安全地检索.font属性的函数。已在Chrome / Safari / Firefox中测试。请注意,我还将Firefox的字体扩展百分比值转换为关键字,因为百分比值似乎无法与Canvas一起使用,例如measureText()。
function getFontFromComputedStyle (computedStyle) {
let font = computedStyle.font;
// Firefox returns the empty string for .font, so create the .font property manually
if (font === '') {
// Firefox uses percentages for font-stretch, but Canvas does not accept percentages
// so convert to keywords, as listed at:
// https://developer.mozilla.org/en-US/docs/Web/CSS/font-stretch
let fontStretchLookupTable = {
'50%': 'ultra-condensed',
'62.5%': 'extra-condensed',
'75%': 'condensed',
'87.5%': 'semi-condensed',
'100%': 'normal',
'112.5%': 'semi-expanded',
'125%': 'expanded',
'150%': 'extra-expanded',
'200%': 'ultra-expanded'
};
// If the retrieved font-stretch percentage isn't found in the lookup table, use
// 'normal' as a last resort.
let fontStretch = fontStretchLookupTable.hasOwnProperty(computedStyle.fontStretch)
? fontStretchLookupTable[computedStyle.fontStretch]
: 'normal';
font = computedStyle.fontStyle
+ ' ' + computedStyle.fontVariant
+ ' ' + computedStyle.fontWeight
+ ' ' + fontStretch
+ ' ' + computedStyle.fontSize
+ '/' + computedStyle.lineHeight
+ ' ' + computedStyle.fontFamily;
}
return font;
}
用法:
getFontFromComputedStyle(getComputedStyle(elem))