react native實現自定義的圓形進度條動畫,主要需要用到animated和react native svg這個外掛程式。先看看最終實現的效果:
大致思路如下:
1. 使用svg建立畫布,指定畫布的寬高;
2. 建立外層倒計時circle,這裡需要使用兩個完全重合的circle疊起來實現,這兩個circle都只保留邊框,其中乙個circle顯示為進度條背景色(上圖中的灰色),另乙個circle顯示為進度條的前景色(上圖的綠色)。而且由於svg採用的是渲染疊加圖層的方式,所以下層的圖形會疊在上層圖形之上。因此作為背景的circle需要放置在上方。
const outercirclecommonconfig = $` // 繪製圓邊點劃線的圖案正規化,說白了就是定義虛線的渲染形式,circumference是整個圓的周長
};
上面**中使用標籤包裹兩個外層circle,主要是為了逆時針旋轉circle 90度。預設circle使用strokedashoffset繪製偏移量時的起點是時鐘的3點鐘位置,這樣通過逆時針旋轉90度,可以修改起點至12點鐘位置。繪製圓形進度條的核心屬性就是這個strokedashoffset,通過定時改變繪製偏移量從而產生進度條的效果。所以上面**中的circumferencewithprogress是乙個animated動畫值。
3. 新增動畫屬性
const = props;
const radian = progress.interpolate();
const circumferencewithprogress = animated.multiply(radius, radian);
const animatedcircleprogress = animated.createanimatedcomponent(circle);
為了讓父級元件能夠靈活的控制進度條,所以這裡將progress和durationtime(持續時間)定義在父級:
const durationtime = 5; // 持續時間(單位:s)
const [progress, setprogress] = usestate(new animated.value(0)); // 倒計時動畫進度
回到circleprogress元件中,這裡將progress動畫值使用interpolate做了一層動畫值的對映(插值),我們的進度一般都是[0, 1],而strokedashoffset偏移量應該是[0, 2 * math.pi] * radius(弧度 * 半徑)範圍內。最後為了保證外層circle的stroke能夠「動起來」,需要使用animated.createanimatedcomponent()方法建立乙個能執行動畫效果的circle元件animatedcircleprogress。修改後如下:
之後在父級元件中,呼叫如下方法,修改progress動畫值即可。
// 開始倒計時
const startcountdown = () => ).start(() => {});
};
如果我們想停止並重置進度條,可以呼叫如下方法:
const resetcountdown = () => ;
4. 新增內層circle,並顯示倒計時時間,還是在circleprogress元件中:
const [count, setcount] = usestate(durationtime);
useeffect(() => ) => );
return () =>
}, );
這裡使用progress.addlistener監聽動畫值progress的進度,並計算對應的倒計時的值。然後渲染在text文字中。
最後我們只需要在父級元件中修改常量durationtime的值就能改變總倒計時時間。非常的方便。
circleprogress元件完整**如下:src/components/circlprogress/index.js檔案
/**
* 圓形進度條
*/import react, from 'react';
import from 'react-native';
import svg, from 'react-native-svg';
import from '@utils';
const svgsize = 100; // 畫布的寬高
const halfofsvgsize = svgsize / 2;
const strokewidth = 2; // 圓形進度條寬度
const radius = (svgsize - strokewidth) / 2; // 外層倒計時進度半徑
const innerradius = radius - 6; // 內層半徑
const circumference = 2 * radius * math.pi; // 總周長
const circleprogress = (props) => = props;
const radian = progress.interpolate();
const circumferencewithprogress = animated.multiply(radius, radian);
const animatedcircleprogress = animated.createanimatedcomponent(circle);
const outercirclecommonconfig = $`
};const [count, setcount] = usestate(durationtime);
useeffect(() => ) => );
return () =>
}, )
return ();
};export default circleprogress;
Android ImageView實現圓形頭像
一 原理解析 先在canvas上面畫乙個圓形,參照圓形的起點座標 半徑,再畫乙個邊長為圓的直徑的bitmap 這個bitmap就是你想畫的圓形頭像 此時圓和bitmap重疊在一起,圓在下面,bitmap在上面,bitmap覆蓋著圓。這時,圓形和bitmap相交的部分正是圓大小的面積,如果能將bitm...
React Native 實現無限輪播
1 配置環境 2 環境配置出現錯誤,請看這一篇 4 需要將資源放到工程中。5 展示如下 檢視繪製完畢之後會呼叫此方法 componentdidmount 開啟定時器 starttimer else 更新狀態機 this.setstate 改變scrollview的偏移量 let offset tem...
iOS 圓形頭像如何實現
思路 view有乙個屬性layer,通過設定cornerradius來設定圓角的半徑,view是正方形的才能保證通過調整圓角半徑來形成圓形頭像 view layer setcornerradius cgrectgetheight view bounds 2 view.layer.maskstobou...