乐趣区

关于svg:如何美化你的图表关于SVG渐变你需要了解的一切

突变在网页设计中简直随处可见,突变的背景、文字、按钮、图表等等,相比于纯色,突变的色彩显得更加灵动天然。

明天咱们要探讨的,就是 SVG 中的突变绘制。

更多 SVG 系列文章:SVG 基础知识、SVG 动画、SVG 中的 Transform 变换。

概述

或者你有应用 css 绘制突变图形的教训,如果要绘制一个突变的矩形,咱们能够这样写:

<div class="bg"></div>

.bg{ 
    height: 100px; 
    width: 200px; 
    // 给元素设置突变背景
    background: linear-gradient(#fb3,#58a); 
}

应用 SVG 绘图,色彩是通过设置元素的fill(填充色彩)和stroke(边框色彩)属性来实现。

<rect height="100" width="150" stroke="#45B649" stroke-width="2" fill="#DCE35B"></rect>


对于突变色彩的设置,咱们不能像在 css 中那样,间接写fill="linear-gradient(color1, color2)",而要应用专门的突变标签:<linearGradient>(线性突变)和 <radialGradient>(径向突变)。

线性突变

根底应用

先来看一个最简略的例子,如何绘制一个线性突变的矩形:

<svg>
   <defs>
       <linearGradient id="gradient-test">
           <stop offset="0%" stop-color="#DCE35B" />
           <stop offset="100%" stop-color="#45B649" />
       </linearGradient>
   </defs>
   <rect height="100" width="150" fill="url(#gradient-test)"></rect>
</svg>


通常,咱们将突变标签 <linearGradient> 定义在 <defs> 元素中,<linearGradient>id 属性作为其惟一标识,不便前面须要应用的中央对其进行援用。

<linearGradient>中的 <stop> 标签定义渐变色的色标,它的 offset 和 stop-color 属性别离定义色标的地位和色彩值,它还有一个属性 stop-opacity,设定stop-color 色彩的透明度。

如果将色标的地位拉近:

<linearGradient id="gradient-1">
    <stop offset="30%" stop-color="#DCE35B" />
    <stop offset="70%" stop-color="#45B649" />
</linearGradient>


矩形右边的 30% 区域被填充为 #DCE35B 实色,而左边 30% 区域被填充为 #45B649 实色。真正的突变只呈现在矩形两头 40% 的区域。

如果两个色彩都设为 50%,就失去了两块均分矩形的实色。在这根底上,咱们能够生成各种色彩的条纹图案。

突变的方向和范畴

在没有设置突变方向的时候,突变的默认方向是从左向右。

如果要设定突变方向,要用到 <linearGradient>x1,y1,x2,y2这几个属性。

<linearGradient id="gradient-1" x1="0" y1="0" x2="0" y2="1">
    <stop offset="0%" stop-color="#DCE35B" />
    <stop offset="100%" stop-color="#45B649" />
</linearGradient>

咱们晓得,在立体上,方向个别由向量来示意。而突变的方向由(x1,y1)(终点)和(x2,y2)(点)两个点定义的向量来示意。

在个别的利用场景中,x1,y1,x2,y2的取值范畴是[0,1](或者用百分数[0%, 100%])。

对于矩形而言,不论矩形的长宽比例是多少,它的左上角对应的都是(0,0),右下角则对应(1,1)

x1="0" y1="0" x2="0" y2="1"示意从 (0,0)(0,1),即突变方向从矩形上边框垂直向下到下边框。

x1="0" y1="0.3" x2="0" y2="0.7"的情景如下:

能够看出,x1,y1,x2,y2不仅决定突变的方向,还决定了突变的范畴,超出突变范畴的局部由起始或完结色标的色彩进行纯色填充。

案例 1:突变文字

<svg width="600" height="270">
    <defs>
        <linearGradient id="background">                          <!-- 背景渐变色 -->
            <stop offset="0%" stop-color="#232526" />
            <stop offset="100%" stop-color="#414345" />
        </linearGradient>
        <linearGradient id="text-color" x1="0" y1="0" x2="0" y2="100%"> <!-- 文字渐变色 -->
            <stop offset="0%" stop-color="#DCE35B" />
            <stop offset="100%" stop-color="#45B649" />
        </linearGradient>
    </defs>
    <rect x="0" y="0" height="100%" width="100%" fill="url(#background)"></rect>
    <text y="28%" x="28%"> 试问闲情都几许?</text>
    <text y="44%" x="28%"> 一川烟草 </text>
    <text y="60%" x="28%"> 满城风絮 </text>
    <text y="76%" x="28%"> 梅子黄时雨 </text>
</svg>
<style>
    text{
        font-size: 32px;
        letter-spacing:5px;
        fill:url(#text-color);     // 文字的填充应用渐变色
    }
</style>

文字的填充,咱们用了垂直方向的渐变色,对于每一行文字,都是从黄色突变到绿色。

如果要将这几行文字作为一个整体来设置渐变色,像上面这样,应该怎么设置呢?

这就要用到 gradientUnits 属性了。

gradientUnits属性定义突变元素(<linearGradient><radialGradient>)要参考的坐标系。 它有两个取值:objectBoundingBoxuserSpaceOnUse

默认值是 objectBoundingBox,它定义突变元素的参考坐标系为 援用该突变的 SVG 元素 ,突变的起止、范畴、方向都是基于援用该突变的 SVG 元素(之前的<rect>,这里的<text>)本身,比方这里的每一个<text> 元素的左上角都是渐变色的 (0,0) 地位,右下角都是(100%,100%)

userSpaceOnUse则以 以后的 SVG 元素视窗区域(viewport) 为突变元素的参考坐标系。也就是 SVG 元素的左上角为渐变色的 (0,0) 地位,右下角为(100%,100%)

<svg height="200" width="300"> 
    <defs>
        <!-- 定义两个突变,除了 gradientUnits,其余配置完全相同 -->
        <linearGradient id="gradient-1" x1="0" y1="0" x2="100%" y2="100%" gradientUnits="objectBoundingBox">
            <stop offset="0%" stop-color="#C6FFDD" />
            <stop offset="100%" stop-color="#f7797d" />
        </linearGradient>
        <linearGradient id="gradient-2" x1="0" y1="0" x2="100%" y2="100%" gradientUnits="userSpaceOnUse">
            <stop offset="0%" stop-color="#C6FFDD" />
            <stop offset="100%" stop-color="#f7797d" />
        </linearGradient>
    </defs>
    <rect x="0" y="0" ></rect>
    <rect x="150" y="0" ></rect>
    <rect x="0" y="100" ></rect>
    <rect x="150" y="100" ></rect>
</svg>
rect{
    height: 100px;
    width: 150px;
    fill: url(#gradient-1); // 四个矩形都填充渐变色,上面左图为 gradient-1,右图为 gradient-2。}


gradientUnits:userSpaceOnUse 实用于画布中有多个图形,但每个图形都是整体突变中的一部分这样的场景。值得注意的是,当 gradientUnits="userSpaceOnUse" 时,x1,y1,x2,y2的取值只有用 % 百分数这样的绝对单位才示意比例,如果取值为 x2="1",那就真的是1px,这一点与gradientUnits="objectBoundingBox" 是不同的。

案例 2:突变的环形进度条

在上一篇文章中,咱们实现了可交互的环形进度条:

这里咱们将其革新成突变的环形进度条。


应用渐变色作为描边 stroke 的色彩,两头应用一个红色透明度突变的圆,减少立体感。

<!-- 改变局部的代码 -->
<svg height="240" width="240" viewBox="0 0 100 100">
    <defs>
        <linearGradient id="circle">
            <stop offset="0%" stop-color="#A5FECB" />
            <stop offset="50%" stop-color="#20BDFF" />
            <stop offset="100%" stop-color="#5433FF" />
        </linearGradient>
        <linearGradient id="center">
            <stop offset="0%" stop-color="rgba(255,255,255,0.25)" />
            <stop offset="100%" stop-color="rgba(255,255,255,0.08)" />
         </linearGradient>
     </defs>
     <!-- 灰色的背景圆环 -->
     <circle cx="50" cy="50" r="40" stroke-width="12" stroke="#eee" fill="none"></circle>
     <!-- 突变的动静圆环 -->
     <circle       
         class="process-circle" 
         cx="50" cy="50" r="40" 
         transform="rotate(-90 50 50)"
         stroke-width="12" 
         stroke="url(#circle)" 
         fill="none" 
         stroke-linecap="round"
         stroke-dasharray="251"></circle>
     <!-- 红色透明度突变的圆,减少立体感 -->
     <circle cx="50" cy="50" r="40" fill="url(#center)"></circle>
</svg> 

径向突变

根底应用

径向突变是色调从中心点向周围辐射的突变。

<svg height="300" width="200">
    <defs>
        <radialGradient id="test">
            <stop offset="0%" stop-color="#e1eec3" />
            <stop offset="100%" stop-color="#f05053" />
        </radialGradient>
    </defs>
    <rect fill="url(#test)" x="10" y="10" width="150" height="150"></rect>
</svg>

和线性突变的构造相似,咱们将径向突变标签 <radialGradient> 定义在 <defs> 元素中,其 id 属性作为其惟一标识,以便前面须要应用的中央对其进行援用。

<radialGradient>中的 <stop> 标签定义渐变色的色标,它的 offset 和 stop-color 属性别离定义色标的地位和色彩值。

突变的范畴

径向突变的范畴由 <radialGradient>cx,cy,r三个属性独特决定,它们的默认值均是 50%,是相对值,绝对的是 援用该突变的 SVG 元素

cxcy 定义径向突变范畴的圆心,(50%, 50%)意味着是 援用该突变的 SVG 元素 的核心。r设定突变范畴的半径,当 r=50% 时,阐明突变范畴的半径在 xy方向的别离是 援用该突变的 SVG 元素 widthheight的 50%。

// 当 rect 高度减小时,突变在 y 方向的半径也减小。<rect fill="url(#test)" x="10" y="10" width="150" height="100"></rect>


cx,cy,r 都取默认值的状况下,径向突变的范畴刚好笼罩援用该突变的 SVG 元素。理论开发中,咱们经常须要调整突变范畴。

突变终点的挪动

在默认状况下,突变终点都是在突变范畴的核心,如果想要不那么对称的突变,就须要扭转突变终点的地位。

<radialGradient>fxfy就是用来设置渐变色起始地位的。fxfy 的值也是相对值,绝对的也是 援用该突变的 SVG 元素

咱们能够设定突变的范畴(cx,cy,r),也能够设定突变的终点地位(fx,fy)。然而如果突变的终点地位在突变的范畴之外,会呈现一些咱们不想要的成果。

测试代码如下,可间接运行:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body{
            display: flex;
            justify-content: center;
        }
        .control{margin-top:20px;}
    </style>
</head>
<body>
    <svg height="300" width="200">
        <defs>
            <radialGradient  id="test">
                <stop offset="0%" stop-color="#e1eec3" />
                <stop offset="100%" stop-color="#f05053" />
            </radialGradient>
        </defs>
        <rect fill="url(#test)" x="10" y="10" width="150" height="150"></rect>
    </svg>
    <div class="control">
        <div>cx:<input value="50" type="range" min="0" max="100" id="cx" /></div>
        <div>cy:<input value="50" type="range" min="0" max="100" id="cy" /></div>
        <div>r:<input value="50" type="range" min="0" max="100" id="r" /></div>
        <div>fx:<input value="50" type="range" min="0" max="100" id="fx" /></div>
        <div>fy:<input value="50" type="range" min="0" max="100" id="fy" /></div>
    </div>
    <script>
        const rg = document.getElementById('test')
        document.querySelectorAll('input').forEach((elem) => {elem.addEventListener('change', (ev) => {rg.setAttribute(ev.target.id, ev.target.value+'%')
            })
        })
    </script>
</body>
</html>

综合案例:通明的泡泡

最初咱们用线性突变和径向突变画一个泡泡。

剖析:

  • 背景是一个用线性突变填充的矩形。
  • 泡泡分为三个局部:由径向突变填充的一个圆形和两个椭圆。

这里的径向突变次要是色彩透明度的突变。设定色彩透明度,咱们能够间接指定 stop-color 的值为 rgba,也能够通过stop-opacity 来设定 stop-color 色彩的透明度。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .bubble{
            animation: move 5s linear infinite;
            animation-direction:alternate;
        }
        // 泡泡的静止
        @keyframes move {
            0%{transform: translate(0,0);
            }
            50%{transform: translate(250px,220px);
            }
            100%{transform: translate(520px,50px);
            }
        }
    </style>
</head>
<body>
    <svg height="400" width="700">
        <defs>
            <!-- 背景的线性突变 -->
            <linearGradient id="background">
                <stop offset="0%" stop-color="#DCE35B" />
                <stop offset="100%" stop-color="#45B649" />
            </linearGradient>
            <!-- 光斑的径向突变,通过 fx、fy 设置不对称的突变 -->
            <radialGradient id="spot" fx="50%" fy="30%">
                <stop offset="10%" stop-color="white" stop-opacity=".7"></stop>  
                <stop offset="70%" stop-color="white" stop-opacity="0"></stop>
            </radialGradient>
            <!-- 泡泡本体的径向突变 -->
            <radialGradient id="bubble">
                <stop offset="0%" stop-color="rgba(255,255,255,0)" ></stop>  
                <stop offset="80%" stop-color="rgba(255,255,255,0.1)" ></stop>
                <stop offset="100%" stop-color="rgba(255,255,255,0.42)"></stop>
            </radialGradient>
        </defs>
        <rect fill="url(#background)" width="100%" height="100%"></rect>
        <g class="bubble">
            <circle cx="100" cy="100" r="70" fill="url(#bubble)"></circle>
            <ellipse rx="50" ry="20" cx="80" cy="60" fill="url(#spot)" transform="rotate(-25, 80, 60)" ></ellipse>
            <ellipse rx="20" ry="10" cx="140" cy="130" fill="url(#spot)" transform="rotate(125, 140, 130)" ></ellipse>
        </g>   
    </svg>
</body>
</html>

以上突变配色均来自网站:https://uigradients.com/

退出移动版