Javascript 如何使用“斜体”字体样式测量文本宽度?

Javascript 如何使用“斜体”字体样式测量文本宽度?,javascript,html5-canvas,html2canvas,Javascript,Html5 Canvas,Html2canvas,我正在使用convas contextmeasureText获取画布上文本的宽度。代码如下: ctx.fillStyle = color; ctx.fontWeight = FONT_WEIGHT; ctx.font = `bolder italic ${fontsize}px`; const textWidth = ctx.measureText(text).width; 问题是,如果字体样式为斜体,则文本右侧将超出边界。这是因为measureText没有考

我正在使用convas context
measureText
获取画布上文本的宽度。代码如下:

    ctx.fillStyle = color;
    ctx.fontWeight = FONT_WEIGHT;
    ctx.font = `bolder italic ${fontsize}px`;

    const textWidth = ctx.measureText(text).width;
问题是,如果字体样式为斜体,则文本右侧将超出边界。这是因为
measureText
没有考虑
italic
。如何计算
italic
样式的文本宽度

下面是convas上斜体字体的两个屏幕截图。第一个是没有斜体的文本,而第二个是斜体的文本。你可以看到第二个有点越界


首先设置
ctx.font
ctx.measureText
的结果基于上下文的当前字体,与您在绘图时看到的字体相同。执行
ctx.fillText
检查字体设置是否正确,我发现语法很容易出错。

您需要将文本加载到隐藏的HTML div中并获得计算的宽度。

这是字体及其容器框的斜体呈现固有的问题。
我不是一个专家,也不会在这个主题上做进一步的讨论,这已经在关于DOM+CSS的这篇文章中讨论过了。只需注意,2DCanvas
measureText
也存在同样的问题

我能想到的唯一解决办法是使用svg元素,它通过
getBBox
方法提供了更好的图形边界框表示

//通过svg元素计算文本的BBox
函数getTextBox(txt,x,y){
var svg=document.createElements(“http://www.w3.org/2000/svg“,‘svg’”;
var text=document.createElements(“http://www.w3.org/2000/svg“,‘文本’);
//所以我们在页面中看不到svg元素
svg.style='位置:绝对;z索引:-1;宽度:0;高度:0';
setAttribute('x',x | | 0);
setAttribute('y',y | | 0);
text.setAttribute('text-anchor',getAlignment(this.textAlign));
text.setAttribute('alignment-baseline',this.textBaseline);
text.style.font=此.font;
text.textContent=txt;
appendChild(文本);
document.body.appendChild(svg);
var-box=text.getBBox();
document.body.removeChild(svg);
返回框;
//将CSS文本对齐符号转换为对应的SVG文本锚定
函数getAlignment(css){
返回{
“左”:“开始”,
“右”:“结束”,
“中间”:“中间”
}[css]| |'';
}
}
//将其附加到proto,以便更容易获取上下文的当前状态
defineProperty(CanvasRenderingContext2D.prototype,'getTextBox',{get:function(){return getTextBox;}}});
var x=20,
y=100;
var ctx=canvas.getContext('2d');
ctx.font=‘粗体斜体100px衬线’;
var txt='右';
ctx.fillText(txt,x,y);
//红色=>ctx.measureText
var m_width=ctx.measureText(txt).width;
ctx.strokeStyle=‘红色’;
ctx.冲程(x,0,m_宽度,y);
ctx.strokeStyle='绿色';
//绿色=>svg.getBBox
var-box=ctx.getTextBox(txt,x,y);
ctx.strokeRect(方框x、方框y、方框宽度、方框高度)

在调用
ctx.font
之前,我已经做了
ctx.measureText
,并且我已经更新了我的答案。DOM受到了与此相关的相同限制:这真的很酷,在很多浏览器中都能很好地工作。我已经使用它很长时间了,但我真的很不幸地发现有一个平台不起作用:(.它在网络视图中的iOS 13+上不起作用(它在iOS的早期版本中起作用)。你知道为什么它不再起作用了,或者我能做些什么吗?