SVG线性渐变显示在一条路径上但不显示在另一条路径上

时间:2018-04-02 21:45:44

标签: html css google-chrome svg web

我有两条非常相似的路径,除了d属性中的结束数字。第一个路径显示正确,但第二个路径未显示。奇怪的是,如果我将第二条路径的笔划更改为除了我定义的渐变之外的其他任何内容,它就会显示出来。如果我从最后一个数字中截断小数,也会出现渐变。有没有理由说第二个没有出现渐变?

为了我的价值,我试图让它在谷歌浏览器上工作。

<svg height="0" width="0">
  <defs>
    <linearGradient id="pageSearchGradient" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#a0c3d2" stop-opacity="0.75"></stop><stop offset="40%" stop-color="#F59B23" stop-opacity="0.85"></stop><stop offset="100%" stop-color="#F59B23" stop-opacity="1"></stop>
  </defs>
</svg>

<svg width="1600" height="500" class="sankey-diagram "><g width="1450" height="500" transform="translate(150, 0)"><g class="sankey-links">

    <!--  Only their decimal points differ for the last number and yet this one is the one that shows up -->
    <path d="M12,436.7529384197002C365.5,436.7529384197002,365.5,436.75293841969994,719,436.38406598523085" class="sankey-link " style="stroke: url(&quot;#pageSearchGradient&quot;); opacity: 0.3; stroke-width: 126.494;"></path>

    <path d="M12,436.7529384197002C365.5,436.7529384197002,365.5,436.75293841969994,719,436.75293841969994" class="sankey-link " style="stroke: url(&quot;#pageSearchGradient&quot;); opacity: 0.3; stroke-width: 126.494;"></path>

</svg>

链接到 https://codepen.io/anon/pen/OvEzNJ?editors=1000#0

1 个答案:

答案 0 :(得分:3)

不同之处在于两条路径的边界框的高度:

> document.querySelector('path:nth-child(1)').getBBox().height
> 0.368865966796875
> document.querySelector('path:nth-child(2)').getBBox().height
> 0

您正在使用渐变矢量的百分比单位,而您没有指定gradientUnits

<linearGradient id="pageSearchGradient" x1="0%" y1="0%" x2="100%" y2="0%">

spec有以下关于这些条件的说明:

  

如果 gradientUnits =“objectBoundingBox”,则使用以下内容建立属性x1y1x2y2的用户坐标系应用渐变的元素的边界框,然后应用属性gradientTransform指定的转换。百分比表示相对于对象的边界框的值   当 gradientUnits =“objectBoundingBox”gradientTransform是单位矩阵时,线性渐变的法线垂直于对象边界框空间中的渐变向量(即抽象坐标系所在的位置( 0,0)位于对象边界框的顶部/左侧,(1,1)位于对象边界框的底部/右侧。

如果该边界框没有高度,则顶部(在边界框空间中定义0)和底部(定义1)是相同的值。似乎浏览器(我也可以在Firefox中看到它)对“抽象坐标系”感到困惑,不再知道如何计算梯度向量及其法线。

我称这是一个错误。我能想出的最佳解决方法是使用gradientUnits="userSpaceOnUse",或者确保路径边界框的宽度和高度始终为非零。 (门槛似乎在第七位左右。)

这是一个显示效果的测试用例。应该有三个矩形,第一个用<rect>绘制,另外两个用<line stroke-width=...>绘制。对于中间线,y1和y2是相同的,对于它们不同的底部,

<svg width="200" height="150">
  <linearGradient id="lg" x1="0%" y1="0%" x2="100%" y2="0%">
    <stop stop-color="yellow" offset="0" />
    <stop stop-color="green" offset="1" />
  </linearGradient>
  <rect x="5" y="0" width="200" height="40" style="fill:url(#lg)" />
  <line x1="0" y1="75" x2="200" y2="75" style="stroke-width:40;stroke:url(#lg)" />
  <line x1="0" y1="125" x2="200" y2="126" style="stroke-width:40;stroke:url(#lg)" />
</svg>