@@ -2,12 +2,22 @@ import { useEffect, useMemo, useRef, useState } from 'react';
22import  {  Driver  }  from  '@irdashies/types' ; 
33import  tracks  from  './tracks/tracks.json' ; 
44import  {  getColor ,  getTailwindStyle  }  from  '@irdashies/utils/colors' ; 
5- import  {  shouldShowTrack  }  from  './tracks/broken-tracks ' ; 
5+ import  {  shouldShowTrack  }  from  './tracks/brokenTracks ' ; 
66import  {  TrackDebug  }  from  './TrackDebug' ; 
7+ import  {  useStartFinishLine  }  from  './hooks/useStartFinishLine' ; 
8+ import  { 
9+   setupCanvasContext , 
10+   drawTrack , 
11+   drawStartFinishLine , 
12+   drawTurnNames , 
13+   drawDrivers , 
14+ }  from  './trackDrawingUtils' ; 
715
816export  interface  TrackProps  { 
917  trackId : number ; 
1018  drivers : TrackDriver [ ] ; 
19+   enableTurnNames ?: boolean ; 
20+   debug ?: boolean ; 
1121} 
1222
1323export  interface  TrackDriver  { 
@@ -36,13 +46,15 @@ export interface TrackDrawing {
3646  } [ ] ; 
3747} 
3848
39- // currently its a bit messy with the turns, so we disable them for now 
40- const  ENABLE_TURNS  =  true ; 
41- 
4249const  TRACK_DRAWING_WIDTH  =  1920 ; 
4350const  TRACK_DRAWING_HEIGHT  =  1080 ; 
4451
45- export  const  TrackCanvas  =  ( {  trackId,  drivers } : TrackProps )  =>  { 
52+ export  const  TrackCanvas  =  ( { 
53+   trackId, 
54+   drivers, 
55+   enableTurnNames, 
56+   debug, 
57+ } : TrackProps )  =>  { 
4658  const  canvasRef  =  useRef < HTMLCanvasElement > ( null ) ; 
4759  const  [ canvasSize ,  setCanvasSize ]  =  useState ( {  width : 0 ,  height : 0  } ) ; 
4860
@@ -81,6 +93,12 @@ export const TrackCanvas = ({ trackId, drivers }: TrackProps) => {
8193    return  colors ; 
8294  } ,  [ drivers ] ) ; 
8395
96+   // Get start/finish line calculations 
97+   const  startFinishLine  =  useStartFinishLine ( { 
98+     startFinishPoint : trackDrawing ?. startFinish ?. point , 
99+     trackPathPoints : trackDrawing ?. active ?. trackPathPoints , 
100+   } ) ; 
101+ 
84102  // Position calculation based on the percentage of the track completed 
85103  const  calculatePositions  =  useMemo ( ( )  =>  { 
86104    if  ( 
@@ -198,73 +216,38 @@ export const TrackCanvas = ({ trackId, drivers }: TrackProps) => {
198216    const  offsetX  =  ( rect . width  -  TRACK_DRAWING_WIDTH  *  scale )  /  2 ; 
199217    const  offsetY  =  ( rect . height  -  TRACK_DRAWING_HEIGHT  *  scale )  /  2 ; 
200218
201-     // Save context state 
202-     ctx . save ( ) ; 
203- 
204-     // Apply scaling and centering 
205-     ctx . translate ( offsetX ,  offsetY ) ; 
206-     ctx . scale ( scale ,  scale ) ; 
207- 
208-     // Shadow 
209-     ctx . shadowColor  =  'black' ; 
210-     ctx . shadowBlur  =  2 ; 
211-     ctx . shadowOffsetX  =  1 ; 
212-     ctx . shadowOffsetY  =  1 ; 
219+     // Setup canvas context with scaling and shadow 
220+     setupCanvasContext ( ctx ,  scale ,  offsetX ,  offsetY ) ; 
213221
214-     // Draw track 
215-     if  ( path2DObjects . inside )  { 
216-       ctx . strokeStyle  =  'white' ; 
217-       ctx . lineWidth  =  20 ; 
218-       ctx . stroke ( path2DObjects . inside ) ; 
219-     } 
220- 
221-     // Draw start/finish line 
222-     if  ( path2DObjects . startFinish )  { 
223-       ctx . lineWidth  =  10 ; 
224-       ctx . strokeStyle  =  getColor ( 'red' ) ; 
225-       ctx . stroke ( path2DObjects . startFinish ) ; 
226-     } 
227- 
228-     // Draw turn numbers 
229-     if  ( ENABLE_TURNS )  { 
230-       trackDrawing . turns ?. forEach ( ( turn )  =>  { 
231-         if  ( ! turn . content  ||  ! turn . x  ||  ! turn . y )  return ; 
232-         ctx . textAlign  =  'center' ; 
233-         ctx . textBaseline  =  'middle' ; 
234-         ctx . fillStyle  =  'white' ; 
235-         ctx . font  =  '2rem sans-serif' ; 
236-         ctx . fillText ( turn . content ,  turn . x ,  turn . y ) ; 
237-       } ) ; 
238-     } 
239- 
240-     // Draw drivers 
241-     Object . values ( calculatePositions ) 
242-       . sort ( ( a ,  b )  =>  Number ( a . isPlayer )  -  Number ( b . isPlayer ) )  // draws player last to be on top 
243-       . forEach ( ( {  driver,  position } )  =>  { 
244-         const  color  =  driverColors [ driver . CarIdx ] ; 
245-         if  ( ! color )  return ; 
246- 
247-         ctx . fillStyle  =  color . fill ; 
248-         ctx . beginPath ( ) ; 
249-         ctx . arc ( position . x ,  position . y ,  40 ,  0 ,  2  *  Math . PI ) ; 
250-         ctx . fill ( ) ; 
251-         ctx . textAlign  =  'center' ; 
252-         ctx . textBaseline  =  'middle' ; 
253-         ctx . fillStyle  =  color . text ; 
254-         ctx . font  =  '2rem sans-serif' ; 
255-         ctx . fillText ( driver . CarNumber ,  position . x ,  position . y ) ; 
256-       } ) ; 
222+     // Draw all elements 
223+     drawTrack ( ctx ,  path2DObjects ) ; 
224+     drawStartFinishLine ( ctx ,  startFinishLine ) ; 
225+     drawTurnNames ( ctx ,  trackDrawing . turns ,  enableTurnNames ) ; 
226+     drawDrivers ( ctx ,  calculatePositions ,  driverColors ) ; 
257227
258228    // Restore context state 
259229    ctx . restore ( ) ; 
260-   } ,  [ calculatePositions ,  path2DObjects ,  trackDrawing ?. turns ,  driverColors ,  canvasSize ] ) ; 
230+   } ,  [ 
231+     calculatePositions , 
232+     path2DObjects , 
233+     trackDrawing ?. turns , 
234+     driverColors , 
235+     canvasSize , 
236+     enableTurnNames , 
237+     trackDrawing ?. startFinish ?. point , 
238+     trackDrawing ?. active ?. trackPathPoints , 
239+     startFinishLine , 
240+   ] ) ; 
261241
262242  // Development/Storybook mode - show debug info and canvas 
263-   if  ( import . meta . env ?. DEV   ||   import . meta . env ?. MODE   ===   'storybook' )  { 
243+   if  ( debug )  { 
264244    return  ( 
265245      < div  className = "overflow-hidden w-full h-full" > 
266246        < TrackDebug  trackId = { trackId }  trackDrawing = { trackDrawing }  /> 
267-         < canvas  className = "will-change-transform w-full h-full"  ref = { canvasRef } > </ canvas > 
247+         < canvas 
248+           className = "will-change-transform w-full h-full" 
249+           ref = { canvasRef } 
250+         > </ canvas > 
268251      </ div > 
269252    ) ; 
270253  } 
@@ -274,7 +257,10 @@ export const TrackCanvas = ({ trackId, drivers }: TrackProps) => {
274257
275258  return  ( 
276259    < div  className = "overflow-hidden w-full h-full" > 
277-       < canvas  className = "will-change-transform w-full h-full"  ref = { canvasRef } > </ canvas > 
260+       < canvas 
261+         className = "will-change-transform w-full h-full" 
262+         ref = { canvasRef } 
263+       > </ canvas > 
278264    </ div > 
279265  ) ; 
280266} ; 
0 commit comments