ฉันชอบ "ความคิดเพียงอย่างเดียว" ของคุณในการทำแผนที่ความกว้างตัวอักษรแบบคงที่! มันใช้งานได้ดีสำหรับวัตถุประสงค์ของฉัน บางครั้งด้วยเหตุผลด้านประสิทธิภาพหรือเนื่องจากคุณไม่สามารถเข้าถึง DOM ได้อย่างง่ายดายคุณอาจต้องการให้เครื่องคิดเลขแบบสแตนด์อโลนแบบแฮ็กที่รวดเร็วปรับเทียบเป็นแบบอักษรเดียว ดังนั้นนี่คือหนึ่งปรับเทียบกับ Helvetica; ผ่านสตริงและ (เป็นทางเลือก) ขนาดตัวอักษร:
function measureText(str, fontSize = 10) {
const widths = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.2796875,0.2765625,0.3546875,0.5546875,0.5546875,0.8890625,0.665625,0.190625,0.3328125,0.3328125,0.3890625,0.5828125,0.2765625,0.3328125,0.2765625,0.3015625,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.2765625,0.2765625,0.584375,0.5828125,0.584375,0.5546875,1.0140625,0.665625,0.665625,0.721875,0.721875,0.665625,0.609375,0.7765625,0.721875,0.2765625,0.5,0.665625,0.5546875,0.8328125,0.721875,0.7765625,0.665625,0.7765625,0.721875,0.665625,0.609375,0.721875,0.665625,0.94375,0.665625,0.665625,0.609375,0.2765625,0.3546875,0.2765625,0.4765625,0.5546875,0.3328125,0.5546875,0.5546875,0.5,0.5546875,0.5546875,0.2765625,0.5546875,0.5546875,0.221875,0.240625,0.5,0.221875,0.8328125,0.5546875,0.5546875,0.5546875,0.5546875,0.3328125,0.5,0.2765625,0.5546875,0.5,0.721875,0.5,0.5,0.5,0.3546875,0.259375,0.353125,0.5890625]
const avg = 0.5279276315789471
return str
.split('')
.map(c => c.charCodeAt(0) < widths.length ? widths[c.charCodeAt(0)] : avg)
.reduce((cur, acc) => acc + cur) * fontSize
}
อาร์เรย์ยักษ์ที่น่าเกลียดนั้นคือความกว้างอักขระ ASCII ที่จัดทำดัชนีโดยรหัสอักขระ ดังนั้นนี่สนับสนุน ASCII (ไม่เช่นนั้นจะถือว่าความกว้างอักขระเฉลี่ย) โชคดีที่ความกว้างนั้นปรับขนาดตัวอักษรแบบเชิงเส้นดังนั้นจึงใช้งานได้กับตัวอักษรทุกขนาด มันเห็นได้ชัดว่าขาดการรับรู้ถึงการจัดช่องไฟหรือหนังสติ๊กหรืออะไรก็ตาม
ในการ "ปรับเทียบ" ฉันเพิ่งแสดงอักขระทุกตัวถึง charCode 126 (ตัวหนอนอันยิ่งใหญ่) ใน svg และได้รับกล่องขอบเขตและบันทึกลงในอาร์เรย์นี้ รหัสเพิ่มเติมและคำอธิบายและสาธิตที่นี่