You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SVG中模拟stroke-alignment(描边对齐)效果

模拟SVG描边对齐(stroke-alignment)的正确实现方式

W3C在2015年起草的stroke-alignment属性至今未被浏览器实现,直接使用该属性无法区分内部/外部描边效果。

无效示例

以下代码尝试使用stroke-alignment,但两个正方形的描边效果完全一致:

The blue square should have stroke inside, the red outside, but they're both the same
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="100">
  <g id="myGroup" transform="translate(20 20)">
    <polygon id="myPoly0" points="0,0 50,0 50,50 0,50" style="fill:blue;stroke:black;stroke-width:4;stroke-alignment:inner"></polygon>
    <polygon id="myPoly1" transform="translate(75 0)" points="0,0 50,0 50,50 0,50" style="fill:red;stroke:black;stroke-width:4;stroke-alignment:outer"></polygon>
  </g>
</svg>

原思路的问题

使用<use>复制图形并通过缩放平移模拟描边对齐时,若图形远离SVG原点会出现偏移——这是因为<use>默认的transform-origin是全局原点(0,0),缩放操作会基于全局坐标系计算,而非原图形的局部原点。

解决方案:锚定局部坐标系缩放

通过设置transform-origin为原图形的局部原点(通常是自身的(0,0)点),让缩放操作基于图形自身位置执行,即可避免偏移。

完整示例代码

<svg xmlns="http://www.w3.org/2000/svg" width="600" height="400">
  <g id="myGroup" style="fill:rgb(45, 130, 255);" transform="translate(20 20)">
    <!-- 原图形:无描边,仅填充 -->
    <polygon id="myPoly0" points="0,0 100,0 100,100 0,100"></polygon>
    <polygon id="myPoly1" transform="translate(110 110)" points="0,0 100,0 100,100 0,100"></polygon>
    <polygon id="myPoly2" transform="translate(220 220)" points="0,0 100,0 100,100 0,100"></polygon>

    <!-- 模拟外部描边:放大图形后反向平移,transform-origin锚定局部原点 -->
    <use href="#myPoly0" vector-effect="non-scaling-stroke" 
         style="fill:none;stroke:black;stroke-width:4;transform-origin: 0 0;" 
         transform="translate(-2 -2) scale(1.04)"></use>
    <use href="#myPoly1" vector-effect="non-scaling-stroke" 
         style="fill:none;stroke:black;stroke-width:4;transform-origin: 0 0;" 
         transform="translate(-2 -2) scale(1.04)"></use>
    <use href="#myPoly2" vector-effect="non-scaling-stroke" 
         style="fill:none;stroke:black;stroke-width:4;transform-origin: 0 0;" 
         transform="translate(-2 -2) scale(1.04)"></use>

    <!-- 额外演示内部描边:缩小图形后正向平移 -->
    <polygon id="myPoly3" transform="translate(330 0)" points="0,0 100,0 100,100 0,100" style="fill:red;"></polygon>
    <use href="#myPoly3" vector-effect="non-scaling-stroke" 
         style="fill:none;stroke:white;stroke-width:4;transform-origin: 0 0;" 
         transform="translate(2 2) scale(0.96)"></use>
  </g>
</svg>

关键说明

  • transform-origin: 0 0;:将缩放原点设置为原图形自身的左上角,确保缩放基于图形局部坐标系执行,不受全局平移影响。
  • 外部描边:缩放比例为1 + 描边宽度/图形边长(如100px边长、4px描边:1 + 4/100 = 1.04),然后反向平移描边宽度/2(4/2=2px),让放大后的图形与原图形位置对齐,描边自然出现在外部。
  • 内部描边:缩放比例为1 - 描边宽度/图形边长(1 - 4/100=0.96),正向平移描边宽度/2,缩小后的图形与原图形对齐,描边被原图形的填充覆盖外部部分,仅显示内部描边。

内容的提问来源于stack exchange,提问作者Jason Polites

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 22:50:22