@@ -11,48 +11,55 @@ function SpinningCat() {
1111
1212 // Show ESC hint briefly
1313 useEffect ( ( ) => {
14- if ( escBtn ) {
15- const timer = setTimeout ( ( ) => setEscBtn ( false ) , 3000 ) ;
16- return ( ) => clearTimeout ( timer ) ;
17- }
14+ if ( ! escBtn ) return ;
15+ const timer = setTimeout ( ( ) => setEscBtn ( false ) , 3000 ) ;
16+ return ( ) => clearTimeout ( timer ) ;
1817 } , [ escBtn ] ) ;
1918
20- // 🔥 FULLSCREEN + PLAY VIDEO TOGETHER
19+ // 🔥 FULLSCREEN + SAFE AUTOPLAY (PRODUCTION SAFE)
2120 useEffect ( ( ) => {
22- const startVideo = async ( ) => {
23- if ( ! runCatVideo || ! containerRef . current || ! videoRef . current ) return ;
21+ if ( ! runCatVideo || ! containerRef . current || ! videoRef . current ) return ;
2422
23+ let cancelled = false ;
24+ const video = videoRef . current ;
25+
26+ const startVideo = async ( ) => {
2527 try {
26- await containerRef . current . requestFullscreen ( ) ;
27- videoRef . current . currentTime = 0 ;
28- await videoRef . current . play ( ) ;
28+ // Enter fullscreen
29+ await containerRef . current ! . requestFullscreen ( ) ;
30+
31+ // Wait until video is actually playable (VERY IMPORTANT for Vercel)
32+ if ( video . readyState < 3 ) {
33+ await new Promise < void > ( ( resolve ) => {
34+ video . oncanplay = ( ) => resolve ( ) ;
35+ } ) ;
36+ }
37+
38+ if ( cancelled ) return ;
39+
40+ video . currentTime = 0 ;
41+ await video . play ( ) ;
2942 } catch ( err ) {
30- console . log ( "Playback issue :" , err ) ;
43+ console . log ( "Video playback blocked :" , err ) ;
3144 }
3245 } ;
3346
34- if ( runCatVideo ) {
35- startVideo ( ) ;
36- } else if ( videoRef . current ) {
37- videoRef . current . pause ( ) ;
38- videoRef . current . currentTime = 0 ;
39- }
47+ startVideo ( ) ;
48+
49+ return ( ) => {
50+ cancelled = true ;
51+ } ;
4052 } , [ runCatVideo ] ) ;
4153
42- // ESC button + keyboard ESC
54+ // Keyboard ESC support
4355 useEffect ( ( ) => {
44- const escListener = ( e : KeyboardEvent ) => {
56+ const onKey = ( e : KeyboardEvent ) => {
4557 if ( e . key === "Escape" ) handleEscape ( ) ;
4658 } ;
47-
48- window . addEventListener ( "keydown" , escListener ) ;
49- return ( ) => window . removeEventListener ( "keydown" , escListener ) ;
59+ window . addEventListener ( "keydown" , onKey ) ;
60+ return ( ) => window . removeEventListener ( "keydown" , onKey ) ;
5061 } , [ ] ) ;
5162
52- const handleContainerClick = ( ) => {
53- setEscBtn ( true ) ;
54- } ;
55-
5663 const handleEscape = ( ) => {
5764 if ( videoRef . current ) {
5865 videoRef . current . pause ( ) ;
@@ -72,7 +79,7 @@ function SpinningCat() {
7279 < motion . div
7380 ref = { containerRef }
7481 className = "cat_container"
75- onClick = { handleContainerClick }
82+ onClick = { ( ) => setEscBtn ( true ) }
7683 exit = { { opacity : 0 } }
7784 transition = { { ease : "easeInOut" , duration : 0.5 } }
7885 >
@@ -94,6 +101,7 @@ function SpinningCat() {
94101 controls = { false }
95102 disablePictureInPicture
96103 controlsList = "nodownload noplaybackrate"
104+ crossOrigin = "anonymous"
97105 onEnded = { handleEscape }
98106 />
99107 </ motion . div >
0 commit comments