阿西河

所有教程

公众号
🌙
阿西河前端的公众号

我的收藏

    最近访问  (文章)

      教程列表

      抓包专区
      测试专区

      SVG 渐变 - 径向

      SVG 渐变- 放射性


      SVG 放射性渐变 - <radialGradient>

      <radialGradient>元素用于定义放射性渐变。

      <radialGradient>标签必须嵌套在<defs>的内部。

      <defs>标签是definitions的缩写,它可对诸如渐变之类的特殊元素进行定义。


      实例 定义一个放射性渐变从白色到蓝色椭圆:

      下面是SVG代码:

      <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
        <defs>
          <radialGradient id="grad1" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
            <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:0" />
            <stop offset="100%" style="stop-color:rgb(0,0,255);stop-opacity:1" />
          </radialGradient>
        </defs>
        <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
      </svg>
      

      代码解析:

      • <radialGradient>标签的 id 属性可为渐变定义一个唯一的名称
      • CX,CY和r属性定义的最外层圆和Fx和Fy定义的最内层圆
      • 渐变颜色范围可以由两个或两个以上的颜色组成。每种颜色用一个<stop>标签指定。offset属性用来定义渐变色开始和结束
      • 填充属性把ellipse元素链接到此渐变

      实例 定义放射性渐变从白色到蓝色的另一个椭圆:

      下面是SVG代码:

      <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
        <defs>
          <radialGradient id="grad2" cx="20%" cy="30%" r="30%" fx="50%" fy="50%">
            <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:0" />
            <stop offset="100%" style="stop-color:rgb(0,0,255);stop-opacity:1" />
          </radialGradient>
        </defs>
        <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad2)" />
      </svg>
      

      示例

      <?xml version="1.0" standalone="no"?>
      <svg width="120" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
        <defs>
            <radialGradient id="RadialGradient1">
              <stop offset="0%" stop-color="red"/>
              <stop offset="100%" stop-color="blue"/>
            </radialGradient>
            <radialGradient id="RadialGradient2" cx="0.25" cy="0.25" r="0.25">
              <stop offset="0%" stop-color="red"/>
              <stop offset="100%" stop-color="blue"/>
            </radialGradient>
        </defs>
       
        <rect x="10" y="10" rx="15" ry="15" width="100" height="100" fill="url(#RadialGradient1)"/> 
        <rect x="10" y="120" rx="15" ry="15" width="100" height="100" fill="url(#RadialGradient2)"/> 
        
      </svg>
      

      中值(stops)的使用方法与之前一致,但是现在这个对象的颜色是中间是红色的,且向着边缘的方向渐渐的变成蓝色。跟线性渐变一样,<radialGradient> 节点可以有多个属性来描述其位置和方向,但是它更加复杂。径向渐变也是通过两个点来定义其边缘位置,两点中的第一个点定义了渐变结束所围绕的圆环,它需要一个中心点,由cx和cy属性及半径r来定义,通过设置这些点我们可以移动渐变范围并改变它的大小,如上例的第二个所展示的。

      第二个点被称为焦点,由fx和fy属性定义。第一个点描述了渐变边缘位置,焦点则描述了渐变的中心,如下例。

      中心和焦点

      <?xml version="1.0" standalone="no"?>
      
      <svg width="120" height="120" version="1.1"
        xmlns="http://www.w3.org/2000/svg">
        <defs>
            <radialGradient id="Gradient"
                  cx="0.5" cy="0.5" r="0.5" fx="0.25" fy="0.25">
              <stop offset="0%" stop-color="red"/>
              <stop offset="100%" stop-color="blue"/>
            </radialGradient>
        </defs>
       
        <rect x="10" y="10" rx="15" ry="15" width="100" height="100"
              fill="url(#Gradient)" stroke="black" stroke-width="2"/>
      
        <circle cx="60" cy="60" r="50" fill="transparent" stroke="white" stroke-width="2"/>
        <circle cx="35" cy="35" r="2" fill="white" stroke="white"/>
        <circle cx="60" cy="60" r="2" fill="white" stroke="white"/>
        <text x="38" y="40" fill="white" font-family="sans-serif" font-size="10pt">(fx,fy)</text>
        <text x="63" y="63" fill="white" font-family="sans-serif" font-size="10pt">(cx,cy)</text>
        
      </svg>
      
      

      因为如果焦点如之前描述的那样被移到圆圈的外面,渐变将不能正确呈现,所以该点会被假定在圆圈范围内。如果没有给出焦点,将认为该点与中心点的位置一致。

      线性渐变和径向渐变都需要一些额外的属性用于描述渐变过程,这里我希望额外提及一个spreadMethod属性,该属性控制了当渐变到达终点的行为,但是此时该对象尚未被填充颜色。这个属性可以有三个值:pad、reflect或repeat。Pad就是目前我们见到的效果,即当渐变到达终点时,最终的偏移颜色被用于填充对象剩下的空间。

      reflect会让渐变一直持续下去,不过它的效果是与渐变本身是相反的,以100%偏移位置的颜色开始,逐渐偏移到0%位置的颜色,然后再回到100%偏移位置的颜色。repeat也会让渐变继续,但是它不会像reflect那样反向渐变,而是跳回到最初的颜色然后继续渐变。

      spreadMethod

      <?xml version="1.0" standalone="no"?>
      
      <svg width="220" height="220" version="1.1" xmlns="http://www.w3.org/2000/svg">
        <defs>
            <radialGradient id="GradientPad"
                  cx="0.5" cy="0.5" r="0.4" fx="0.75" fy="0.75"
                  spreadMethod="pad">
              <stop offset="0%" stop-color="red"/>
              <stop offset="100%" stop-color="blue"/>
            </radialGradient>
            <radialGradient id="GradientRepeat"
                  cx="0.5" cy="0.5" r="0.4" fx="0.75" fy="0.75"
                  spreadMethod="repeat">
              <stop offset="0%" stop-color="red"/>
              <stop offset="100%" stop-color="blue"/>
            </radialGradient>
            <radialGradient id="GradientReflect"
                  cx="0.5" cy="0.5" r="0.4" fx="0.75" fy="0.75"
                  spreadMethod="reflect">
              <stop offset="0%" stop-color="red"/>
              <stop offset="100%" stop-color="blue"/>
            </radialGradient>
        </defs>
      
        <rect x="10" y="10" rx="15" ry="15" width="100" height="100" fill="url(#GradientPad)"/>
        <rect x="10" y="120" rx="15" ry="15" width="100" height="100" fill="url(#GradientRepeat)"/>
        <rect x="120" y="120" rx="15" ry="15" width="100" height="100" fill="url(#GradientReflect)"/>
      
        <text x="15" y="30" fill="white" font-family="sans-serif" font-size="12pt">Pad</text>
        <text x="15" y="140" fill="white" font-family="sans-serif" font-size="12pt">Repeat</text>
        <text x="125" y="140" fill="white" font-family="sans-serif" font-size="12pt">Reflect</text>
      
      </svg>
      

      两种渐变都有一个叫做 gradientUnits(渐变单元)的属性,它描述了用来描述渐变的大小和方向的单元系统。该属性有两个值:userSpaceOnUse 、objectBoundingBox。默认值为objectBoundingBox,我们目前看到的效果都是在这种系统下的,它大体上定义了对象的渐变大小范围,所以你只要指定从0到1的坐标值,渐变就会自动的缩放到对象相同大小。userSpaceOnUse使用绝对单元,所以你必须知道对象的位置,并将渐变放在同样地位置上。上例中的radialGradient需要被重写成:

      <radialGradient id="Gradient" cx="60" cy="60" r="50" fx="35" fy="35" gradientUnits="userSpaceOnUse">
      

      你也可以利用属性gradientTransform给渐变添加额外的变化,但是因为我们还没有介绍transforms,所以我们将在后续的章节中介绍它。

      如果对象边界框不是一个正方形,处理gradientUnits=“objectBoundingBox"还有一些其他警告,但是这些方法特别复杂因此有待一些了解得更深的人来解释他们。

      目录
      目录