svg实现实时流动图

@[TOC]svg实现实时流动图

用svg绘制路径并实现路径动画

SVG,可缩放矢量图形(Scalable Vector Graphics),是一种用于描述二维图形的 XML 标记语言。

与位图图像不同,SVG 图像以文本形式存储,并且可以缩放到任意大小而不会失真,因为它们基于数学描述而不是像素。

svg使用详解

  1. svg渐变线性---- linearGradient
<svg version="1.1" class="dpB" :style="{ width: svgWidth + 'px', height: svgHeight + 'px' }">
             <!-- 定义线性渐变 -->
             <linearGradient id="gradientMotionPath2" x1="0%" y1="0%" x2="100%" y2="100%" gradientUnits="userSpaceOnUse">
              <stop offset="0%" style="stop-color: rgba(45, 0, 255, 1)"></stop>
              <stop offset="100%" style="stop-color: rgba(225, 217, 255, 1)"></stop>
            </linearGradient>
            
            <path id="motionPath2" fill="none" :d="pathData3" stroke="url(#gradientMotionPath2)" stroke-width="2" stroke-dasharray="0"
              stroke-linecap="round" class="polyLine">
            </path>
</svg>

代码解析:

  • 标签的id属性可为渐变定义一个唯一的名称
  • 标签的X1,X2,Y1,Y2属性定义渐变起始点坐标和结束点坐标
  • 渐变的颜色范围可由两种或多种颜色组成。渐变中可以包含多个 元素,每个 元素表示渐变中的一个颜色和位置。offset属性用来定义渐变的开始和结束位置。
  • 填充属性把 ellipse 元素链接到此渐变
  • stroke: 设置路径的描边颜色。告诉path使用指定ID值的渐变来描边这个路径
  1. 路径---- path 。使用 元素可以绘制直线、曲线、弧线等各种复杂的图形,并且可以通过设置路径命令来控制路径的形状和样式。

<svg
  width="200"     <!-- 指定SVG画布的宽度 -->
  height="200"    <!-- 指定SVG画布的高度 -->
  xmlns="http://www.w3.org/2000/svg">   <!-- 指定SVG命名空间 -->
     <path
       d="path-data"            <!-- 定义路径的路径数据 -->
       fill="fill-color"        <!-- 路径的填充颜色 -->
       stroke="stroke-color"    <!-- 路径的描边颜色 -->
       stroke-width="width"     <!-- 路径的描边宽度 -->
       stroke-linecap="round"   <!-- 用于定义不同类型的开放数据的终结--路径两端是圆形还是方形 -->
     />
</svg>

属性解析:

  1. d 属性定义了路径的路径数据,即路径命令序列。路径数据由一系列的路径命令组成,每个路径命令以字母开头,后面跟随一组数字参数。常用的路径命令包括:M(移动到)、L(直线到)、H(水平线到)、V(垂直线到)、C(三次贝塞尔曲线)、S(光滑曲线)、Q(二次贝塞尔曲线)、T(光滑二次贝塞尔曲线)、A(圆弧)、Z(闭合路径)等。
  2. fill 属性定义了路径的填充颜色。
  3. stroke 属性定义了路径的描边颜色。
  4. stroke-width 属性定义了路径的描边宽度。

注意: 命令是大小写敏感的。大写的命令指定绝对坐标,而小写命令指定相对(于当前位置的)坐标。
–绝对坐标中,负的 x 和 y 将被解释为负坐标;
–相对坐标中,负的 x 值为向左移动,负的 y 值为向上移动

  1. 定义一个元素如何沿着运动路径进行移动---- animateMotion 元素
 <path
    id="path1"
    d="M100,250 C 100,50 400,50 400,250"
    fill="none"
    stroke="blue"
    stroke-width="7.06" />
  <circle cx="100" cy="250" r="17.64" fill="blue" />

  <path
    d="M-25,-12.5 L25,-12.5 L 0,-87.5 z"
    fill="yellow"
    stroke="red"
    stroke-width="7.06">
    <animateMotion dur="6s" repeatCount="indefinite" rotate="auto">
      <mpath href="#path1" />
    </animateMotion>

备注: 为了复用一个已经定义的路径,就有必要使用一个 元素嵌入到 中,而不是使用 path。
元素的mpath子元素使 元素能够引用一个外部的 元素作为运动路径的定义。
令mpath的#href值等于外部path的id

  1. 动画元素放在形状元素的内部,用来定义一个元素的某个属性如何踩着时点改变。在指定持续时间里,属性从开始值变成结束值----- animate
<svg width="250" height="250"
  viewPort="0 0 250 250" version="1.1"
  xmlns="http://www.w3.org/2000/svg">
  <rect x="50" y="50" width="100" height="100">
    <animate attributeType="XML"
      attributeName="y"
      from="0" to="50"
      dur="5s"/>
  </rect>
</svg>

attributeName:该属性标识了在一个动画动作环节中,父元素的需要被改变的属性名。下面的示例使用了 y 作为attributeName,通过改变一个矩形在 Y 轴上的位置来变动这个矩形

  1. SVG 提供了一系列的图形元素来绘制各种形状的图形,如矩形、圆形、直线、多边形等。

矩形(Rectangles):使用 元素绘制矩形,可以指定矩形的位置、大小、圆角等属性。

<rect x="50" y="50" width="100" height="50" rx="10" ry="10" fill="blue" />

圆形(Circles):使用 元素绘制圆形,可以指定圆心坐标和半径。

<circle cx="100" cy="100" r="50" fill="red" />

椭圆(Ellipses):使用 元素绘制椭圆,可以指定椭圆的中心坐标和长短轴的半径。

<ellipse cx="100" cy="100" rx="80" ry="50" fill="green" />

直线(Lines):使用 元素绘制直线,需要指定起点和终点坐标。

<line x1="50" y1="50" x2="150" y2="150" stroke="black" stroke-width="2" />

多边形(Polygons):使用 元素绘制多边形,需要指定多个顶点的坐标。

<polygon points="100,50 150,150 50,150" fill="orange" />

折线(Polylines):使用 元素绘制折线,需要指定多个点的坐标。

<polyline points="100,50 150,150 50,150" fill="none" stroke="blue" stroke-width="2" />

路径(Paths):使用 元素绘制路径,可以通过指定一系列的路径命令来绘制各种形状。

<path d="M10 10 L90 10 L90 90 Z" fill="none" stroke="black" stroke-width="2" />

svg路径流动实际案例:

根据各个数据的正负判断流动的方向。通过(getBoundingClientRect)获取每个元素相对于视口的位置信息,计算每块svg的宽度和高度。主要是通过绝对定位指定每块画布的位置,然后计算每条svg路径的关键点,画出路径之后通过(animateMotion)元素定义了一个元素如何沿着运动路径进行移动。

        <div class="posA" name="负载" style="top: 150px; right: 270px;">
          <svg version="1.1" class="dpB" :style="{ width: svgWidth + 'px', height: svgHeight + 'px' }">
             <!-- 定义线性渐变 -->
             <linearGradient id="gradientMotionPath2" x1="0%" y1="0%" x2="100%" y2="100%" gradientUnits="userSpaceOnUse">
              <stop offset="0%" style="stop-color: rgba(45, 0, 255, 1)"></stop>
              <stop offset="100%" style="stop-color: rgba(225, 217, 255, 1)"></stop>
            </linearGradient>
            <path id="motionPath2" fill="none" :d="pathData3" stroke="url(#gradientMotionPath2)" stroke-width="2" stroke-dasharray="0"
              stroke-linecap="round" class="polyLine">
            </path>

            <circle r="4" fill="blue">
              <!-- <animateMotion> 元素定义了一个元素如何沿着运动路径进行移动。 -->
              <animateMotion dur="3s" repeatCount="indefinite" :path="pathData3" rotate="auto"
                animation-direction="reverse">
                <mpath href="#motionPath2" />
              </animateMotion>
              <!-- 使用 <animate> 元素定义图形的颜色如何在移动过程中进行渐变 -->
              <animate attributeName="fill" values="#6241FC; #C3B7FF" dur="3s" repeatCount="indefinite" />
            </circle>
          </svg>
        </div>
        <!-- :style="{bottom: (150 + svgHeight) + 'px', left: '270px'}"  style="top: 258px; left: 270px;"-->
        <div class="posA" name="HINEN" :style="`top: ${150 + svgHeight + 30}px ; left: 270px`">
          <svg version="1.1" class="dpB" :style="{ width: svgWidth + 'px', height: svgHeight + 'px' }">
            <!-- 定义线性渐变 -->
            <linearGradient id="positiveGradientId3" x1="0%" y1="0%" x2="100%" y2="100%" gradientUnits="userSpaceOnUse">
              <stop offset="0%" style="stop-color: rgba(149, 239, 255, 1)"></stop>
              <stop offset="100%" style="stop-color: rgba(0, 166, 214, 1)"></stop>
            </linearGradient>
            <!-- <linearGradient id="negativeGradientId3" x1="100%" y1="100%" x2="0%" y2="0%" gradientUnits="userSpaceOnUse">
              <stop offset="0%" style="stop-color: rgba(0, 166, 214, 1)"></stop>
              <stop offset="100%" style="stop-color: rgba(149, 239, 255, 1)"></stop>
            </linearGradient> -->
            <!-- :stroke="batteryPower > 0 ? 'url(#positiveGradientId3)' : 'url(#negativeGradientId3)'" -->
            <path id="motionPath3" fill="none" :d="batteryPower > 0 ? pathData3 : pathData31" stroke="url(#positiveGradientId3)"
              stroke-width="2" stroke-dasharray="0" stroke-linecap="round" class="polyLine">
            </path>
            <circle r="4" fill="blue">
              <!-- <animateMotion> 元素定义了一个元素如何沿着运动路径进行移动。 -->
              <animateMotion dur="3s" repeatCount="indefinite" :path="pathData3" rotate="auto"
                animation-direction="reverse">
                <mpath href="#motionPath3" />
              </animateMotion>
              <!-- 使用 <animate> 元素定义图形的颜色如何在移动过程中进行渐变 -->
              <animate attributeName="fill" :values="batteryPower > 0 ? '#41D5FF; #00ACDD' : '#00ACDD; #41D5FF'" dur="3s" repeatCount="indefinite" />
            </circle>
          </svg>
        </div>
        <div class="posA" name="电网" :style="`top: ${150 + svgHeight + 30}px ; right: 270px`">
          <svg version="1.1" class="dpB" :style="{ width: svgWidth + 'px', height: svgHeight + 'px' }">
            <!-- 定义线性渐变 -->
            <linearGradient id="positiveGradientId4" x1="0%" y1="0%" x2="100%" y2="100%" gradientUnits="userSpaceOnUse">
              <stop offset="0%" style="stop-color: rgba(0, 162, 90, 1)"></stop>
              <stop offset="100%" style="stop-color: rgba(14, 249, 190, 1);"></stop>
            </linearGradient>
            <!-- <linearGradient id="negativeGradientId4" x1="100%" y1="100%" x2="0%" y2="0%" gradientUnits="userSpaceOnUse">
              <stop offset="0%" style="stop-color: rgba(0, 162, 90, 1)"></stop>
              <stop offset="100%" style="stop-color: rgba(14, 249, 190, 1);"></stop>
            </linearGradient> -->
            <!-- stroke: 设置路径的描边颜色。告诉SVG引擎使用ID为gradientMotionPath4的渐变来描边这个路径 -->
            <!-- :stroke="totalGridPower > 0 ? 'url(#positiveGradientId4)' : 'url(#negativeGradientId4)'" -->
            <path id="motionPath4" fill="none" :d="totalGridPower > 0 ? pathData1 : pathData4" stroke="url(#positiveGradientId4)"
              stroke-width="2" stroke-dasharray="0" stroke-linecap="round" class="polyLine">
            </path>

            <circle r="4" fill="blue" style="animation-direction: reverse;">
              <!-- <animateMotion> 元素定义了一个元素如何沿着运动路径进行移动。 -->
              <animateMotion dur="3s" repeatCount="indefinite" :path="pathData4" rotate="auto"
                style="animation-direction: reverse">
                <mpath href="#motionPath4" style="animation-direction: reverse" />
              </animateMotion>
              <!-- 使用 <animate> 元素定义图形的颜色如何在移动过程中进行渐变 -->
              <animate attributeName="fill" :values="totalGridPower > 0 ? '#01A15A; #00EC83' :  '#00EC83; #01A15A'" dur="3s" repeatCount="indefinite"
                style="animation-direction:reverse " />
            </circle>

          </svg>
        </div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值