如何使用 svg 渐变插入色调?

How to interpolate hue with svg gradient?

我想要一个具有从 hsl(0, 100%, 50%)hsl(360, 100%, 50%) 的渐变的 svg 形状,其中色调从 0 -> 360 平滑地运行,以创建如下内容:

当我用这些停止色制作渐变时:

<linearGradient id="Gradient1">
  <stop offset="0%" stop-color="hsl(0, 100%, 50%)"/>
  <stop offset="100%" stop-color="hsl(360, 100%, 50%)"/>
</linearGradient>

…它会产生完全红色的渐变

我通过添加更多停靠点设法hack around它:

<linearGradient id="Gradient2">
  <stop offset="0%" stop-color="hsl(0, 100%, 50%)"/>
  <stop offset="1%" stop-color="hsl(3, 100%, 50%)"/>
  <stop offset="2%" stop-color="hsl(7, 100%, 50%)"/>
  <!-- Lots more -->
  <stop offset="98%" stop-color="hsl(352, 100%, 50%)"/>
  <stop offset="99%" stop-color="hsl(356, 100%, 50%)"/>
</linearGradient>

虽然看起来很丑。

有更好的方法吗?

全 hsl 渐变 0 - 360

通过将停止颜色设置为 10%,我得到了接近图像的形状:

<svg height="100%" viewBox="0 0 100 20">
  <defs>
    <linearGradient id="Gradient2">
      <stop offset="0%" stop-color="hsl(0, 100%, 50%)" />
      <stop offset="10%" stop-color="hsl(36, 100%, 50%)" />
      <stop offset="20%" stop-color="hsl(72, 100%, 50%)" />
      <stop offset="30%" stop-color="hsl(108, 100%, 50%)" />
      <stop offset="40%" stop-color="hsl(144, 100%, 50%)" />
      <stop offset="50%" stop-color="hsl(180, 100%, 50%)" />
      <stop offset="60%" stop-color="hsl(252, 100%, 50%)" />
      <stop offset="70%" stop-color="hsl(236, 100%, 50%)" />
      <stop offset="80%" stop-color="hsl(288, 100%, 50%)" />
      <stop offset="90%" stop-color="hsl(324, 100%, 50%)" />
      <stop offset="100%" stop-color="hsl(360, 100%, 50%)" />
    </linearGradient>
  </defs>
  <line stroke-width="16" stroke-linecap="round" stroke="url(#Gradient2)" x1="10" y1="10" y2="10.1" x2="90" />
</svg>

如果您想了解如何在 1% 处停止颜色,请查看由 Harry 创建的 fiddle:
Fiddle

包含在与 10% 止损点的比较中。

如果您认为停止颜色太多,那么您可以使用 javascript 添加每个停止元素。但我认为一般来说,手动添加它们是更好的方法。

SVG 中的颜色插值是使用 sRGB 颜色完成的 space(虽然您应该能够指定 linearRGB,但我认为它没有得到很好的支持),所以您不能做您想做的事 -这些 HSL 颜色在被插值之前被转换为 sRGB。

(从技术上讲,SVG 1.1 不支持 HSL 颜色 - 所以虽然这在 Chrome 中有效,但如果它在任何地方都无效,请不要感到惊讶)

梯度每 60 度停止一次!

由于 hsl and rgb interact 的方式,您可以通过在色调上每 60 度停止一次渐变来获得最佳效果。添加更多站点或 其他地方,使结果更糟。

使用十六进制、html 颜色名称、rgb 或 hsl 来定义渐变应该在网络浏览器中产生相同的结果,因为它们最终都会转换为 rgb。我不确定网络浏览器之外的 hsl svg 兼容性,为了安全起见,在大多数情况下我会坚持使用 rgb 或 hex。

<svg width=100%>
  <rect width=100%           height="1em" fill="url(#hslGradient)"/>
  <rect width=100% y="1.5em" height="1em" fill="url(#nameGradient)"/>
  <rect width=100% y="3em"   height="1em" fill="url(#rgbGradient)"/>
  <rect width=100% y="4.5em" height="1em" fill="url(#hexGradient)"/>
  <defs>
    <linearGradient id="hslGradient">
      <stop offset=0%   stop-color="hsl(  0, 100%, 50%)" />
      <stop offset=16%  stop-color="hsl( 60, 100%, 50%)" />
      <stop offset=33%  stop-color="hsl(120, 100%, 50%)" />
      <stop offset=50%  stop-color="hsl(180, 100%, 50%)" />
      <stop offset=66%  stop-color="hsl(240, 100%, 50%)" />
      <stop offset=83%  stop-color="hsl(300, 100%, 50%)" />
      <stop offset=100% stop-color="hsl(360, 100%, 50%)" />
    </linearGradient>
    <linearGradient id="nameGradient">
      <stop offset=0%   stop-color="red"    />
      <stop offset=16%  stop-color="yellow" />
      <stop offset=33%  stop-color="lime"   />
      <stop offset=50%  stop-color="cyan"   />
      <stop offset=66%  stop-color="blue"   />
      <stop offset=83%  stop-color="magenta"/>
      <stop offset=100% stop-color="red"    />
    </linearGradient>
    <linearGradient id=rgbGradient>
      <stop offset=0%   stop-color="rgb(255,  0,  0)"/>
      <stop offset=16%  stop-color="rgb(255,255,  0)"/>
      <stop offset=33%  stop-color="rgb(  0,255,  0)"/>
      <stop offset=50%  stop-color="rgb(  0,255,255)"/>
      <stop offset=66%  stop-color="rgb(  0,  0,255)"/>
      <stop offset=83%  stop-color="rgb(255,  0,255)"/>
      <stop offset=100% stop-color="rgb(255,  0,  0)"/>
    </linearGradient>
  <linearGradient id=hexGradient>
      <stop offset=0%   stop-color="#f00"/>
      <stop offset=16%  stop-color="#ff0"/>
      <stop offset=33%  stop-color="#0f0"/>
      <stop offset=50%  stop-color="#0ff"/>
      <stop offset=66%  stop-color="#00f"/>
      <stop offset=83%  stop-color="#f0f"/>
      <stop offset=100% stop-color="#f00"/>
    </linearGradient>
  </defs>
</svg>

如果我们谈论网络,我个人会使用 css 渐变。

html {
  background: linear-gradient(to right,
    #f00,
    #ff0,
    #0f0,
    #0ff,
    #00f,
    #f0f,
    #f00)
}