gpt4 book ai didi

javascript - 如何使用 `italic` 字体样式测量文本宽度?

转载 作者:行者123 更新时间:2023-11-29 23:25:38 28 4
gpt4 key购买 nike

我正在使用 convas context measureText 来获取 Canvas 上我的文本的宽度。下面是代码:

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

const textWidth = ctx.measureText(text).width;

问题是,如果字体样式是italic,那么文本的右边就会越界。那是因为 measureText 没有考虑 italic。如何计算 italic 样式的文本宽度?

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

enter image description here

enter image description here

最佳答案

这是字体及其容器框的斜体渲染固有的问题。
我不是专家,不会扩展这个主题,这个主题已经在 Q/A 中处理过。关于 DOM + CSS。请注意,2DCanvas measureText 也存在同样的问题。

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

// Calculate the BBox of a text through an svg Element
function getTextBox(txt, x, y) {
var svg = document.createElementNS("http://www.w3.org/2000/svg", 'svg');
var text = document.createElementNS("http://www.w3.org/2000/svg", 'text');
// so we don't see the svg element in page
svg.style = 'position: absolute; z-index:-1; width:0; height: 0';
text.setAttribute('x', x || 0);
text.setAttribute('y', y || 0);
text.setAttribute('text-anchor', getAlignment(this.textAlign));
text.setAttribute('alignment-baseline', this.textBaseline);
text.style.font = this.font;
text.textContent = txt;
svg.appendChild(text);
document.body.appendChild(svg);
var box = text.getBBox();
document.body.removeChild(svg);
return box;

// convert CSS text-align notation to correpsonding SVG text-anchor
function getAlignment(css) {
return {
'left': 'start',
'right': 'end',
'center': 'middle'
}[css] || '';

}
}
// attach it to the proto so it's easier to grab context's current status
Object.defineProperty(CanvasRenderingContext2D.prototype, 'getTextBox', {get: function() {return getTextBox;}});


var x = 20,
y = 100;
var ctx = canvas.getContext('2d');
ctx.font = 'bolder italic 100px serif';
var txt = 'Right';
ctx.fillText(txt, x, y);
// red => ctx.measureText
var m_width = ctx.measureText(txt).width;
ctx.strokeStyle = 'red';
ctx.strokeRect(x, 0, m_width, y);
ctx.strokeStyle = 'green';
// green => svg.getBBox
var box = ctx.getTextBox(txt, x, y);
ctx.strokeRect(box.x, box.y, box.width, box.height);
<canvas id="canvas"></canvas>

关于javascript - 如何使用 `italic` 字体样式测量文本宽度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49475419/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com