@@ -459,84 +459,94 @@ <h1>Wall Ball Rep Tracker (Chrome)</h1>
459459 }
460460
461461 async function detect ( ) {
462- let poses = [ ] ;
463- try {
464- // Get video frame data
465- ctx . clearRect ( 0 , 0 , canvas . width , canvas . height ) ;
466- ctx . drawImage ( video , 0 , 0 , canvas . width , canvas . height ) ;
467-
468- // Get image data to analyze pixels
469- const imageData = ctx . getImageData ( 0 , 0 , canvas . width , canvas . height ) ;
470- const data = imageData . data ;
462+ try {
463+ // Get video frame data
464+ ctx . clearRect ( 0 , 0 , canvas . width , canvas . height ) ;
465+ ctx . drawImage ( video , 0 , 0 , canvas . width , canvas . height ) ;
466+
467+ // Get image data to analyze pixels
468+ const imageData = ctx . getImageData ( 0 , 0 , canvas . width , canvas . height ) ;
469+ const data = imageData . data ;
470+
471+ // Track stick
472+ let stickX = 0 ;
473+ let stickY = 0 ;
474+ let matchingPixels = 0 ;
475+
476+ // Get selected color
477+ const selectedColor = document . getElementById ( 'stick-color' ) . value ;
478+
479+ // Scan for matching colored pixels
480+ for ( let i = 0 ; i < data . length ; i += 4 ) {
481+ const r = data [ i ] ;
482+ const g = data [ i + 1 ] ;
483+ const b = data [ i + 2 ] ;
471484
472- // Track black stick
473- let stickX = 0 ;
474- let stickY = 0 ;
475- let blackPixels = 0 ;
485+ let isMatch = false ;
486+ if ( selectedColor === 'black' ) {
487+ // Check for black pixels (RGB values close to 0)
488+ isMatch = r < 50 && g < 50 && b < 50 ;
489+ } else if ( selectedColor === 'white' ) {
490+ // Check for white pixels (RGB values close to 255)
491+ isMatch = r > 200 && g > 200 && b > 200 ;
492+ }
476493
477- // Scan for black pixels (RGB values close to 0)
478- for ( let i = 0 ; i < data . length ; i += 4 ) {
479- const r = data [ i ] ;
480- const g = data [ i + 1 ] ;
481- const b = data [ i + 2 ] ;
494+ if ( isMatch ) {
495+ const pixelIndex = i / 4 ;
496+ const x = pixelIndex % canvas . width ;
497+ const y = Math . floor ( pixelIndex / canvas . width ) ;
482498
483- // Check if pixel is black (allowing some tolerance)
484- if ( r < 50 && g < 50 && b < 50 ) {
485- const pixelIndex = i / 4 ;
486- const x = pixelIndex % canvas . width ;
487- const y = Math . floor ( pixelIndex / canvas . width ) ;
488-
489- // Accumulate position for averaging
490- stickX += x ;
491- stickY += y ;
492- blackPixels ++ ;
493- }
499+ // Accumulate position for averaging
500+ stickX += x ;
501+ stickY += y ;
502+ matchingPixels ++ ;
494503 }
504+ }
505+
506+ // If we found enough matching pixels, calculate stick position
507+ if ( matchingPixels > 100 ) {
508+ stickX = Math . round ( stickX / matchingPixels ) ;
509+ stickY = Math . round ( stickY / matchingPixels ) ;
495510
496- // If we found enough black pixels, calculate stick position
497- if ( blackPixels > 100 ) {
498- stickX = Math . round ( stickX / blackPixels ) ;
499- stickY = Math . round ( stickY / blackPixels ) ;
500-
501- // Draw stick tracking point
502- ctx . fillStyle = '#00FF00' ;
503- ctx . beginPath ( ) ;
504- ctx . arc ( stickX , stickY , 8 , 0 , 2 * Math . PI ) ;
505- ctx . fill ( ) ;
506-
507- // Show stick coordinates
508- ctx . fillStyle = 'white' ;
509- ctx . font = '16px Arial' ;
510- ctx . fillText ( `Stick: (${ stickX } , ${ stickY } )` , 10 , 20 ) ;
511-
512- // Track rep based on stick movement
513- const currentTime = Date . now ( ) ;
514- const timeSinceLastRep = currentTime - lastRepTime ;
515-
516- // Ready position: Stick must be high
517- if ( stickY < canvas . height / 3 ) {
518- stickStage = 'ready' ;
519- }
520-
521- // Follow through: Stick must move down with minimum time between reps
522- if ( stickY > canvas . height * 2 / 3 &&
523- stickStage === 'ready' &&
524- timeSinceLastRep > REP_COOLDOWN ) {
525- reps ++ ;
526- stickStage = 'down' ;
527- lastRepTime = currentTime ;
528- document . getElementById ( 'reps' ) . textContent = `Reps: ${ reps } ` ;
529- }
530-
531- // Show current stage
532- ctx . fillText ( `Stage: ${ stickStage || 'none' } ` , 10 , 40 ) ;
511+ // Draw stick tracking point
512+ ctx . fillStyle = '#00FF00' ;
513+ ctx . beginPath ( ) ;
514+ ctx . arc ( stickX , stickY , 8 , 0 , 2 * Math . PI ) ;
515+ ctx . fill ( ) ;
516+
517+ // Show stick coordinates and color
518+ ctx . fillStyle = 'white' ;
519+ ctx . font = '16px Arial' ;
520+ ctx . fillText ( `${ selectedColor . charAt ( 0 ) . toUpperCase ( ) + selectedColor . slice ( 1 ) } Stick: (${ stickX } , ${ stickY } )` , 10 , 20 ) ;
521+
522+ // Track rep based on stick movement
523+ const currentTime = Date . now ( ) ;
524+ const timeSinceLastRep = currentTime - lastRepTime ;
525+
526+ // Ready position: Stick must be high
527+ if ( stickY < canvas . height / 3 ) {
528+ stickStage = 'ready' ;
529+ }
530+
531+ // Follow through: Stick must move down with minimum time between reps
532+ if ( stickY > canvas . height * 2 / 3 &&
533+ stickStage === 'ready' &&
534+ timeSinceLastRep > REP_COOLDOWN ) {
535+ reps ++ ;
536+ stickStage = 'down' ;
537+ lastRepTime = currentTime ;
538+ document . getElementById ( 'reps' ) . textContent = `Reps: ${ reps } ` ;
533539 }
534540
535- } catch ( error ) {
536- console . error ( 'Detection error:' , error ) ;
541+ // Show current stage
542+ ctx . fillText ( `Stage: ${ stickStage || 'none' } ` , 10 , 40 ) ;
537543 }
538544
539- requestAnimationFrame ( detect ) ;
545+ } catch ( error ) {
546+ console . error ( 'Detection error:' , error ) ;
547+ }
548+
549+ requestAnimationFrame ( detect ) ;
540550 }
541551
542552 // Initialize variables
0 commit comments