马黑黑 发表于 2024-11-11 07:50

svgdr教程·渐变

<style>
        .art > p { margin: 12px 0; font: normal 18px/24px sans-serif; }
        .art mark { padding: 2px 6px; background: lightblue; }
        .art svg { outline: 1px solid silver; }
        .tRed { color: red; }
</style>

<div class="art">
        <h2>渐变</h2>
        <p>指令:<mark>gradient()</mark>
        <p>参数:<mark>name, options, stopcode</mark>
        <p>语法:<mark>gradient(name, options, stopcode)</mark>
        <p>参数解释:</p>
        <blockquote>
                ① name - SVG渐变名称,必须,两个可选值:<span class="tRed">linearGradient</span>、<span class="tRed">radialGradient</span>,即线性渐变和径向渐变<br>
                ② options - 渐变标签的属性配置,必须,配置里至少要包含 *Gradient 标签的id,配置内容及方法稍后举例说明<br>
                ③ stopcode - 渐变内部stop节点,即一组stop子标签,用于描述渐变颜色变化,稍后举例说明
        </blockquote>
        <p><strong>一、初识SVG渐变</strong></p>
        <p>先看SVG渐变的简单代码结构:</p>
       
        <div id="div1"><pre id="pre1">
&lt;!-- 重要 :(1)渐变必须有id,其内需要至少两个stop标签节点;(2)*Gradient标签放在&lt;defs&gt; ... &lt;/defs&gt; 之内 --&gt;

&lt;!-- 线性渐变 --&gt;
&lt;defs&gt;
        &lt;linearGradient id="gID"&gt;
                &lt;stop ... /&gt;
                &lt;stop ... /&gt;
        &lt;/linearGradient&gt;
&lt;/defs&gt;

&lt;!-- 径向渐变 --&gt;
&lt;defs&gt;
        &lt;radialGradient id="gID"&gt;
                &lt;stop ... /&gt;
                &lt;stop ... /&gt;
        &lt;/radialGradient&gt;
&lt;/defs&gt;
        </pre></div>

        <p>再看SVG渐变标签其他重要属性:</p>

        <div id="div2"><pre id="pre2">
// 一、线性渐变
&lt;linearGradient id="linearID" x1="0" x2="0" y1="0" y2="1"&gt; ... &lt;/linearGradient&gt;

// 属性 x1、x2、y1、y2 定义渐变路线走向,取值范围 0-1 或 0%-100%

// 横向和纵向渐变取值举例:
// 0 1 0 0 -自左向右,缺省默认值
// 1 0 0 0 - 自右向左
// 0 0 0 1 - 自上而下
// 0 0 1 0 - 自下而上

// 原理 :x1、x2为水平渐变,若它们相等,水平方向颜色不产生过渡;y1、y2为纵向渐变,若它们相等,垂直方向颜色不产生过渡。x1、x2、y1、y2在合法范围内取值自由,不同设置会得出不同的渐变形态

// 二、径向渐变
&lt;radialGradient id="radialID" cx="0.5" cy="0.5" r="0.5" fx="0.5" fy="0.5"&gt; ... &lt;/radialGradient&gt;

// 说明 :以上各参数均取值 0.5,这是缺省值,即即使没有设置这些属性它们都是这样取值,此时渐变中心点、焦点均在中心(50%)
// 属性 cx、cy、r 定义渐变的中心点坐标和半径,取值范围 0%-100% 或 百分比的浮点数
// 属性 fx、fy 定义渐变焦点坐标(可选),用于控制渐变的形状和方向,取值范围同上
// cx、cy 规定的是径向渐变的发起点,fx、fy 规定的是渐变位置,这两组属性不易理解
        </pre></div>
        <p>接着来看看 stop 标签:</p>
        <div id="div4"><pre id="pre4">
&lt;!-- stop标签是 linearGradient 和 radialGradient 两个渐变标签所需的子标签,任何一种渐变至少需要两组 stop 标签节点 --&gt;
&lt;!-- stop 标签必须的属性有 offset(偏移)、stop-color(颜色中值),还有可选参数 stop-opacity(不透明度)--&gt;

&lt;!-- 线性渐变 --&gt;
&lt;linearGradient id="lgID"&gt;
        &lt;stop offset="0%" stop-color="red" stop-opacity=".8" /&gt;
        &lt;stop offset="100%" stop-color="green" stop-opacity=".9" /&gt;
&lt;/linearGradient&gt;

&lt;!-- 径向渐变 --&gt;
&lt;radialGradient id="rdID"&gt;
        &lt;stop offset="0%" stop-color="red" stop-opacity=".8" /&gt;
        &lt;stop offset="100%" stop-color="green" stop-opacity=".9" /&gt;
&lt;/radialGradient&gt;
        </pre></div>

        <p>svg渐变的属性还有一个需要提一下,<span class="tRed">spreadMethod</span>,扩展方式,值有 pad(缺省默认)、reflect(反射)和 repeat(重复)。要让 spreadMethod 发挥作用,x1、x2 和 y1、y2 只要有一对不能设置边缘数值(即非0即1的数值)。</p>
        <p>上述内容理解起来不容易,不过都是设计svg渐变的基础,要使用 svgdr 的 gradient() 指令来创建渐变并应用于目标元素,需要花点时间和精力至少弄懂个大概。下面是 gradient() 指令应用举例,代码中有注释说明:</p>

        <svg id="msvg" width="800" height="400"></svg>

        <p>绘制代码:</p>

        <div id="div3"><pre id="pre3">
var attr1 = { id: 'linear', x1: .3, x2: .7, y1: .5, y2: .25 }; //声明线性渐变配置
var attr2 = { id: 'radial', cx: .5, cy: .5, r: .5}; //声明径向渐变配置
// 声明 stop 标签组代码字串
var stop = `
        &lt;stop offset="0%" stop-color="pink"&gt;&lt;/stop&gt;
        &lt;stop offset="100%" stop-color="lightblue"&gt;&lt;/stop&gt;
`;

dr.gradient('linearGradient', attr1, stop); //创建线性渐变
dr.gradient('radialGradient', attr2, stop); //创建径向渐变

dr.rect(10, 10, 380, 380, 'url(#linear)'); //画矩形 : fill属性应用线性渐变
dr.rect(410, 10, 380, 380, 'url(#radial)'); //画矩形 :fill属性应用径向渐变
        </pre></div>

        <p>svgdr绘制指令生成的SVG代码:</p>
        <div id="div5"><pre id="pre5"></pre></div>
        <p>上面的例子主要是展示两种svg渐变的创建与应用。下面的例子则在 stop 子节点层面多下了一些工夫:</p>
        <svg id="msvg2" width="400" height="400"></svg>
        <p>svgdr绘制代码:</p>
        <div id="div6"><pre id="pre6">
var stop = `
        &lt;stop offset="0%" stop-color="lightgreen"&gt;&lt;/stop&gt;
        &lt;stop offset="50%" stop-color="lightgreen" stop-opacity="0.5"&gt;&lt;/stop&gt;
        &lt;stop offset="51%" stop-color="olive"&gt;&lt;/stop&gt;
        &lt;stop offset="100%" stop-color="olive"&gt;&lt;/stop&gt;
`;

dr.gradient('radialGradient', {id: 'rGrd'}, stop);
dr.rect(0, 0, '100%', '100%', 'url(#rGrd)');
        </pre></div>
        <p>这组绘制代码,第二个stop子标签偏移 50%、加入透明度设置 0.5,第三个stop子标签偏移值 50%,这两个stop标签在径向渐变中设计了一个消除了锯齿的圆或椭圆,视被渲染对象宽高尺寸而定。最后,id="rGrd" 的径向渐变应用于宽高为svg宽高100%的矩形上生成一个漂亮的图案。</p>
        <p>上面绘制代码生成的SVG代码:</p>
        <div id="div7"><pre id="pre7"></pre></div>
        <p>渐变是一个复杂的机制,在svg中实现渐变更复杂。或许完全理解渐变很困难,但是,只要对之感兴趣,弄懂它不会难于上青天。</p>
        <p><a href="/forum.php?mod=viewthread&tid=79137&extra=page%3D1" targete="_blank">返回目录</a></p>
</div>

<script type="module">
import hl from 'https://638183.freep.cn/638183/web/mod/helight.js';
import draw from 'https://638183.freep.cn/638183/web/mod/svgdr.js';

var dr = draw.dr('msvg');
var attr1 = { id: 'linear', x1: .3, x2: .7, y1: .5, y2: .25 };
var attr2 = { id: 'radial', cx: .5, cy: .5, r: .5};
var stop = `
        <stop offset="0%" stop-color="pink"></stop>
        <stop offset="100%" stop-color="lightblue"></stop>
`;
dr.gradient('linearGradient', attr1, stop);
dr.gradient('radialGradient', attr2, stop);
dr.rect(10, 10, 380, 380, 'url(#linear)');
dr.rect(410, 10, 380, 380, 'url(#radial)');
pre5.textContent = dr.code(msvg);

var dr2 = draw.dr('msvg2');
var stop = `
        <stop offset="0%" stop-color="lightgreen"></stop>
        <stop offset="50%" stop-color="lightgreen" stop-opacity="0.5"></stop>
        <stop offset="51%" stop-color="olive"></stop>
        <stop offset="100%" stop-color="olive"></stop>
`;
dr2.gradient('radialGradient', {id: 'radial2'}, stop);
dr2.rect(0, 0, '100%', '100%', 'url(#radial2)');
pre7.textContent = dr2.code(msvg2);

hl.hl(div1,pre1);
hl.hl(div2,pre2);
hl.hl(div3,pre3);
hl.hl(div4,pre4);
hl.hl(div5,pre5);
hl.hl(div6,pre6);
hl.hl(div7,pre7);

</script>

梦江南 发表于 2024-11-11 09:42

这种渐变在PS里能实现,想不到在代码里也能实现。老师真厉害!

红影 发表于 2024-11-11 09:57

这节课程把线性渐变和径向渐变都讲得那么详细。线性渐变有方向性,感觉径向渐变更简单些,但径向渐变有渐变焦点的设置,让它增加了难度。
这个里面还有stop-opacity 这个是新的东西呢。

红影 发表于 2024-11-11 10:12

第一个例子中的线性渐变在82度多的角度,径向渐变就是常规的使用。
画这些需要的步骤:声明渐变标签、配置 stop 标签、用声明的标签名称创建渐变、用渐变id画图形——用自己的语言记忆一下。

红影 发表于 2024-11-11 10:13

后面还有和SVG代码的比较,比较了才知道,使用svgdr绘制可以省去好多长单词的使用,太方便了{:4_173:}{:4_187:}

红影 发表于 2024-11-11 10:20

最后的圆球,在绿色小球上因为是同色,是只有透明度变化的渐变,然后外侧又是同色,球的外侧没有渐变。“径向渐变中设计了一个消除了锯齿的圆或椭圆”又看到这个,记得黑黑曾经讲过的,让出1%左右的数值,可以消除锯齿呢。嗯,记下了{:4_187:}

红影 发表于 2024-11-11 10:21

好像就spreadMethod提了一下,没讲,这个要自己去看看了。
又一个好东西,黑黑辛苦了{:4_199:}{:4_184:}

马黑黑 发表于 2024-11-11 12:43

红影 发表于 2024-11-11 10:21
好像就spreadMethod提了一下,没讲,这个要自己去看看了。
又一个好东西,黑黑辛苦了

spreadMethod属性用来实现 CSS中的 repeating-*-gradient

马黑黑 发表于 2024-11-11 12:44

红影 发表于 2024-11-11 10:20
最后的圆球,在绿色小球上因为是同色,是只有透明度变化的渐变,然后外侧又是同色,球的外侧没有渐变。“径 ...

这是挺管用的小妙招

马黑黑 发表于 2024-11-11 12:44

梦江南 发表于 2024-11-11 09:42
这种渐变在PS里能实现,想不到在代码里也能实现。老师真厉害!

PS的后台是代码

马黑黑 发表于 2024-11-11 12:45

红影 发表于 2024-11-11 09:57
这节课程把线性渐变和径向渐变都讲得那么详细。线性渐变有方向性,感觉径向渐变更简单些,但径向渐变有渐变 ...

stop-opacity 并不新,只是不常见于帖子中,所以没有印象

马黑黑 发表于 2024-11-11 12:47

红影 发表于 2024-11-11 09:57
这节课程把线性渐变和径向渐变都讲得那么详细。线性渐变有方向性,感觉径向渐变更简单些,但径向渐变有渐变 ...

fx、fy 可以忽略它,我个人感觉它们封装的不理想,和cx、cy功能上有重合,职责并不清晰

马黑黑 发表于 2024-11-11 12:48

红影 发表于 2024-11-11 10:13
后面还有和SVG代码的比较,比较了才知道,使用svgdr绘制可以省去好多长单词的使用,太方便了{:4_1 ...

也不完全能省,有好多还是老老实实写出来

泡沫 发表于 2024-11-11 21:01

即线性渐变和径向渐变之前也有接触过呀,怎么在SVG里面感觉跟新的一样。。。啊。。{:4_198:}

马黑黑 发表于 2024-11-11 21:06

泡沫 发表于 2024-11-11 21:01
即线性渐变和径向渐变之前也有接触过呀,怎么在SVG里面感觉跟新的一样。。。啊。。

它的代码结构严重不同于CSS

泡沫 发表于 2024-11-11 21:57

马黑黑 发表于 2024-11-11 21:06
它的代码结构严重不同于CSS

原来不是我的问题,那就好了。。{:4_173:}
当新的学吧就
这个渐变跟PS里的严重不同
用PS来帮助理解好象没啥用,PS一笔下去,渐变就出来了。

马黑黑 发表于 2024-11-11 22:56

泡沫 发表于 2024-11-11 21:57
原来不是我的问题,那就好了。。
当新的学吧就
这个渐变跟PS里的严重不同


其实道理还是一样,只是代码结构不同。svg的渐变可能更高级

红影 发表于 2024-11-11 23:57

马黑黑 发表于 2024-11-11 12:43
spreadMethod属性用来实现 CSS中的 repeating-*-gradient

哦哦,知道了,谢谢黑黑{:4_187:}

红影 发表于 2024-11-11 23:57

马黑黑 发表于 2024-11-11 12:44
这是挺管用的小妙招

是的,记得黑黑说到过怎样消除锯齿的事。

红影 发表于 2024-11-11 23:58

马黑黑 发表于 2024-11-11 12:45
stop-opacity 并不新,只是不常见于帖子中,所以没有印象

是啊,貌似在svgdr中还是头一次见到。
页: [1] 2
查看完整版本: svgdr教程·渐变