Skip to content

校正矢量图路径与填充

2026-07-12 · 543 字 · 2 分钟 · 浏览量

今天照例是设计古琴字体。在设计过程中,我注意到一个问题,就是 svg 的显示正常,但是导出为字体轮廓后,填充变得异常。例如下面这个“口”字:

原来是因为这个“口”字的路径是由两个闭合路径组成的,但其填充规则是 even-odd,字体轮廓的填充规则是 non-zero,也就是说默认外圈轮廓是顺时针方向,而内圈轮廓是逆时针方向。然而 even-odd 与轮廓方向无关,而是用射线法则来判断点是否在路径内。因此需要将 even-odd 的 fill rule 转换为 non-zero 的 fill rule,例如下面这个“口”字:

二者的源代码区别如下:

html
<svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
  <path fill-rule="evenodd" fill="#3498db" d="
    M 10 10 
    L 190 10 
    L 190 190 
    L 10 190 
    Z 
    
    M 50 50 
    L 150 50 
    L 150 150 
    L 50 150 
    Z
  "/>
</svg>
html
<svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
  <path fill-rule="nonzero" fill="#e74c3c" d="
    M 10 10 
    L 190 10 
    L 190 190 
    L 10 190 
    Z 
    
    M 50 50 
    L 50 150 
    L 150 150 
    L 150 50 
    Z
  "/>
</svg>

注意到改动了 fill rule 和内圈路径的方向(由顺时针改为逆时针)。但在 svg 层面上的改动,很难从源码中直观的找到需要修改的路径,于是可以借助 脚本工具 进行修复。

或者在设计路径时就注意路径的方向。在 figma 中,如果需要在矢量图中挖洞,则需要把内圈路径置于外圈路径上方,然后使用布尔运算中的“减法”(subtract)操作,然后将路径拼合(outline stroke)后导出为 svg,这样就可以保证路径的方向正确。而之前我仅仅是用油漆桶工具填充两个闭合路径之间的区域,导致内圈路径的方向是默认的顺时针,而此时使用的是 even-odd 填充规则,导出为字体轮廓后使得填充异常。

返回

人同此心,心同此理;如风沐面,若水润心