用图案制作响应角度的svg形状

时间:2017-04-17 21:52:04

标签: html css d3.js svg

我正在尝试创建一个SVG形状,它是一个可模式化的路径。我面临的问题是两端需要有角度,元素需要响应(角度保持不变,但元素的长度会发生变化)。

我最初只使用HTML和CSS进行此操作,但必须使用前后元素创建角度,这意味着无法使模式排列。因此,为什么我在寻找SVG解决方案。

以下是元素的外观:

Angle variations for an svg shape using a linear gradient

我最接近的尝试是rect元素,其中clip-path引用正在使用路径。问题是元素必须是响应的,但路径不能定位在“最右边”。

我确实有d3可供我使用,但我不确定这是否可以减轻复杂性。如何创建这种响应式图案形状?

2 个答案:

答案 0 :(得分:4)

可以使用<use>元素的技巧在SVG中执行此操作。

<svg width="100%" height="50px">
  <defs>
    <pattern id="stripes" patternUnits="userSpaceOnUse" width="50" height="50">
      <path d="M-10,20 L20,-10
               M-10,45 L45,-10
               M0,60 L60,0
               M25,60 L60,25" fill="none" stroke="lightgrey" stroke-width="10"/>
    </pattern>
    <clipPath id="leftarrow">
      <path d="M15,0 L0,25,15,50,5000,50,5000,0 Z"/>
    </clipPath>
    <path id="rightarrowpath" d="M-15,0 L0,25,-15,50,-5000,50,-5000,0 Z"/>
    <clipPath id="rightarrow">
      <use xlink:href="#rightarrowpath" x="100%"/>
    </clipPath>
  </defs>

  <g clip-path="url(#leftarrow)">
    <rect width="100%" height="50" fill="url(#stripes)"
          clip-path="url(#rightarrow)"/>
  </g>
</svg>

如何运作

首先,我们将SVG定义为100%宽度,以便填充容器。我们添加一个大小相同的矩形(100%x 50px)。 SVG没有viewBox,因为我们不希望任何延伸。

现在我们需要将矩形剪切成左右箭头形状。左箭头很简单,因为我们可以使用x=0处的箭头部分定义真正的宽剪切路径。只要它足够宽,它应该没问题。

<svg width="100%" height="50px">
  <defs>
    <pattern id="stripes" patternUnits="userSpaceOnUse" width="50" height="50">
      <path d="M-10,20 L20,-10
               M-10,45 L45,-10
               M0,60 L60,0
               M25,60 L60,25" fill="none" stroke="lightgrey" stroke-width="10"/>
    </pattern>
    <clipPath id="leftarrow">
      <path d="M15,0 L0,25,15,50,5000,50,5000,0 Z"/>
    </clipPath>
  </defs>

  <rect width="100%" height="50" fill="url(#stripes)"
        clip-path="url(#leftarrow)"/>
</svg>

不幸的是,右手箭头不是那么直截了当。原因是我们希望箭头自动定位在SVG的右侧(即100%宽度)。但<path>定义不允许百分比。我们也不能使用transform来获取它,因为你也不能在变换中使用百分比。

幸运的是,有一个“漏洞”技术。 <use>元素允许我们提供偏移量(xy),以便定位它引用的元素。这些属性允许百分比。

所以我们要做的是定义右箭头剪辑路径以使其右手边缘位于x = 0,然后我们使用<use>元素将其定位为100%。

<svg width="100%" height="50px">
  <defs>
    <pattern id="stripes" patternUnits="userSpaceOnUse" width="50" height="50">
      <path d="M-10,20 L20,-10
               M-10,45 L45,-10
               M0,60 L60,0
               M25,60 L60,25" fill="none" stroke="lightgrey" stroke-width="10"/>
    </pattern>
    <path id="rightarrowpath" d="M-15,0 L0,25,-15,50,-5000,50,-5000,0 Z"/>
    <clipPath id="rightarrow">
      <use xlink:href="#rightarrowpath" x="100%"/>
    </clipPath>
  </defs>

  <rect width="100%" height="50" fill="url(#stripes)"
        clip-path="url(#rightarrow)"/>
</svg>

我们需要做的就是将这两种技术结合起来,得到我们的双端(响应)图案箭头。但是,由于矩形不能有两个剪切路径,我们必须将其包装在一个组中,并将其中一个剪切路径应用于该剪切路径。

最终结果是这个答案顶部的例子。

答案 1 :(得分:1)

这是一个HTML / CSS解决方案。

我们所做的是transformsupport)两个元素skew()来创建尖端。在下面,您可以看到红色父DIV创建了点的一侧,而子元素通过在相反方向上倾斜来创建另一侧。在最终解决方案中,我们从父元素中删除背景。

div {
  height: 25px;
  transform: skew( 25deg );
  overflow: hidden;
  position: relative;
  background-color: indianred;
}
div:before {
  content: '';
  display: block;
  height: 100%;
  background-color: rebeccapurple;
  transform: skew( -42deg );
}
<div></div>

然后我们使用repeating lindear gradientsupport)来创建有角度的细条纹。

div {
  height: 25px;
  transform: skew( 25deg );
  overflow: hidden;
  position: relative;
}

div:before {
  content: '';
  display: block;
  height: 100%;
  background: repeating-linear-gradient(
    35deg,
    transparent,
    transparent 3px,
    lightgray 3px,
    lightgray 6px
  );;
  transform: skew( -42deg );
}
<div></div>