Saya suka "satu-satunya ide" Anda hanya melakukan peta lebar karakter statis! Ini sebenarnya berfungsi dengan baik untuk tujuan saya. Terkadang, untuk alasan kinerja atau karena Anda tidak memiliki akses mudah ke DOM, Anda mungkin ingin kalkulator mandiri yang cepat dikalibrasi ke satu font. Jadi, inilah yang dikalibrasi ke Helvetica; meneruskan string dan (opsional) ukuran font:
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
}
Array jelek raksasa itu adalah lebar karakter ASCII yang diindeks oleh kode karakter. Jadi ini hanya mendukung ASCII (selain itu mengasumsikan lebar karakter rata-rata). Untungnya, lebar pada dasarnya berskala linier dengan ukuran font, sehingga berfungsi cukup baik pada ukuran font apa pun. Itu terasa kurang kesadaran tentang kerning atau ligatur atau apa pun.
Untuk "mengkalibrasi", saya hanya merender setiap karakter hingga charCode 126 (the perkasa tilde) pada svg dan mendapatkan kotak pembatas dan menyimpannya ke array ini; lebih banyak kode dan penjelasan dan demo di sini .