数据大屏(五):数据大屏项目中svg组件开发

1,668 阅读3分钟

概要:本文主要介绍在数据大屏项目中关于svg重要的两个组件的开发思路,实现源码,以及实现过程中用到的svg的放射性渐变radialGradient相关的介绍。

loading组件

期望得到的效果:

000-31.gif

实现思路:

  • 两个圆,外圆半径大于内圆半径来实现,外部圆包含着内部圆。
  • 通过svg的stroke-dasharray:4分之一的圆的周长,实现两段圆弧显示,两段圆弧不显示的效果。
  • 外圆和内圆作用域内都加上smil动画效果,改变旋转的角度rotate,需要用到animateTransform标签动画。内圆是顺时针旋转角度是0 360,外圆是逆时针旋转,角度是360 0,并且圆的旋转坐标都是围绕着内圆的中心坐标。
  • 利用stroke-linecap="round"属性剪裁路径两端的形状为圆形
  • 利用animate标签动画,改变内外层圆的颜色,让内外层颜色互相转换 最终代码如下:
     <svg :width="width" :height="height" viewBox="0 0 200 200" preserveAspectRatio="xMidYMid meet">
        <circle cx="100" cy="100" r="50" stroke-width="10" stroke="#02bcfe" fill="none" stroke-dasharray="79" stroke-linecap="round">
          <animateTransform
            attributeName="transform"
            type="rotate"
            values="0 100 100;360 100 100"
            dur="2s"
            repeatCount="indefinite"></animateTransform>
            <animate attributeName="stroke" :values="#02bcfe;#3be6cb;#02bcfe" dur="2s" repeatCount="indefinite" />
        </circle>
        <circle cx="100" cy="100" r="80" stroke-width="10" stroke="#3be6cb" fill="none" stroke-dasharray="126" stroke-linecap="round">
          <animateTransform
            attributeName="transform"
            type="rotate"
            values="360 100 100;0 100 100"
            dur="2s"
            repeatCount="indefinite">
          </animateTransform>
          <animate attributeName="stroke" values="#3be6cb;#02bcfe;#3be6cb" dur="2s" repeatCount="indefinite" />          
        </circle>
     </svg>

飞线矩阵

期望得到类似的效果

000-31.gif

实现思路

  • 核心就是利用svg蒙版遮罩的效果,圆的半径和矩形重合然后在圆上加动画,通过改变圆的半径,来改变运动在矩形上的长度。
  • 利用放射性颜色渐变渐变透明度来提亮飞线颜色的亮度。

svg蒙板相关知识讲解

不使用蒙版,下面的rect元素会覆盖掉上面的颜色变成黄色

    <svg width="200" height="200" viewBox="0 0 200 200">
      <rect x="0" y="0" width="200" height="390" fill="red"></rect>
      <rect x="0" y="0" width="200" height="390" fill="blue"></rect>
    </svg>

image.png

蒙板的使用方法:

定义蒙版: 定义蒙板的标签 填充色等<\mask><\defs> 使用蒙版:在svg元素上使用,mask=url(#蒙板id)

    <svg width="200" height="200" viewBox="0 0 200 200">
      <defs>
        <mask id="test-mask">
          <!-- 填充色 -->
          <rect x="5" y="5" width="50" height="50" fill="green"></rect>
        </mask>
      </defs>
      <rect x="0" y="0" width="200" height="200" fill="red"></rect>
      <rect x="0" y="0" width="200" height="200" fill="blue" mask="url(#test-mask)"></rect>
    </svg>

使用蒙板后效果:

image.png

渐变色相关的知识

linearGradient

linearGradient元素用来定义线性渐变,用于图形元素的填充或描边

fill="url(#MyGradient)"表示通过id指向元素的颜色进行填充

stop元素:一个渐变上的颜色坡度,是用stop元素定义的。stop元素可以是<linearGradient>元素或者<radialGradient>元素的子元素。

<svg width="120" height="120"  viewBox="0 0 120 120">
    <defs>
        <linearGradient id="MyGradient">
            <stop offset="5%"  stop-color="green" stop-opacity="1" />
            <stop offset="95%" stop-color="gold" stop-opacity="0" />
        </linearGradient>
    </defs>
    <rect fill="url(#MyGradient)" x="10" y="10" width="100" height="100"/>
</svg>

image.png

放射性渐变

相同的代码,只是使用的是放射性渐变,效果完全不一样

    <svg width="120" height="120"  viewBox="0 0 120 120">
        <defs>
            <radialGradient id="MyGradient1">
                <stop offset="5%"  stop-color="green" stop-opacity="1" />
                <stop offset="95%" stop-color="gold" stop-opacity="0"/>
            </radialGradient>
        </defs>
        <rect fill="url(#MyGradient1)" x="10" y="10" width="100" height="100"/>
    </svg>  

image.png

放射性渐变是从一个点开始发散绘制渐变,不设置的话默认是从50% 50%开始,就是整个元素的中心点开始。

cx cy中心点,控制内圈开始辐射的范围,fx,fy焦点,控制外圈开始辐射的范围, 外圈是朝内圈坐标点投射

      <svg width="400" height="400" style="background: rgb(51, 6, 6);">
        <defs>
          <radialGradient id="test-radial-gradient" r="50%" cx="50%" cy="50%" fx="50%" fy="50%">
            <stop offset="0%" stop-color="white"></stop>
            <stop offset="10%" stop-color="yellow"></stop>
            <stop offset="95%" stop-color="red" stop-opacity="1"></stop>
            <stop offset="0%" stop-color="#fff" stop-opacity="1"></stop>
            <stop offset="100%" stop-color="#fff" stop-opacity="0"></stop>
          </radialGradient>
        </defs>
        <rect x="5" y="5" width="390" height="390" fill="url(#test-radial-gradient)"></rect>
      </svg>

image.png

<radialGradient> 节点可以有多个属性来描述其位置和方向,但是它更加复杂。 <radialGradient>渐变是通过两个点来定义其边缘位置:

第一个点定义了渐变结束所围绕的圆环,它需要一个中心点,由cx和cy属性及半径r来定义。通过设置这些点我们可以移动渐变范围并改变它的大小。

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

image.png

组件飞线矩形实现代码

    <svg  width="300" height="300" >
       <defs>
        <radialGradient id="radialGradientId1" r="50%" cx="50%" cy="50%" fx="100%" fy="50%">
          <stop offset="0%" stop-color="#fff" stop-opacity="1"></stop>
          <stop offset="100%" stop-color="#fff" stop-opacity="0"></stop>
        </radialGradient>         
         <mask id="maskIdTest">
          <circle r="50" cx="0" cy="0" fill="url(#radialGradientId1)">
            <animateMotion
              dur="3s"
              path="M0 0 L300 0  L300 300 L0 300 Z"
              rotate="auto"
              repeatCount="indefinite"
            ></animateMotion>   
          </circle>        
         </mask>
       </defs>
       <path id="pathWithMask" d="M0 0 L300 0  L300 300 L0 300 Z" fill="none" stroke-width="1" stroke="green"/>
       <path id="pathWithMask" d="M0 0 L300 0  L300 300 L0 300 Z" fill="none" stroke-width="3" stroke="blue" mask="url(#maskIdTest)"/>     
    </svg>

GIF 2021-7-21 19-24-42.gif