在Canvas与SVG的使用中,我们经常需要根据字符串的长度来计算文字绘制的起点与终点,常规的方法莫过于使用经验值,如中文字符长度乘以6(经验值),英文字符长度乘以3,代码示例如下:
// 判断是否是ASCII字符
var pattern = /[\u0000-\u00FF]*/,
// 根据字符的个数来计算字符串的长度
width = pattern.test(text) ? text.length * 3 : text.length * 6
上述的方法采用了正则表达式,但是对于中英混合的字符就会过于复杂,例如“2017年7月15日”,就需要分别找出中文字符个数,英文字符个数,不仅设计繁琐,而且宽度也不精确,所以需要一种更灵巧的办法。
充分利用浏览器的布局特性可轻松解决上述问题:
1. 创建隐藏层(也可重复使用);
2. 创建字符串容器,如SPAN元素;
3. 添加字符串;
4. 计算字符串容器宽度;
具体实现代码如下:
/**
1. @param str 要计算的字符串
2. @param fontSize 字符串的字体大小
3. 根据需要,还可以添加字体控制,如微软雅黑与Times New Roma的字符宽度肯定不一致
*/
function textWidth(str, fontSize) {
if(!textWidth.txt) {
var txt = document.createElement('span');
txt.style.position = 'absolute';
// 避免遮挡其他元素
txt.style.zIndex = -10;
// 千万不可设置为display:none;
txt.style.visibility = 'hidden'
// 一定要加载到DOM中才能计算出字符宽度
document.body.appendChild(txt);
textWidth.txt = txt;
}
// 控制字符的字体大小
textWidth.txt.style.fontSize = fontSize + 'px';
// 设置字符内容
textWidth.txt.textContent = str;
// 返回计算结果
return textWidth.txt.offsetWidth;
}
现在可轻松计算字符宽度了,如下:
// 输出99
alert(textWidth('国际米兰', 14))
// 输出85
alert(textWidth('国际米兰', 12))
最后,实际效果绘制的效果图如下所示:
结论
结合使用DOM技术,可轻松解决许多SVG、canvas绘图技术无法解决的难题。