1- import React , { useState , useEffect , cloneElement } from ' react' ;
2- import { View , Text , TouchableOpacity , StyleSheet } from ' react-native' ;
3- import { LinearGradient } from ' expo-linear-gradient' ;
4- import { FontAwesome } from ' @expo/vector-icons' ; // Use FontAwesome icons
1+ import React , { useState , useEffect , useRef } from " react" ;
2+ import { View , Text , TouchableOpacity , StyleSheet } from " react-native" ;
3+ import { LinearGradient } from " expo-linear-gradient" ;
4+ import { FontAwesome } from " @expo/vector-icons" ;
55
66const Stopwatch = ( ) => {
77 const [ time , setTime ] = useState ( 0 ) ;
88 const [ isRunning , setIsRunning ] = useState ( false ) ;
9+ const startTimeRef = useRef ( null ) ;
910
1011 useEffect ( ( ) => {
1112 let interval ;
12- if ( isRunning ) {
13+ if ( isRunning ) {
14+ startTimeRef . current = Date . now ( ) - time ;
1315 interval = setInterval ( ( ) => {
14- setTime ( ( prevTime ) => prevTime + 10 ) ; // Increment by 10ms
15- } , 10 ) ; // Update every 10ms
16- } else {
16+ const now = Date . now ( ) ;
17+ setTime ( now - startTimeRef . current ) ;
18+ } , 10 ) ;
19+ } else if ( interval ) {
1720 clearInterval ( interval ) ;
1821 }
1922 return ( ) => clearInterval ( interval ) ;
20- } , [ isRunning ] ) ;
23+ } , [ isRunning ] ) ;
2124
2225 const resetTimer = ( ) => {
2326 setIsRunning ( false ) ;
@@ -26,89 +29,109 @@ const Stopwatch = () => {
2629
2730 return (
2831 < View style = { styles . container } >
29- < LinearGradient
30- colors = { [ 'rgba(245, 245, 245, 1)' , 'rgba(204, 204, 204, 1)' ] }
31- style = { styles . gradient }
32- >
33- < View style = { styles . circle } >
34- < Text style = { styles . timer } > { formatTime ( time ) } </ Text >
35- </ View >
36- </ LinearGradient >
37- < View style = { styles . buttons } >
38- < TouchableOpacity
39- style = { [ styles . button , isRunning ? styles . stopButton : styles . startButton ] }
40- onPress = { ( ) => setIsRunning ( ! isRunning ) }
32+ < LinearGradient
33+ colors = { [ 'rgba(245,245,245,1)' , 'rgba(204,204,204,1' ] }
34+ style = { styles . gradient }
4135 >
42- < FontAwesome
43- name = { isRunning ? 'pause' : 'play' }
44- size = { 20 }
45- color = "white"
46- />
47- </ TouchableOpacity >
48- < TouchableOpacity style = { styles . button } onPress = { resetTimer } >
49- < FontAwesome name = "refresh" size = { 20 } color = "white"
50- />
51- </ TouchableOpacity >
52- </ View >
36+ < View style = { styles . circle } >
37+ < Text style = { styles . timer } > { formatTime ( time ) } </ Text >
38+ </ View >
39+ </ LinearGradient >
40+ < View style = { styles . buttons } >
41+ < TouchableOpacity
42+ style = { [ styles . button , isRunning ? styles . stopButton : styles . startButton ] }
43+ onPress = { ( ) => setIsRunning ( ! isRunning ) }
44+ >
45+ < FontAwesome
46+ name = { isRunning ? "pause" : "play" }
47+ size = { 25 }
48+ color = "white"
49+ />
50+ </ TouchableOpacity >
51+ < TouchableOpacity style = { [ styles . button , styles . refreshButton ] } onPress = { resetTimer } >
52+ < FontAwesome name = "refresh" size = { 25 } color = "white" />
53+ </ TouchableOpacity >
54+ </ View >
5355 </ View >
5456 ) ;
57+
5558} ;
5659
5760const formatTime = ( milliseconds ) => {
5861 const mins = Math . floor ( milliseconds / 60000 ) ;
5962 const secs = Math . floor ( ( milliseconds % 60000 ) / 1000 ) ;
60- const ms = Math . floor ( ( milliseconds % 1000 ) / 10 ) ;
61- return `${ String ( mins ) . padStart ( 2 , '0' ) } :${ String ( secs ) . padStart ( 2 , '0' ) } .${ String ( ms ) . padStart ( 2 , '0' ) } ` ;
63+ const ms = Math . floor ( ( milliseconds % 1000 ) / 10 ) ;
64+ return `${ String ( mins ) . padStart ( 2 , '0' ) } :${ String ( secs ) . padStart ( 2 , '0' ) } .${ String ( ms ) . padStart ( 2 , '0' ) } ` ;
6265} ;
6366
67+ export default Stopwatch ;
68+
69+
6470const styles = StyleSheet . create ( {
6571 container : {
66- flex : 1 ,
67- justifyContent : ' center' ,
68- alignItems : ' center' ,
69- backgroundColor : ' rgb(241 241 241)' ,
72+ flex :1 ,
73+ justifyContent :" center" ,
74+ alignItems : " center" ,
75+ backgroundColor : " rgb(241, 241, 241)"
7076 } ,
7177 gradient : {
72- justifyContent : ' center' ,
73- alignItems : ' center' ,
78+ justifyContent : " center" ,
79+ alignItems : " center" ,
7480 width : 250 ,
7581 height : 250 ,
76- borderRadius : "50%" ,
82+ borderRadius : 125 ,
7783 marginBottom : 40 ,
78- borderWidth : 10 , // Border thickness
79- borderColor : ' lightgray' , // Border color
84+ borderWidth :10 ,
85+ borderColor : " lightgray"
8086 } ,
8187 circle : {
82- width : 250 , // Circle width
83- height : 250 , // Circle height
84- borderRadius : "50%" ,
85- justifyContent : ' center' ,
86- alignItems : ' center' ,
88+ width :250 ,
89+ height :250 ,
90+ borderRadius : 125 ,
91+ justifyContent : " center" ,
92+ alignItems : " center"
8793 } ,
8894 timer : {
89- fontSize : 36 ,
90- fontWeight : 'bold' ,
91- } ,
92- buttons : {
93- flexDirection : 'row' ,
95+ fontSize :36 ,
96+ fontWeight :"bold"
9497 } ,
9598 button : {
96- padding : 15 ,
97- margin : 10 ,
98- width :55 ,
99- height :55 ,
100- borderRadius : "50%" ,
101- backgroundColor : 'rgb(103 209 96)' ,
102- justifyContent :"center" ,
103- alignItems :"center"
99+ padding :15 ,
100+ margin :10 ,
101+ width :70 ,
102+ height :70 ,
103+ borderRadius :35 ,
104+ justifyContent : "center" ,
105+ alignItems : "center"
106+ } ,
107+ buttons : {
108+ flexDirection : "row"
104109 } ,
105110 startButton : {
106- backgroundColor : 'deepskyblue' ,
111+ backgroundColor : "#E91E62"
107112 } ,
108113 stopButton : {
109- backgroundColor : 'rgb(225 0 0)' ,
114+ backgroundColor : "#001F3F"
115+ } ,
116+ refreshButton : {
117+ backgroundColor : "green"
110118 } ,
111-
112119} ) ;
113120
114- export default Stopwatch ;
121+
122+
123+
124+
125+
126+
127+
128+
129+
130+
131+
132+
133+
134+
135+
136+
137+
0 commit comments