React Native 進(jìn)度條(react-native-svg)

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-svgreact-native中實(shí)現(xiàn)如下的效果:

進(jì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)度條+動畫效果

圓形進(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)度條+動畫
圓形進(jìn)度條+動畫

項(xiàng)目代碼地址

react-native-svg-example

參考資料

svg教程
svg元素
react-native-svg
react-art
SVG Circle Progress
Radial Progress Meters (CSS/SVG)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末散罕,一起剝皮案震驚了整個濱河市分歇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌欧漱,老刑警劉巖职抡,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異误甚,居然都是意外死亡缚甩,警方通過查閱死者的電腦和手機(jī)谱净,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來擅威,“玉大人壕探,你說我怎么就攤上這事〗即裕” “怎么了李请?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長厉熟。 經(jīng)常有香客問我导盅,道長,這世上最難降的妖魔是什么揍瑟? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任白翻,我火速辦了婚禮,結(jié)果婚禮上绢片,老公的妹妹穿的比我還像新娘滤馍。我一直安慰自己,他們只是感情好杉畜,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布纪蜒。 她就那樣靜靜地躺著,像睡著了一般此叠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上随珠,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天灭袁,我揣著相機(jī)與錄音,去河邊找鬼窗看。 笑死茸歧,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的显沈。 我是一名探鬼主播软瞎,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼拉讯!你這毒婦竟也來了涤浇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤魔慷,失蹤者是張志新(化名)和其女友劉穎只锭,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體院尔,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蜻展,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年喉誊,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纵顾。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡伍茄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出施逾,到底是詐尸還是另有隱情幻林,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布音念,位于F島的核電站沪饺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏闷愤。R本人自食惡果不足惜整葡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望讥脐。 院中可真熱鬧遭居,春花似錦、人聲如沸旬渠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽告丢。三九已至枪蘑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間岖免,已是汗流浹背岳颇。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留颅湘,地道東北人话侧。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像闯参,于是被迫代替她去往敵國和親瞻鹏。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容