马黑黑 发表于 2025-9-23 12:20

svg渐变在水平线和垂直线上失效的处理方法

本帖最后由 马黑黑 于 2025-9-23 12:22 编辑 <br /><br /><p>SVG渐变用于直线类元素,假若直线为水平线或垂直线,渐变将失效,线条将无法显示。原因在于线条没有实际性厚度,解决方法就是给线条添加厚度。这里所说的厚度本质上指线条在占位空间层面上,① 水平线在Y轴上,② 垂直线在X轴上,头尾两端的Y、X坐标值不能相等,即,y1≠y2,x1≠x2,满足此条件,渐变才会生效。但此时,直线已经不是严格意义上的水平线、垂直线,不过当我们给极小差距的值,渲染效果肉眼看不出来。试看如下演示:</p>
<div class="codebox" data-prev="1">
&lt;svg width="400" height="400"&gt;
        &lt;defs&gt;
                &lt;linearGradient id="lGrd"&gt;
                        &lt;stop offset="0" stop-color="plum" /&gt;
                        &lt;stop offset="0.5" stop-color="purple" /&gt;
                        &lt;stop offset="1" stop-color="plum" /&gt;
                &lt;/linearGradient&gt;
        &lt;/defs&gt;
        &lt;!-- 圆 :演示渐变样式 --&gt;
        &lt;circle cx="200" cy="200" r="100" fill="url(#lGrd)" /&gt;
        &lt;!-- 水平线 :避免 y1 = y2 --&gt;
        &lt;line x1="40" y1="380" x2="390" y2="380.01" stroke="url(#lGrd)" stroke-width="8" /&gt;
        &lt;!-- 垂直线 :避免x1 = x2 --&gt;
        &lt;line x1="20" y1="20" x2="20.01" y2="380" stroke="url(#lGrd)" stroke-width="8" /&gt;
&lt;/svg&gt;
</div>

<p>以上是到目前止最好的解决方案,该方案网上找不到。网上介绍的处理方法是给渐变设置 gradientUnits 属性,属性值设为 userSpaceOnUse,我测试不出效果。DS则认为是线条的线帽样式属性 stroke-linecap 缺省值 butt 拦截了渐变,设置 stroke-linecap="round" 可以解决问题,此法我也测试不出效果。</p>

<script type="module">
        import linenumber from 'https://638183.freep.cn/638183/web/js/linenumber.js';
        linenumber();
</script>

马黑黑 发表于 2025-9-23 12:26

上例使用线性渐变,使用径向渐变原理相同。

线性渐变不设置渐变的 x1,x2,y1,y2 时是使用了默认设置,即 0 0 0 1,自左向右的渐变。所以,查看运行效果,垂直线上面的颜色并没有渐变效果,因为它分配到的颜色是靠左的颜色;水平线则能渲染出完整的线性渐变效果。

杨帆 发表于 2025-9-23 13:44

马老师厉害,终于发现问题并探索出最好的解决方案{:4_191:}

红影 发表于 2025-9-23 15:28

这法子好,0.01的差值肉眼很难分辨,却让渐变得以实现。聪明{:4_199:}

马黑黑 发表于 2025-9-23 18:10

红影 发表于 2025-9-23 15:28
这法子好,0.01的差值肉眼很难分辨,却让渐变得以实现。聪明

目前好像也只有这个方法凑效

马黑黑 发表于 2025-9-23 18:10

杨帆 发表于 2025-9-23 13:44
马老师厉害,终于发现问题并探索出最好的解决方案

这是姑且、将就的方法

花飞飞 发表于 2025-9-23 19:42

马黑黑 发表于 2025-9-23 12:26
上例使用线性渐变,使用径向渐变原理相同。

线性渐变不设置渐变的 x1,x2,y1,y2 时是使用了默认设置, ...

这问题解决得太巧妙了。。思路是真厉害。。
不止0.01,直到0001都可以。。。{:4_173:}

马黑黑 发表于 2025-9-23 19:45

花飞飞 发表于 2025-9-23 19:42
这问题解决得太巧妙了。。思路是真厉害。。
不止0.01,直到0001都可以。。。
就是不必写太长的数值

花飞飞 发表于 2025-9-23 19:54

马黑黑 发表于 2025-9-23 19:45
就是不必写太长的数值

也是,反正眼睛么是看不出来滴。。手也不必辣么累。。
你是喝了哪种酒后想到的??或者抽了哪个牌子的香烟?熏了什么香?{:4_170:}

马黑黑 发表于 2025-9-23 19:56

花飞飞 发表于 2025-9-23 19:54
也是,反正眼睛么是看不出来滴。。手也不必辣么累。。
你是喝了哪种酒后想到的??或者抽了哪个牌子的香 ...

烟:玉溪也可,芙蓉王更好
酒:茅台还行,黄酒更好

花飞飞 发表于 2025-9-23 20:34

马黑黑 发表于 2025-9-23 19:56
烟:玉溪也可,芙蓉王更好
酒:茅台还行,黄酒更好

这么好呀。。。回头我都尝尝,看能不能写代码有灵感。。{:4_170:}

马黑黑 发表于 2025-9-23 22:33

花飞飞 发表于 2025-9-23 20:34
这么好呀。。。回头我都尝尝,看能不能写代码有灵感。。

理论上会有的

红影 发表于 2025-9-23 23:39

马黑黑 发表于 2025-9-23 18:10
目前好像也只有这个方法凑效

能找到方法已经很厉害了{:4_187:}

马黑黑 发表于 2025-9-24 18:02

红影 发表于 2025-9-23 23:39
能找到方法已经很厉害了

你理解厚度就可以了。不过这一切,需要查看的是英文文档,中文文档有点滞后,有时好几年都没跟上。然后还有一些文档需要翻墙才能访问。

花飞飞 发表于 2025-9-24 19:46

马黑黑 发表于 2025-9-23 22:33
理论上会有的

理论跟实际差十万八千里不止

马黑黑 发表于 2025-9-24 19:48

花飞飞 发表于 2025-9-24 19:46
理论跟实际差十万八千里不止

180度

花飞飞 发表于 2025-9-24 20:12

马黑黑 发表于 2025-9-24 19:48
180度

方向和距离都是

马黑黑 发表于 2025-9-24 20:19

花飞飞 发表于 2025-9-24 20:12
方向和距离都是

嗯嗯

红影 发表于 2025-9-24 21:58

马黑黑 发表于 2025-9-24 18:02
你理解厚度就可以了。不过这一切,需要查看的是英文文档,中文文档有点滞后,有时好几年都没跟上。然后还 ...

查个文档还挺麻烦的呢,黑黑辛苦了。

马黑黑 发表于 2025-9-24 23:10

红影 发表于 2025-9-24 21:58
查个文档还挺麻烦的呢,黑黑辛苦了。

这是碰上了要进行处理,得弄清原理
页: [1] 2
查看完整版本: svg渐变在水平线和垂直线上失效的处理方法