我想使用JavaScript来计算字符串的宽度。如果不使用单行字体,这可能吗?
如果它不是内置的,我唯一的想法是为每个字符创建一个宽度表,但这是非常不合理的,特别是支持Unicode和不同的类型大小(以及所有浏览器)。
我想使用JavaScript来计算字符串的宽度。如果不使用单行字体,这可能吗?
如果它不是内置的,我唯一的想法是为每个字符创建一个宽度表,但这是非常不合理的,特别是支持Unicode和不同的类型大小(以及所有浏览器)。
当前回答
嘿,大家,我知道我来晚了一点,但我们开始吧
window.addEventListener("error",function(e){ alert(e.message); });
var canvas = new OffscreenCanvas(400, 50);
var ctx = canvas.getContext("2d");
ctx.font = "16px Ariel"; //this can be dynamic using getComputedStyle
const chars = ["a","b","c","d","e","f"," "," "];
const charWidths = new Map();
while(chars.length > 0){
var char = chars.shift();
var wide = ctx.measureText(char).width;
charWidths.set(char,wide);
}
然后你可以用它来做如下的事情:
var pixelWidth = charWidths.get("0");
//fyi css properties like letter-spacing need to be accounted for
其他回答
对于任何一个在那里使用React和/或Typescript…
试试这个Codepen!
export default function App() {
const spanRef = useRef<HTMLSpanElement>(null);
const [textWidth, setTextWidth] = useState(0);
const getTextWidthInPixels = (ref: HTMLSpanElement) =>
ref.getBoundingClientRect().width;
useEffect(() => {
setTextWidth(getTextWidthInPixels(spanRef.current!));
}, [spanRef]);
return (
<div className="App">
<span
ref={spanRef}
contentEditable
suppressContentEditableWarning
onInput={() => setTextWidth(getTextWidthInPixels(spanRef.current!))}
>
Edit Me!!!
</span>
{`textWidth: ${textWidth}px`}
</div>
);
}
将文本包装在内联定位的元素(如<span>)中是个好主意。 useRef是React访问DOM元素的方式,在我们的例子中是<span> getBoundingClientRect可以获得任何DOM元素的总宽度。 contentteditable允许用户更改元素的内容…这有点不安全(React会抛出警告!) suppresscontentteditablewarning将帮助我们防止这些警告
这是我随手拼凑的一个例子。看来我们都达成共识了。
String.prototype.width = function(font) {
var f = font || '12px arial',
o = $('<div></div>')
.text(this)
.css({'position': 'absolute', 'float': 'left', 'white-space': 'nowrap', 'visibility': 'hidden', 'font': f})
.appendTo($('body')),
w = o.width();
o.remove();
return w;
}
使用它很简单:"a string".width()
**增加了空格:nowrap,因此宽度大于窗口宽度的字符串可以被计算。
嘿,大家,我知道我来晚了一点,但我们开始吧
window.addEventListener("error",function(e){ alert(e.message); });
var canvas = new OffscreenCanvas(400, 50);
var ctx = canvas.getContext("2d");
ctx.font = "16px Ariel"; //this can be dynamic using getComputedStyle
const chars = ["a","b","c","d","e","f"," "," "];
const charWidths = new Map();
while(chars.length > 0){
var char = chars.shift();
var wide = ctx.measureText(char).width;
charWidths.set(char,wide);
}
然后你可以用它来做如下的事情:
var pixelWidth = charWidths.get("0");
//fyi css properties like letter-spacing need to be accounted for
工作示例:http://jsfiddle.net/tdpLdqpo/1/
HTML:
<h1 id="test1">
How wide is this text?
</h1>
<div id="result1"></div>
<hr/>
<p id="test2">
How wide is this text?
</p>
<div id="result2"></div>
<hr/>
<p id="test3">
How wide is this text?<br/><br/>
f sdfj f sdlfj lfj lsdk jflsjd fljsd flj sflj sldfj lsdfjlsdjkf sfjoifoewj flsdjfl jofjlgjdlsfjsdofjisdojfsdmfnnfoisjfoi ojfo dsjfo jdsofjsodnfo sjfoj ifjjfoewj fofew jfos fojo foew jofj s f j
</p>
<div id="result3"></div>
JavaScript代码:
function getTextWidth(text, font) {
var canvas = getTextWidth.canvas ||
(getTextWidth.canvas = document.createElement("canvas"));
var context = canvas.getContext("2d");
context.font = font;
var metrics = context.measureText(text);
return metrics.width;
};
$("#result1")
.text("answer: " +
getTextWidth(
$("#test1").text(),
$("#test1").css("font")) + " px");
$("#result2")
.text("answer: " +
getTextWidth(
$("#test2").text(),
$("#test2").css("font")) + " px");
$("#result3")
.text("answer: " +
getTextWidth(
$("#test3").text(),
$("#test3").css("font")) + " px");
我为此写了一个小工具。也许对某些人有用。它不需要jQuery也能工作。
https://github.com/schickling/calculate-size
用法:
var size = calculateSize("Hello world!", {
font: 'Arial',
fontSize: '12px'
});
console.log(size.width); // 65
console.log(size.height); // 14
小提琴:http://jsfiddle.net/PEvL8/