@@ -42,118 +42,118 @@ const wedges = [
42
42
43
43
const SpinningWheel : React . FC < SpinningWheelProps > = ( { size = 500 , onDoneSpinning, onClick } ) => {
44
44
const canvasRef = useRef < HTMLCanvasElement > ( null ) ;
45
- let rotation = 0 ;
46
- let velocity = 0 ; // Spin velocity
47
- const maxVelocity = 0.025 ; // Maximum spin velocity
48
- const acceleration = 1.000 + ( Math . random ( ) * 0.001 ) ; // How fast the wheel ramps up
49
- const deceleration = 0.999 ; // How fast the wheel slows down
50
- let spinning = false ; // Whether the wheel is currently spinning
51
- let phase = 'stopped' ;
52
-
53
- // Draw the wheel
54
- const drawWheel = ( ctx : CanvasRenderingContext2D ) => {
55
- const numWedges = wedges . length ;
56
- const arcSize = ( 2 * Math . PI ) / numWedges ;
57
- const borderWidth = 5 ;
58
-
59
- wedges . forEach ( ( wedge , i ) => {
60
- const angle = i * arcSize ;
61
-
62
- // Draw wedge
63
- ctx . beginPath ( ) ;
64
- ctx . moveTo ( size / 2 , size / 2 ) ;
65
- ctx . arc ( size / 2 , size / 2 , size / 2 , angle , angle + arcSize , false ) ;
66
- ctx . fillStyle = wedge . color ;
67
- ctx . fill ( ) ;
68
45
69
- // Add border around each wedge
70
- ctx . lineWidth = 3 ; // Adjust the thickness of the wedge border
71
- ctx . strokeStyle = "black" ; // Set the border color for wedges
72
- ctx . stroke ( ) ; // Draw the border
73
-
74
- // Draw text
75
- ctx . save ( ) ;
76
- ctx . translate ( size / 2 , size / 2 ) ;
77
- ctx . rotate ( angle + arcSize / 2 ) ;
78
- ctx . textAlign = "center" ;
79
- ctx . fillStyle = "black" ; // Text color
80
- ctx . font = "16px Arial" ;
81
- ctx . fillText ( wedge . label , size / 2.5 , 10 ) ;
82
- ctx . restore ( ) ;
83
- } ) ;
84
-
85
- // Add a border around the wheel
86
- ctx . beginPath ( ) ;
87
- ctx . arc ( size / 2 , size / 2 , size / 2 , 0 , 2 * Math . PI , false ) ;
88
- ctx . lineWidth = borderWidth ; // Set the border thickness (adjust this as needed)
89
- ctx . strokeStyle = "black" ; // Set the border color
90
- ctx . stroke ( ) ; // Draw the border
91
-
92
- // Draw the middle circle
93
- const centerX = size / 2 ;
94
- const centerY = size / 2 ;
95
- const centerRadius = size / 4 ; // Adjust the size of the middle circle
96
-
97
- ctx . beginPath ( ) ;
98
- ctx . arc ( centerX , centerY , centerRadius , 0 , 2 * Math . PI , false ) ;
99
- ctx . fillStyle = "gray" ; // Color of the middle circle
100
- ctx . fill ( ) ;
101
- } ;
102
-
103
- // Animation frame to handle spinning
104
- const updateRotation = ( ) => {
105
- const canvas = canvasRef . current ;
106
- if ( canvas ) {
107
- const ctx = canvas . getContext ( "2d" ) ;
108
- if ( ctx ) {
109
- // Clear the canvas and re-draw the wheel
110
- ctx . clearRect ( 0 , 0 , size , size ) ;
46
+ useEffect ( ( ) => {
47
+ let rotation = 0 ;
48
+ let velocity = 0 ; // Spin velocity
49
+ const maxVelocity = 0.025 ; // Maximum spin velocity
50
+ const acceleration = 1.000 + ( Math . random ( ) * 0.001 ) ; // How fast the wheel ramps up
51
+ const deceleration = 0.999 ; // How fast the wheel slows down
52
+ let spinning = false ; // Whether the wheel is currently spinning
53
+ let phase = 'stopped' ;
54
+
55
+ // Draw the wheel
56
+ const drawWheel = ( ctx : CanvasRenderingContext2D ) => {
57
+ const numWedges = wedges . length ;
58
+ const arcSize = ( 2 * Math . PI ) / numWedges ;
59
+ const borderWidth = 5 ;
60
+
61
+ wedges . forEach ( ( wedge , i ) => {
62
+ const angle = i * arcSize ;
63
+
64
+ // Draw wedge
65
+ ctx . beginPath ( ) ;
66
+ ctx . moveTo ( size / 2 , size / 2 ) ;
67
+ ctx . arc ( size / 2 , size / 2 , size / 2 , angle , angle + arcSize , false ) ;
68
+ ctx . fillStyle = wedge . color ;
69
+ ctx . fill ( ) ;
70
+
71
+ // Add border around each wedge
72
+ ctx . lineWidth = 3 ; // Adjust the thickness of the wedge border
73
+ ctx . strokeStyle = "black" ; // Set the border color for wedges
74
+ ctx . stroke ( ) ; // Draw the border
75
+
76
+ // Draw text
111
77
ctx . save ( ) ;
112
78
ctx . translate ( size / 2 , size / 2 ) ;
113
- ctx . rotate ( rotation ) ; // Apply current rotation
114
- ctx . translate ( - size / 2 , - size / 2 ) ;
115
- drawWheel ( ctx ) ;
79
+ ctx . rotate ( angle + arcSize / 2 ) ;
80
+ ctx . textAlign = "center" ;
81
+ ctx . fillStyle = "black" ; // Text color
82
+ ctx . font = "16px Arial" ;
83
+ ctx . fillText ( wedge . label , size / 2.5 , 10 ) ;
116
84
ctx . restore ( ) ;
85
+ } ) ;
86
+
87
+ // Add a border around the wheel
88
+ ctx . beginPath ( ) ;
89
+ ctx . arc ( size / 2 , size / 2 , size / 2 , 0 , 2 * Math . PI , false ) ;
90
+ ctx . lineWidth = borderWidth ; // Set the border thickness (adjust this as needed)
91
+ ctx . strokeStyle = "black" ; // Set the border color
92
+ ctx . stroke ( ) ; // Draw the border
93
+
94
+ // Draw the middle circle
95
+ const centerX = size / 2 ;
96
+ const centerY = size / 2 ;
97
+ const centerRadius = size / 4 ; // Adjust the size of the middle circle
98
+
99
+ ctx . beginPath ( ) ;
100
+ ctx . arc ( centerX , centerY , centerRadius , 0 , 2 * Math . PI , false ) ;
101
+ ctx . fillStyle = "gray" ; // Color of the middle circle
102
+ ctx . fill ( ) ;
103
+ } ;
104
+
105
+ // Animation frame to handle spinning
106
+ const updateRotation = ( ) => {
107
+ const canvas = canvasRef . current ;
108
+ if ( canvas ) {
109
+ const ctx = canvas . getContext ( "2d" ) ;
110
+ if ( ctx ) {
111
+ // Clear the canvas and re-draw the wheel
112
+ ctx . clearRect ( 0 , 0 , size , size ) ;
113
+ ctx . save ( ) ;
114
+ ctx . translate ( size / 2 , size / 2 ) ;
115
+ ctx . rotate ( rotation ) ; // Apply current rotation
116
+ ctx . translate ( - size / 2 , - size / 2 ) ;
117
+ drawWheel ( ctx ) ;
118
+ ctx . restore ( ) ;
119
+ }
117
120
}
118
- }
119
121
120
- if ( phase === 'accelerating' ) {
121
- if ( velocity < maxVelocity ) {
122
- if ( velocity === 0 ) {
123
- velocity = velocity + 0.02 ;
122
+ if ( phase === 'accelerating' ) {
123
+ if ( velocity < maxVelocity ) {
124
+ if ( velocity === 0 ) {
125
+ velocity = velocity + 0.02 ;
126
+ }
127
+ velocity = velocity * acceleration ;
128
+ } else {
129
+ phase = 'decelerating' ;
124
130
}
125
- velocity = velocity * acceleration ;
126
- } else {
127
- phase = 'decelerating' ;
128
131
}
129
- }
130
-
131
- if ( phase === 'decelerating' ) {
132
- if ( velocity > 0.02 ) {
133
- velocity = velocity * deceleration ;
134
- } else if ( velocity > 0.001 ) {
135
- const fastDeceleration = 3 ;
136
- velocity = velocity * ( 1 - ( ( 1 - deceleration ) * fastDeceleration ) ) ;
137
- } else {
138
- phase = 'stopped' ;
139
- spinning = false ;
140
- velocity = 0 ;
141
- setTimeout ( ( ) => onDoneSpinning ( ) , 2000 ) ;
132
+
133
+ if ( phase === 'decelerating' ) {
134
+ if ( velocity > 0.02 ) {
135
+ velocity = velocity * deceleration ;
136
+ } else if ( velocity > 0.001 ) {
137
+ const fastDeceleration = 3 ;
138
+ velocity = velocity * ( 1 - ( ( 1 - deceleration ) * fastDeceleration ) ) ;
139
+ } else {
140
+ phase = 'stopped' ;
141
+ spinning = false ;
142
+ velocity = 0 ;
143
+ setTimeout ( ( ) => onDoneSpinning ( ) , 2000 ) ;
144
+ }
142
145
}
143
- }
144
146
145
- if ( spinning ) {
146
- rotation = rotation + ( velocity ) ;
147
- requestAnimationFrame ( updateRotation ) ; // Continue the animation loop
148
- }
149
- } ;
147
+ if ( spinning ) {
148
+ rotation = rotation + ( velocity ) ;
149
+ requestAnimationFrame ( updateRotation ) ; // Continue the animation loop
150
+ }
151
+ } ;
150
152
151
- useEffect ( ( ) => {
152
153
spinning = true ;
153
154
phase = 'accelerating' ;
154
155
updateRotation ( ) ;
155
- } , [ ] ) ;
156
-
156
+ } , [ onDoneSpinning , size ] ) ;
157
157
158
158
return (
159
159
< div className = "text-white" onClick = { onClick } >
0 commit comments