-
Notifications
You must be signed in to change notification settings - Fork 0
/
App.js
104 lines (95 loc) · 2.5 KB
/
App.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import React, {useState} from 'react';
import {View, Text, StyleSheet, Animated} from 'react-native';
import Svg, {Circle, G} from 'react-native-svg';
import {useRef} from 'react';
import {useEffect} from 'react';
export default () => {
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Timer
time={20}
radius={100}
strokeWidth={20}
color={'black'}
delay={0}
/>
<Timer time={60} radius={50} strokeWidth={5} color={'green'} delay={0} />
<Timer
time={30}
radius={150}
strokeWidth={15}
color={'purple'}
delay={1000}
/>
</View>
);
};
const AnimatedCircle = new Animated.createAnimatedComponent(Circle);
const Timer = ({
time = 60,
radius = 50,
strokeWidth = 10,
color = 'cyan',
delay = 0,
}) => {
const animatedValue = useRef(new Animated.Value(time)).current;
const halfCircle = radius + strokeWidth;
const strokeDasharray = 2 * Math.PI * radius;
const [strokeDashoffset, setStrokeDashoffset] = useState(0);
const [timer, setTimer] = useState(time);
const Animate = () => {
Animated.timing(animatedValue, {
delay,
toValue: 0,
duration: time * 1000,
useNativeDriver: true,
}).start();
};
useEffect(() => {
Animate();
animatedValue.addListener(value => {
Promise.all([
setStrokeDashoffset(
strokeDasharray - strokeDasharray * (value.value / time),
),
setTimer(value.value),
]);
});
}, []);
return (
<View>
<Svg
width={radius * 2}
height={radius * 2}
viewBox={`0 0 ${halfCircle * 2} ${halfCircle * 2}`}>
<G rotation={'-90'} origin={`${halfCircle}, ${halfCircle}`}>
<Circle
r={radius}
cx={'50%'}
cy={'50%'}
stroke={color}
strokeWidth={strokeWidth}
strokeOpacity={0.2}
/>
<AnimatedCircle
r={radius}
cx={'50%'}
cy={'50%'}
stroke={color}
strokeWidth={strokeWidth}
strokeDasharray={strokeDasharray}
strokeDashoffset={strokeDashoffset}
strokeLinecap={'round'}
/>
</G>
</Svg>
<View
style={[
StyleSheet.absoluteFillObject,
{justifyContent: 'center', alignItems: 'center'},
]}>
<Text style={[{fontSize: radius * 0.5}]}>{timer.toFixed(0)}</Text>
</View>
</View>
);
};