【问题标题】:Stroke SVG Path only inside or only outside仅在内部或仅在外部描边 SVG 路径
【发布时间】:2019-07-12 13:22:17
【问题描述】:

考虑 2 个 html svg 路径,一个正方形(inside 类)和一个矩形(outside 类)具有相同的高度。当我应用stroke-width: 10px 时,笔划在内部应用5px,在外部应用5pxFiddle

我如何只在里面或只在外面抚摸?

.inside { 
  stroke: #333;
  stroke-mode: inside;     // property does not exist
  stroke-width: 5px;
}

.outside {
   stroke: #333;
   stroke-mode: outside;   // property does not exist
   stroke-width: 5px;
}

如果没有这样的属性,是否有解决方法来实现类似:

【问题讨论】:

  • 改变内部矩形内部的大小是不行的吗?
  • 它适用于矩形等简单路径,但适用于包含多个路径的复杂 SVG,例如从正方形中移除的圆形?
  • 你可能想看看像这里解释的剪辑路径:stackoverflow.com/a/32162431/4428236,这似乎是目前唯一有效的解决方案,因为 SVG 工作组未能从多个实现中风控制属性提案...
  • 是的,这是真的。当我创建 svgs 时,我从不使用笔触,只是填充。当我想在某物周围设置边框时,我只需像这样绘制路径。
  • 您可以通过使用paint-order 属性来产生仅在外部进行描边的错觉,该属性允许您控制填充和描边(以及绘画标记)的绘制顺序。如果您使用paint-order: stroke; svg 将先绘制笔触,然后再进行填充。所以描边的内半部分会被填充遮住。

标签: html css svg stroke


【解决方案1】:

@enxaneta 上面的评论完全正确。

通常情况下,填充矩形的宽度为48px,具有strokestroke-width12px,矩形将显示:

  • 12px 宽边框
  • 36px 的表观宽度

为什么是36px 而不是48px

因为沿矩形左侧绘制的12px-宽笔划遮挡了矩形的6px,而沿矩形右侧绘制的12px-宽笔划遮挡了矩形的6px矩形。

查看stroke 具有 50% 不透明度的示例 - 您可以看到 stroke 的一半与 fill 重叠:

svg rect {
  x: 10px;
  y: 10px;
  width: 200px;
  height: 100px;
  stroke: rgba(0, 0, 0, 0.5);
  stroke-width: 12px;
  fill: rgb(255, 0, 0);
}
<svg>
  <rect />
</svg>

创建12px外边框的解决方案:

要创建外边框,解决方案是绘制笔触,然后然后在顶部绘制填充。

我们可以使用:

paint-order: stroke;

现在矩形将显示:

  • 一个明显的6px 宽边框(因为12px 宽边框的一半宽度被顶部的fill 遮住了)
  • 宽度为48px

svg rect {
  x: 10px;
  y: 10px;
  width: 200px;
  height: 100px;
  stroke: rgba(0, 0, 0, 0.5);
  stroke-width: 12px;
  fill: rgb(255, 0, 0);
  paint-order: stroke;
}
<svg>
  <rect />
</svg>

最后,确保矩形显示为:

  • 12px 宽边框
  • 宽度为48px

stroke-width12px 更改为 24px(即预期显示宽度的两倍):

svg rect {
  x: 10px;
  y: 10px;
  width: 200px;
  height: 100px;
  stroke: rgb(0, 0, 0);
  stroke-width: 24px;      /* double the intended display width */
  fill: rgb(255, 0, 0);
  paint-order: stroke;
}
<svg>
  <rect />
</svg>

创建12px内边框的解决方案:

要创建内边框,我们需要三个步骤而不是两个。

前两个步骤很简单:

  • stroke-width 加倍(与外边框一样)
  • 使用paint-order: fill(而不是paint-order: stroke

svg rect {
  x: 10px;
  y: 10px;
  width: 200px;
  height: 100px;
  stroke: rgba(0, 0, 0, 0.5);
  stroke-width: 24px;      /* double the intended display width */
  fill: rgb(255, 0, 0);
  paint-order: fill;
}
<svg>
  <rect />
</svg>

第三步是定义和应用&lt;clipPath&gt;,它完全复制了具有内边框的形状。

例如,如果形状是:

<rect width="200" height="100" />

那么&lt;clipPath&gt;应该是:

<clipPath id="my-clip-path">
  <rect width="200" height="100" /> <!-- Same as the shape -->
</clipPath>

工作示例:

#my-rect {
  stroke: rgb(0, 0, 0);
  stroke-width: 24px;
  fill: rgb(255, 0, 0);
  paint-order: fill;
  clip-path: url(#my-clip-path);
}

#my-rect,
#my-clip-path-rect {
  x: 10px;
  y: 10px;
  width: 200px;
  height: 100px;
}
<svg>
  <defs>
    <clipPath id="my-clip-path">
      <rect id="my-clip-path-rect" />
    </clipPath>
  </defs>
  
  <rect id="my-rect" />
</svg>

所有矩形加在一起:

svg {
  display: block;
  float: left;
  width: 220px;
  margin-left: 12px;
}

svg:nth-of-type(1) rect {
  x: 10px;
  y: 10px;
  width: 200px;
  height: 100px;
  stroke: rgba(0, 0, 0, 0.5);
  stroke-width: 12px;
  fill: rgb(255, 0, 0);
}

svg:nth-of-type(2) rect {
  x: 10px;
  y: 10px;
  width: 200px;
  height: 100px;
  stroke: rgba(0, 0, 0, 0.5);
  stroke-width: 24px;
  fill: rgb(255, 0, 0);
}

svg:nth-of-type(3) rect {
  x: 10px;
  y: 10px;
  width: 200px;
  height: 100px;
  stroke: rgb(0, 0, 0);
  stroke-width: 24px;
  fill: rgb(255, 0, 0);
  paint-order: stroke;
}

#svg3clip {
  width: 200px;
  height: 100px;
}

svg:nth-of-type(4) rect {
  x: 10px;
  y: 10px;
  width: 200px;
  height: 100px;
  stroke: rgb(0, 0, 0);
  stroke-width: 24px;
  fill: rgb(255, 0, 0);
  paint-order: fill;
  clip-path: url(#svg3clip);
}
<svg>
  <rect />
</svg>

<svg>
  <rect />
</svg>

<svg>
  <defs>
    <clipPath id="svg3clip">
      <rect />
    </clipPath>
  </defs>
  
  <rect />
</svg>

<svg>
  <rect />
</svg>

进一步阅读:

【讨论】:

  • 谢谢,这适用于外部边界。有内部边界的解决方法吗?
  • 我想到了这一点,@SaravanabalagiRamachandran 和我想出了一个使用paint-order: fill&lt;clipPath&gt; SVG 元素(结合clip-path CSS 属性)。详情见上文。
  • 非常感谢,非常感谢。我想指出,这种内部笔划解决方法受到我们需要复制形状并使用它来剪辑它的事实的限制。我希望有一种方法可以将对象剪辑到自身而无需重复。
  • 是的 - 你应该能够做到这一点,@SaravanabalagiRamachandran,通过利用 SVG 非常有用的 &lt;use&gt; 元素。见:developer.mozilla.org/en-US/docs/Web/SVG/Element/use
猜你喜欢
  • 1970-01-01
  • 2015-11-29
  • 2014-01-14
  • 2012-07-09
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2016-01-16
相关资源
最近更新 更多