Skip to content

Commit 02b99e0

Browse files
fixing smooth pursuit
1 parent 83d997e commit 02b99e0

File tree

1 file changed

+35
-90
lines changed

1 file changed

+35
-90
lines changed

webcamstudy/src/components/SmoothPursuitVideoTask.jsx

Lines changed: 35 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,23 @@
11
import React, { useEffect, useRef, useState } from 'react';
22

3+
// 1. Import video files directly at the top
4+
// This is the modern and most reliable way to handle static assets.
5+
import circleVideo from '../assets/smooth-pursuit/Circle.mp4';
6+
import squareVideo from '../assets/smooth-pursuit/Square.mp4';
7+
import infinityVideo from '../assets/smooth-pursuit/Infinity.mp4';
8+
import starVideo from '../assets/smooth-pursuit/Star.mp4';
9+
import triangleVideo from '../assets/smooth-pursuit/Triangle.mp4';
10+
import leftRightVideo from '../assets/smooth-pursuit/left_right.mp4';
11+
12+
// Use the imported variables in your array.
13+
// The 'type' property is no longer needed as we set the src directly.
314
const SMOOTH_PURSUIT_VIDEOS = [
4-
{
5-
src: require('../assets/smooth-pursuit/Circle.mp4'),
6-
name: 'Circle',
7-
type: 'video/mp4',
8-
},
9-
{
10-
src: require('../assets/smooth-pursuit/Square.mp4'),
11-
name: 'Square',
12-
type: 'video/mp4',
13-
},
14-
{
15-
src: require('../assets/smooth-pursuit/Infinity.mp4'),
16-
name: 'Infinity',
17-
type: 'video/mp4',
18-
},
19-
{
20-
src: require('../assets/smooth-pursuit/Star.mp4'),
21-
name: 'Star',
22-
type: 'video/mp4',
23-
},
24-
{
25-
src: require('../assets/smooth-pursuit/Triangle.mp4'),
26-
name: 'Triangle',
27-
type: 'video/mp4',
28-
},
29-
{
30-
src: require('../assets/smooth-pursuit/left_right.mp4'),
31-
name: 'Left to Right',
32-
type: 'video/mp4',
33-
},
15+
{ src: circleVideo, name: 'Circle' },
16+
{ src: squareVideo, name: 'Square' },
17+
{ src: infinityVideo, name: 'Infinity' },
18+
{ src: starVideo, name: 'Star' },
19+
{ src: triangleVideo, name: 'Triangle' },
20+
{ src: leftRightVideo, name: 'Left to Right' },
3421
];
3522

3623
const SmoothPursuitVideoTask = ({ onSubmit, onTaskComplete }) => {
@@ -43,29 +30,22 @@ const SmoothPursuitVideoTask = ({ onSubmit, onTaskComplete }) => {
4330
const currentVideo = SMOOTH_PURSUIT_VIDEOS[currentVideoIndex];
4431
const isLastVideo = currentVideoIndex === SMOOTH_PURSUIT_VIDEOS.length - 1;
4532

46-
// Handle phase transitions for each video
33+
// This logic remains the same
4734
useEffect(() => {
4835
setPhase('cross');
4936
setVideoEnded(false);
5037
setVideoError(false);
5138

52-
// Cross phase (1 second)
53-
const crossTimer = setTimeout(() => {
54-
setPhase('instruction');
55-
}, 1000);
56-
57-
// Instruction phase (1 second)
58-
const instructionTimer = setTimeout(() => {
59-
setPhase('video');
60-
}, 2000);
39+
const crossTimer = setTimeout(() => setPhase('instruction'), 1000);
40+
const instructionTimer = setTimeout(() => setPhase('video'), 2000);
6141

6242
return () => {
6343
clearTimeout(crossTimer);
6444
clearTimeout(instructionTimer);
6545
};
6646
}, [currentVideoIndex]);
6747

68-
// Handle video events
48+
// This logic remains the same
6949
useEffect(() => {
7050
const video = videoRef.current;
7151
if (!video || phase !== 'video') return;
@@ -76,57 +56,35 @@ const SmoothPursuitVideoTask = ({ onSubmit, onTaskComplete }) => {
7656
onTaskComplete?.();
7757
}
7858
};
79-
80-
const handleError = () => {
59+
const handleError = (e) => {
8160
setVideoError(true);
82-
console.error('Video playback error for:', currentVideo.src);
61+
console.error('Video playback error:', currentVideo.name, e);
8362
};
84-
8563
const handleCanPlay = () => {
8664
setVideoError(false);
87-
// Auto-play when video is ready
88-
video.play().catch(error => {
89-
console.warn('Autoplay failed:', error);
90-
});
91-
};
92-
93-
// Prevent fullscreen attempts
94-
const preventFullscreen = (e) => {
95-
e.preventDefault();
96-
e.stopPropagation();
97-
return false;
65+
video.play().catch(error => console.warn('Autoplay failed:', error));
9866
};
9967

10068
video.addEventListener('ended', handleEnded);
10169
video.addEventListener('error', handleError);
10270
video.addEventListener('canplay', handleCanPlay);
103-
video.addEventListener('dblclick', preventFullscreen);
104-
video.addEventListener('webkitbeginfullscreen', preventFullscreen);
105-
video.addEventListener('mozfullscreenchange', preventFullscreen);
106-
video.addEventListener('fullscreenchange', preventFullscreen);
10771

10872
return () => {
10973
video.removeEventListener('ended', handleEnded);
11074
video.removeEventListener('error', handleError);
11175
video.removeEventListener('canplay', handleCanPlay);
112-
video.removeEventListener('dblclick', preventFullscreen);
113-
video.removeEventListener('webkitbeginfullscreen', preventFullscreen);
114-
video.removeEventListener('mozfullscreenchange', preventFullscreen);
115-
video.removeEventListener('fullscreenchange', preventFullscreen);
11676
};
117-
}, [phase, currentVideo]);
77+
}, [phase, currentVideo, isLastVideo, onTaskComplete]);
11878

11979
const handleNextVideo = () => {
12080
if (isLastVideo) {
121-
// All videos completed - store data and signal task completion
12281
const completionData = {
12382
videosCompleted: SMOOTH_PURSUIT_VIDEOS.length,
12483
completedAt: new Date().toISOString()
12584
};
12685
onSubmit?.(completionData);
127-
onTaskComplete?.(); // Signal that the task is complete to show next button
86+
onTaskComplete?.();
12887
} else {
129-
// Move to next video
13088
setCurrentVideoIndex(prev => prev + 1);
13189
}
13290
};
@@ -139,35 +97,30 @@ const SmoothPursuitVideoTask = ({ onSubmit, onTaskComplete }) => {
13997
<div style={styles.cross}>+</div>
14098
</div>
14199
);
142-
143100
case 'instruction':
144101
return (
145102
<div style={styles.phaseContainer}>
146-
<h2 style={styles.instructionText}>
147-
Track the ball in the video
148-
</h2>
103+
<h2 style={styles.instructionText}>Track the ball in the video</h2>
149104
</div>
150105
);
151-
152106
case 'video':
153107
return (
154108
<div style={styles.videoContainer}>
155109
{videoError ? (
156110
<div style={styles.errorContainer}>
157111
<h3>Video Loading Error</h3>
158112
<p>There was an issue loading: {currentVideo.name}</p>
159-
<button
160-
onClick={handleNextVideo}
161-
style={styles.errorButton}
162-
>
163-
{isLastVideo ? 'Finish Videos' : 'Skip to Next Video'}
113+
<button onClick={handleNextVideo} style={styles.errorButton}>
114+
{isLastVideo ? 'Finish Task' : 'Skip to Next Video'}
164115
</button>
165116
</div>
166117
) : (
167118
<>
119+
{/* 2. Set the 'src' attribute directly on the <video> tag */}
168120
<video
169121
ref={videoRef}
170122
style={styles.video}
123+
src={currentVideo.src}
171124
controls
172125
muted
173126
playsInline
@@ -177,35 +130,27 @@ const SmoothPursuitVideoTask = ({ onSubmit, onTaskComplete }) => {
177130
onContextMenu={(e) => e.preventDefault()}
178131
onDoubleClick={(e) => e.preventDefault()}
179132
>
180-
<source src={currentVideo.src} type={currentVideo.type} />
181133
Your browser does not support the video tag.
182134
</video>
183135

184136
{videoEnded && !isLastVideo && (
185-
<button
186-
onClick={handleNextVideo}
187-
style={styles.nextButton}
188-
>
189-
{'Next Video'}
137+
<button onClick={handleNextVideo} style={styles.nextButton}>
138+
Next Video
190139
</button>
191140
)}
192141
</>
193142
)}
194143
</div>
195144
);
196-
197145
default:
198146
return null;
199147
}
200148
};
201149

202-
return (
203-
<div style={styles.container}>
204-
{renderContent()}
205-
</div>
206-
);
150+
return <div style={styles.container}>{renderContent()}</div>;
207151
};
208152

153+
// Styles remain the same
209154
const styles = {
210155
container: {
211156
height: '100vh',

0 commit comments

Comments
 (0)