Cómo embellecer sus diagramas, ¡todo lo que necesita saber sobre los degradados SVG!

Los degradados se pueden ver en casi todas partes en el diseño web. Los fondos degradados, el texto, los botones, los gráficos, etc., son más flexibles y naturales que los colores sólidos.

Lo que vamos a discutir hoy es SVGel dibujo de degradado en formato .

Más SVGartículos de la serie: Conceptos básicos de SVG, Animación SVG , Transformar en SVG .

Visión de conjunto

Tal vez tenga cssexperiencia en dibujar gráficos degradados. Si desea dibujar un rectángulo degradado, podemos escribir:

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

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

Con SVGel dibujo, el color se logra configurando las propiedades fill(color de relleno) y stroke(color del borde) del elemento.

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

imagen.pngPara la configuración del color del degradado, no podemos cssescribirlo directamente como en fill="linear-gradient(color1, color2)", pero usamos etiquetas de degradado especiales: <linearGradient>(gradiente lineal) y <radialGradient>(gradiente radial).

Gradiente lineal

Uso básico

Primero veamos el ejemplo más simple, cómo dibujar un rectángulo de degradado lineal:

<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>
复制代码

imagen.pngPor lo general, definimos la etiqueta de degradado <linearGradient>en el <defs>elemento y <linearGradient>su idatributo se usa como su identificador único, lo cual es conveniente para referirse a él en el lugar donde debe usarse más adelante.

<linearGradient>La <stop>etiqueta en define la parada de color del degradado de color, y sus atributos offset y  stop-colordefinen la posición y el valor de color de la parada de color respectivamente, y también tiene un atributo stop-opacityque establece stop-colorla transparencia del color.

Si te mueves, el color se detiene más cerca:

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

imagen.pngEl área del 30 % a la izquierda del rectángulo se rellena con un color #DCE35Bsólido y el área del 30 % a la derecha se rellena con un #45B649color sólido. El gradiente real solo aparece en el medio 40% del rectángulo.

如果两个颜色都设为50%,就得到了两块均分矩形的实色。在这基础上,我们可以生成各种颜色的条纹图案。

imagen.png

渐变的方向和范围

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

如果要设定渐变方向,要用到<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)

imagen.png

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

x1="0" y1="0.3" x2="0" y2="0.7"的情形如下: imagen.png 可以看出,x1,y1,x2,y2不仅决定渐变的方向,还决定了渐变的范围,超出渐变范围的部分由起始或结束色标的颜色进行纯色填充。

案例1:渐变文字

imagen.png

<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>
复制代码

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

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

imagen.png

这就要用到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。
}
复制代码

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

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

上一篇文章中,我们实现了可交互的环形进度条: imagen.png 这里我们将其改造成渐变的环形进度条。

circulo-progreso.gif 使用渐变色作为描边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> 
复制代码

径向渐变

基础使用

径向渐变是色彩从中心点向四周辐射的渐变。

imagen.png

<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>
复制代码

imagen.pngcx,cy,r都取默认值的情况下,径向渐变的范围刚好覆盖引用该渐变的SVG元素。实际开发中,我们常常需要调整渐变范围。

progreso-ctrl-cxyr.gif

渐变起点的移动

在默认情况下,渐变起点都是在渐变范围的中心,如果想要不那么对称的渐变,就需要改变渐变起点的位置。

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

progreso-ctrl-fxyr.gif

我们可以设定渐变的范围(cx,cy,r),也可以设定渐变的起点位置(fx,fy)。但是如果渐变的起点位置在渐变的范围之外,会出现一些我们不想要的效果。

imagen.png

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

<!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>
复制代码

综合案例:透明的泡泡

最后我们用线性渐变和径向渐变画一个泡泡。

burbuja.gif

分析:

  • 背景是一个用线性渐变填充的矩形。
  • La burbuja se divide en tres partes: un círculo y dos elipses rellenas con degradados radiales.

El degradado radial aquí es principalmente un degradado de transparencia de color. Para establecer la transparencia del color, podemos especificar directamente stop-colorel valor rgba, o podemos stop-opacityestablecer stop-colorla transparencia del 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>
复制代码

Los colores degradados anteriores son todos del sitio web: uigradients.com/

Supongo que te gusta

Origin juejin.im/post/7098637240825282591
Recomendado
Clasificación