使用React Native製做圓形加載條

圖片描述

先放運行截圖說明作什麼吧,css

vued467c4a48f880b36ace99599d3f2d776f.png

react-native-percentage-circle 項目地址html

最近需求須要一個顯示百分比的加載條。然而去搜索了好久,沒能發現比較滿意的組件,只好本身解決了。固然對於大多數前端而言,這個並非特別難的,可能思路衆多,然而面對React Native彷佛就有點相形見絀了。解決這樣的問題,咱們仍是得迴歸前端自己,看看有什麼能夠嫁接的方案沒。前端

前端常規制做進度條方法

前端實現相對容易點,咱們能夠用canvas去繪製圓,也能夠用SVG去繪製.vue

使用SVG

<svg style="width:2.8rem" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 130 130" overflow="visible" enable-background="new 0 0 130 130" id="progress">
    <circle fill="none" stroke="#ccc" stroke-width="4" stroke-miterlimit="10" cx="64.8" cy="64.8" r="59.8"></circle>
    <circle class="styled" fill="none" stroke="#2ecc71" stroke-width="4" stroke-miterlimit="10" cx="64.8" cy="64.8" r="59.8" style="stroke-dashoffset: -93.9336; stroke-dasharray: 375.734;"></circle>
 
 </svg>

SVG主要是用Circle進行繪製,關於Circle使用能夠看 這裏 。咱們先繪製第一個圓,用於底色。接下來咱們只須要在上面繪製一個帶有色彩的圓(切記不要填充顏色fill="none")。這個時候咱們須要瞭解兩個關鍵的屬性;react

stroke-dasharray: 用於控制路徑繪製中虛線和間距的。例子中的即圓的周長。css3

stroke-dashoffset: 用於指定距離虛線繪製的起點git

若是咱們知道了這個的話,咱們只須要計算出圓的周長github

var CircleLength = R * 2 * Math.PI;

var PercentOffset = - CircleLength * yourPercent;

而後將這個第二個Circle屬性賦予到style中:npm

style="stroke-dashoffset: -93.9336; stroke-dasharray: 375.734;"

SVG相對來講還算是比較易用的解決方案, Demo;canvas

使用 CSS漸變

還有一個更加直接的方法,就是利用 CSS3 中的linear-gradient

效果如圖:

vued0540dac2f68979c1a631a5a8e8d1e7de.png

咱們只須要指定line-grdient中經過旋轉的角度而後設置好間隔的漸變百分比就行啦。

background-image:linear-gradient(90deg, transparent 50%, #16a085 50%),     linear-gradient(90deg, #eee 50%, transparent 50%);

下圖爲隱藏掉遮擋的小圓的樣子。
vued224f221ee72e1b143419483d5dbd47ea.png

代碼以下:

.circle1{
  position:relative;
  width:110px;
  height:110px;
  border-radius:100%;
  background-color: #eee;
  background-image:linear-gradient(90deg, transparent 50%, #16a085 50%),     linear-gradient(90deg, #eee 50%, transparent 50%);
 }
.circle2{
  position:relative;
  top:5px;
  left:5px;
  width:100px;
  height:100px;
  border-radius:100%;
  background-color: #fff;
}
<div class="circle1">
    <div class="circle2"></div>
</div>

DEMO

使用CSS Transform

若是要用Transform 的話,這個腦洞就比較大了,解決的方案也有不少,今天本身分享一個相對不燒腦的解決方案:

圖片描述

圖3-1

vueda8bd72e3f10eb74cfde516ac3cce26f0.png
圖3-2

如圖 咱們須要創建一個外部的圓,也就是用於繪製灰色的底色,而後再用一個區域進行層級遮擋(也能夠本身用border來模擬啦)。記住屬性必定要有overflow:hidden.

接下來咱們須要添加左右兩個分區,用於放置進行彩條繪製的容器。如圖3-1咱們設置左分區一個,裏面是一個左半圓,而這個半圓距離容器距離是100%,默認是不可見的。而後它須要圍繞圓心旋轉,比較巧妙的是,它須要旋轉過180度後,纔會回到它的父容器可見區域。如圖3-2同理咱們能夠設置右半區,而後將半圓放在-100%的距離,即右半圓默認也不可見的。當它開始旋轉的時候即以下圖紅色區域就是咱們的角度:
vued702057d32db43d43e19852eb09441d57.png

注意因爲是兩個圓進行配合,所以角度過180度,時候,左半圓則開始旋轉,而右半圓則保持180度便可。

.left-wrap{
    overflow: hidden;
    position: absolute;
    left:0;
    top:0;
    width: 50%;
    height:100%;
    
}
.left-wrap .loader{
    position: absolute;
    left:100%;
    top:0;
    width:100%;
    height:100%;
    border-radius: 1000px;
    background-color: #333; 
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    transform-origin:0 50% 0;
}
// 省略一些右半區代碼

.right-wrap{
    ....
    left:50%;
}
.right-wrap .loader{ 
    ...
    left:-100%;
    border-bottom-right-radius: 0;
    border-top-right-radius: 0;    
    transform-origin:100% 50% 0;    
}

DEMO

這些就是前端的一些解決方法固然你也能夠選擇開源的框架,好比:

如何使用React Native寫這樣的進度條呢?

前面的前端思路本身卻是有了,因而以爲很easy嘛,不過在開始寫的時候發現 尷尬了。 SVG成本比較大,你須要安裝依賴react-native-art-svg。用漸變的話,固然也比較麻煩,也需呀安裝依賴,本身心裏以爲:畫一個圓至於麼!!!

因而乎開始本身造輪子了,採用了第三種方案,就用view + transform進行組件封裝。纔開始還挺順的,不過看官方文檔,發現沒有對 transform origin支持。雖然支持了rotate ,scale,translate,可是發現這個缺陷,無疑陷入一絲困境。隨後發現有人早已提了本身的pr給官方,但願獲得支持。相似於 transformOrgin:{x:100}這樣子。 固然目前最新版依舊沒有歸入到計劃中。不過官方支持了transformMatrix , 這個雖好,但是樓主數學倒是渣,能不能有一個讓學渣快速理解的方案。

The transform-origin property lets you modify the origin for transformations of an element. For example, the transform-origin of the rotate() function is the centre of rotation. (This property is applied by first translating the element by the negated value of the property, then applying the element's transform, then translating by the property value.)

大體意思就是這個屬性在進行選擇時指定origin的時候,會先將元素平移過去,而後再移回來。因此咱們能夠在旋轉時這樣指定:

<View style={[styles.leftWrap,{
  // ....
  <View style={[styles.loader,{
     ...  radius: 半徑
     transform:[{translateX:-this.props.radius/2},{rotate:this.state.leftTransformerDegree},{translateX:this.props.radius/2}],  
     }]}></View>
 </View>

這樣本身就能夠解決transform origin的問題了。這樣寫進度就很是easy 啦。本身簡單封裝了這個組件 react-native-percentage-circle

簡單開始:

npm i react-native-percentage-circle --save
import PercentageCircle from 'react-native-percentage-circle';

//...

redner() {
  <View>
    <PercentageCircle radius={35} percent={50} color={"#3498db"}></PercentageCircle>  
  </View>
}

選項說明

Props Type Example Description
color string '#000' 進度條顏色
percent Number 30 百分之多少
radius Number 20 圓的半徑

固然目前的參數本身想到的就這些,固然你們能夠本身寫,也能夠提PR ,將它擴展。

文章同步博客 : http://www.jackpu.com/shi-yon...

參考

相關文章
相關標籤/搜索