Fabric JS JSON转HTML:部分字体无法在span中垂直居中
解决FabricJS JSON转HTML后特殊字体垂直居中问题
问题根源
很多非标准字体(比如你提到的Choko Pain、Nurjan、Eczar Extra Bold、VarianeScript)的字体基线、上升/下降高度和Roboto这类系统默认字体差异极大。浏览器默认的文本布局基于基线对齐,而FabricJS在Canvas渲染文本时会精确计算字体度量数据来实现居中,这就导致HTML里的<span>无法自动匹配FabricJS的视觉效果。
解决方案:基于字体度量的精准偏移
通过Canvas获取字体的真实度量信息,动态计算偏移量,将文本拉到垂直居中位置,完全模拟FabricJS的渲染逻辑。
完整实现代码
HTML结构
<div class="text-wrapper"> <!-- 正常对齐的参考文本 --> <span class="fabric-text" data-font="Roboto" data-content="Roboto (正常居中)">Roboto (正常居中)</span> <!-- 需要修复的特殊字体文本 --> <span class="fabric-text" data-font="ChokoPlain" data-content="ChokoPlain (修复前偏移)">ChokoPlain (修复前偏移)</span> <span class="fabric-text" data-font="Eczar Extra Bold" data-content="Eczar Extra Bold">Eczar Extra Bold</span> <span class="fabric-text" data-font="VarianeScript" data-content="VarianeScript">VarianeScript</span> </div>
基础CSS
.text-wrapper { width: 100%; padding: 1.5rem; background-color: #f8f9fa; border: 1px solid #dee2e6; /* 添加中线参考,方便观察对齐效果 */ background-image: linear-gradient(transparent 49%, #ffe5e5 50%, #ffe5e5 51%, transparent 51%); } .fabric-text { display: inline-block; margin: 0 1.25rem; font-size: 1.5rem; line-height: 3.75rem; /* 模拟FabricJS文本框的高度 */ position: relative; }
核心JavaScript逻辑
function adjustTextVerticalCenter() { const textElements = document.querySelectorAll('.fabric-text'); textElements.forEach(el => { const fontName = el.dataset.font; const computedStyle = window.getComputedStyle(el); const fontSize = parseInt(computedStyle.fontSize); const lineHeight = parseInt(computedStyle.lineHeight); // 用隐藏Canvas获取字体精确度量 const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); ctx.font = `${fontSize}px ${fontName}`; // 获取字体的上升高度、下降高度 const metrics = ctx.measureText(el.dataset.content); const ascent = metrics.actualBoundingBoxAscent; const descent = metrics.actualBoundingBoxDescent; const totalFontHeight = ascent + descent; // 计算偏移:容器中线位置 - 字体本身的中线位置 const translateYOffset = (lineHeight / 2) - (ascent - (totalFontHeight / 2)); // 应用偏移 el.style.transform = `translateY(${translateYOffset}px)`; }); } // 确保字体加载完成后执行(必须) window.addEventListener('load', adjustTextVerticalCenter); // 如果是异步加载字体,监听字体加载完成事件 document.fonts.ready.then(adjustTextVerticalCenter);
效果对比
修复前
修复后
注意事项
- 必须等字体加载完成:如果字体还没加载就计算度量,会得到错误数值,导致偏移失效。
- 动态文本需重新计算:如果是后续动态生成的文本元素,要在元素插入DOM后重新调用
adjustTextVerticalCenter()。 - 特殊字形微调:像VarianeScript这类花体字体,可能需要根据实际度量结果微调偏移公式,比如调整
totalFontHeight的权重。
内容的提问来源于stack exchange,提问作者rathod annu
相关产品推荐
相关产品推荐

