@[TOC]svg实现实时流动图
用svg绘制路径并实现路径动画
SVG,可缩放矢量图形(Scalable Vector Graphics),是一种用于描述二维图形的 XML 标记语言。
与位图图像不同,SVG 图像以文本形式存储,并且可以缩放到任意大小而不会失真,因为它们基于数学描述而不是像素。
svg使用详解
- 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值的渐变来描边这个路径
- 路径---- 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>
属性解析:
- d 属性定义了路径的路径数据,即路径命令序列。路径数据由一系列的路径命令组成,每个路径命令以字母开头,后面跟随一组数字参数。常用的路径命令包括:M(移动到)、L(直线到)、H(水平线到)、V(垂直线到)、C(三次贝塞尔曲线)、S(光滑曲线)、Q(二次贝塞尔曲线)、T(光滑二次贝塞尔曲线)、A(圆弧)、Z(闭合路径)等。
- fill 属性定义了路径的填充颜色。
- stroke 属性定义了路径的描边颜色。
- stroke-width 属性定义了路径的描边宽度。
注意: 命令是大小写敏感的。大写的命令指定绝对坐标,而小写命令指定相对(于当前位置的)坐标。
–绝对坐标中,负的 x 和 y 将被解释为负坐标;
–相对坐标中,负的 x 值为向左移动,负的 y 值为向上移动
- 定义一个元素如何沿着运动路径进行移动---- 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>
备注: 为了复用一个已经定义的路径,就有必要使用一个
元素的mpath子元素使 元素能够引用一个外部的
令mpath的#href值等于外部path的id
- 动画元素放在形状元素的内部,用来定义一个元素的某个属性如何踩着时点改变。在指定持续时间里,属性从开始值变成结束值----- 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 轴上的位置来变动这个矩形
- 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>