概要:本文主要介绍在数据大屏项目中关于svg重要的两个组件的开发思路,实现源码,以及实现过程中用到的svg的放射性渐变radialGradient相关的介绍。
loading组件
期望得到的效果:
实现思路:
- 两个圆,外圆半径大于内圆半径来实现,外部圆包含着内部圆。
- 通过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>
飞线矩阵
期望得到类似的效果
实现思路
- 核心就是利用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>
蒙板的使用方法:
定义蒙版: 定义蒙板的标签 填充色等<\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>
使用蒙板后效果:
渐变色相关的知识
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>
放射性渐变
相同的代码,只是使用的是放射性渐变,效果完全不一样
<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>
放射性渐变是从一个点开始发散绘制渐变,不设置的话默认是从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>
<radialGradient>
节点可以有多个属性来描述其位置和方向,但是它更加复杂。
<radialGradient>
渐变是通过两个点来定义其边缘位置:
第一个点定义了渐变结束所围绕的圆环,它需要一个中心点,由cx和cy属性及半径r来定义。通过设置这些点我们可以移动渐变范围并改变它的大小。
第二个点被称为焦点,由fx和fy属性定义。第一个点描述了渐变边缘位置,焦点则描述了渐变的中心
组件飞线矩形实现代码
<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>