SVG定義
摘自維基百科:可縮放矢量圖形(英語:Scalable Vector Graphics潮针,SVG)是一種基于可擴(kuò)展標(biāo)記語言(XML),用于描述二維矢量圖形的圖形格式。SVG由W3C制定,是一個開放標(biāo)準(zhǔn)滨砍。
這些概念性的東西就不多講了,感興趣的自行去網(wǎng)絡(luò)查找妖异,或者參考文章末尾給出的鏈接惋戏。
SVG path 命令
- M = moveto
- L = lineto
- H = horizontal lineto
- V = vertical lineto
- C = curveto
- S = smooth curveto
- Q = quadratic Bézier curve
- T = smooth quadratic Bézier curveto
- A = elliptical Arc
- Z = closepath
比如:
M5 8 L100 0
的意思是:
移動到 point(5, 8) → 連線到point(100,0)
我們使用react-native-svg在react-native
中實(shí)現(xiàn)如下的效果:
進(jìn)度條效果圖

進(jìn)度條效果圖
直線進(jìn)度條
<Svg height="24" width="225">
<G fill="none" stroke="#3d5875">
<Path strokeLinecap="round" strokeWidth="8" d="M5 8 l215 0" />
</G>
<G fill="none" stroke="#00e0ff">
<Path strokeLinecap="round" strokeWidth="8" d="M5 8 l100 0"/>
</G>
</Svg>
參數(shù) | 解釋 |
---|---|
stroke="#3d5875" | 線條的顏色 |
strokeWidth="8" | 線條的寬度 |
strokeLinecap="round" | 線條的兩邊用圓角 |
d="M5 8 l215 0" | 背景線條充滿,總長度225 - 圓角長度5 * 2 = 215 |
d="M5 8 l100 0" | 前景線條的長度 |
直線進(jìn)度條效果圖
直線進(jìn)度條 + 動畫
// 1他膳,假設(shè)進(jìn)度是0~100
// 2响逢,線條的長度是 215(215 = 225 - 5 * 2)
let AnimatedPath = Animated.createAnimatedComponent(Path);
export default class AwesomeProject extends Component {
constructor(props)
{
super(props);
this.state = {
lineFillAnimation: new Animated.Value(0),
};
// 這里是動畫的映射關(guān)系
this.lineAnimation = this.state.lineFillAnimation.interpolate({
inputRange: [
0,
100
],
outputRange: [
`M5 8 l0 0`,
`M5 8 l215 0`,
]
});
}
componentDidMount()
{
this.startAnimation();
}
startAnimation()
{
this.state.lineFillAnimation.setValue(0);
Animated.spring(
this.state.lineFillAnimation,
{
toValue: 50, // 設(shè)置進(jìn)度值,范圍:0~100
friction: 5, // 動畫摩擦力
tension: 35 // 動畫張力
}
).start();
}
render() {
return (
<View style={styles.container}>
<Svg height="16" width="225">
<G fill="none" stroke="#3d5875">
<Path strokeLinecap="round" strokeWidth="8" d="M5 8 l215 0" />
</G>
<G fill="none" stroke="#00e0ff">
<AnimatedPath strokeLinecap="round" strokeWidth="8" d={this.lineAnimation}/>
</G>
</Svg>
</View>
);
}
}

直線進(jìn)度條+動畫效果
圓形進(jìn)度條
this.dasharray = [Math.PI * 2 * 42];
<Svg
height="100"
width="100">
<Circle
cx="50"
cy="50"
r="42"
stroke="#3d5875"
strokeWidth="8"
fill="transparent"
/>
<Circle
cx="50"
cy="50"
r="42"
origin="50,50"
rotate="-90"
stroke="#00e0ff"
strokeWidth="8"
strokeLinecap="round"
fill="transparent"
strokeDasharray={this.dasharray} strokeDashoffset={50}
/>
</Svg>
參數(shù) | 解釋 |
---|---|
<Svg height="100" width="100" | 整個圓形畫布的長矩乐、寬為100x100 |
<Circle cx="50" cy="50" strokeWidth="8" r="42" stroke="#3d5875" fill="transparent" /> |
畫底色圓形 圓形的中心點(diǎn)是point(50,50) 線條寬是8 半徑是42 = (100 - 8 * 2) / 2 線條顏色是#3d5875 圓形的填充色是透明 |
rotate="-90" | 逆時針旋轉(zhuǎn)90度 |
strokeLinecap="round" | 線條的結(jié)點(diǎn)是圓形的 |
strokeDasharray | 固定的計(jì)算形式:圓周長 = [Math.PI * 2 * 半徑] |
strokeDashoffset={50} | 非前景色的周長度龄句,就是圖中黑色的弧形的長度(范圍:0~圓周長) |
圓形進(jìn)度條
圓形進(jìn)度條 + 動畫
let AnimatedCircle = Animated.createAnimatedComponent(Circle)
export default class AwesomeProject extends Component {
constructor(props)
{
super(props);
this.state = {
circleFillAnimation: new Animated.Value(0)
};
this.dasharray = [Math.PI * 2 * 42];
// 這里是動畫的映射關(guān)系
this.circleAnimation = this.state.circleFillAnimation.interpolate({
inputRange: [
0,
100,
],
outputRange: [
this.dasharray[0],
0
]
});
}
componentDidMount()
{
this.startAnimation();
}
startAnimation()
{
this.state.circleFillAnimation.setValue(0);
Animated.spring(
this.state.circleFillAnimation,
{
toValue: 80, // 設(shè)置進(jìn)度值,范圍:0~100
friction: 5, // 動畫摩擦力
tension: 35 // 動畫張力
}
).start();
}
render() {
return (
<View style={styles.container}>
<Svg
height="100"
width="100">
<Circle
cx="50"
cy="50"
r="42"
stroke="#3d5875"
strokeWidth="8"
fill="transparent"
/>
<AnimatedCircle
cx="50"
cy="50"
r="42"
origin="50,50"
rotate="-90"
stroke="#00e0ff"
strokeWidth="8"
strokeLinecap="round"
fill="transparent"
strokeDasharray={this.dasharray} strokeDashoffset={this.circleAnimation}
/>
</Svg>
</View>
);
}
}

圓形進(jìn)度條+動畫
項(xiàng)目代碼地址
參考資料
svg教程
svg元素
react-native-svg
react-art
SVG Circle Progress
Radial Progress Meters (CSS/SVG)