woshiwahah commited on
Commit
c475101
1 Parent(s): 020daf6

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +252 -1
index.html CHANGED
@@ -1 +1,252 @@
1
- The first version of index.html
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Motion Capture Visualization</title>
8
+ <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
9
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.0/papaparse.min.js"></script>
10
+ <style>
11
+ body {
12
+ font-family: Arial, sans-serif;
13
+ margin: 0;
14
+ padding: 20px;
15
+ display: flex;
16
+ flex-direction: column;
17
+ align-items: center;
18
+ }
19
+
20
+ .content-container {
21
+ display: flex;
22
+ justify-content: space-between;
23
+ width: 100%;
24
+ max-width: 1200px;
25
+ margin-top: 20px;
26
+ }
27
+
28
+ .video-container {
29
+ width: 48%;
30
+ }
31
+
32
+ #plotDiv {
33
+ width: 48%;
34
+ height: 400px;
35
+ }
36
+
37
+ video {
38
+ width: 100%;
39
+ height: auto;
40
+ }
41
+
42
+ .controls {
43
+ display: flex;
44
+ justify-content: center;
45
+ margin-top: 10px;
46
+ }
47
+
48
+ button {
49
+ margin: 0 5px;
50
+ font-size: 20px;
51
+ }
52
+
53
+ .checkbox-container {
54
+ margin-bottom: 20px;
55
+ }
56
+
57
+ #loadingIndicator {
58
+ display: none;
59
+ position: fixed;
60
+ top: 50%;
61
+ left: 50%;
62
+ transform: translate(-50%, -50%);
63
+ background-color: rgba(0, 0, 0, 0.7);
64
+ color: white;
65
+ padding: 20px;
66
+ border-radius: 5px;
67
+ z-index: 1000;
68
+ }
69
+ </style>
70
+ </head>
71
+
72
+ <body>
73
+ <h1>Motion Capture Visualization</h1>
74
+
75
+ <div class="checkbox-container">
76
+ <label>
77
+ <input type="radio" name="videoOption" value="fold_towels" checked> Fold towels
78
+ </label>
79
+ <label>
80
+ <input type="radio" name="videoOption" value="pipette"> Pipette
81
+ </label>
82
+ <label>
83
+ <input type="radio" name="videoOption" value="take_the_item"> Take the item
84
+ </label>
85
+ <label>
86
+ <input type="radio" name="videoOption" value="twist_the_tube"> Twist the tube
87
+ </label>
88
+ </div>
89
+
90
+ <div class="content-container">
91
+ <div class="video-container">
92
+ <video id="laptopVideo">
93
+ <source src="https://huggingface.co/datasets/cyberorigin/fold_towels/resolve/main/Video/video.mp4"
94
+ type="video/mp4">
95
+ Your browser does not support the video tag.
96
+ </video>
97
+ <div class="controls">
98
+ <button id="playPauseBtn">▶️</button>
99
+ <button id="rewindBtn">⏪</button>
100
+ <button id="forwardBtn">⏩</button>
101
+ <button id="restartBtn">↩️</button>
102
+ </div>
103
+ </div>
104
+ <div id="plotDiv"></div>
105
+ </div>
106
+
107
+ <div id="loadingIndicator">Loading...</div>
108
+
109
+ <script>
110
+ let csvFilePath = 'https://huggingface.co/datasets/cyberorigin/fold_towels/resolve/main/MoCap/mocap.csv';
111
+ const body_part_names = [
112
+ 'Left Shoulder', 'Right Upper Arm', 'Left Lower Leg', 'Spine1', 'Right Upper Leg',
113
+ 'Spine3', 'Right Lower Arm', 'Left Foot', 'Right Lower Leg', 'Right Shoulder',
114
+ 'Left Hand', 'Left Upper Leg', 'Right Foot', 'Spine', 'Spine2', 'Left Lower Arm',
115
+ 'Left Toe', 'Neck', 'Right Hand', 'Right Toe', 'Head', 'Left Upper Arm', 'Hips'
116
+ ];
117
+ const laptopVideo = document.getElementById('laptopVideo');
118
+ const playPauseBtn = document.getElementById('playPauseBtn');
119
+ const rewindBtn = document.getElementById('rewindBtn');
120
+ const forwardBtn = document.getElementById('forwardBtn');
121
+ const restartBtn = document.getElementById('restartBtn');
122
+ const radioButtons = document.querySelectorAll('input[name="videoOption"]');
123
+ let animationFrameId;
124
+ let isPlaying = false;
125
+ function togglePlayPause() {
126
+ if (!isPlaying) {
127
+ laptopVideo.play();
128
+ playPauseBtn.textContent = '⏸️';
129
+ isPlaying = true;
130
+ animate3DVisualization();
131
+ } else {
132
+ laptopVideo.pause();
133
+ playPauseBtn.textContent = '▶️';
134
+ isPlaying = false;
135
+ cancelAnimationFrame(animationFrameId);
136
+ }
137
+ }
138
+ function rewind() {
139
+ laptopVideo.currentTime -= 5;
140
+ update3DVisualization();
141
+ }
142
+ function forward() {
143
+ laptopVideo.currentTime += 5;
144
+ update3DVisualization();
145
+ }
146
+ function restart() {
147
+ laptopVideo.currentTime = 0;
148
+ update3DVisualization();
149
+ }
150
+ playPauseBtn.addEventListener('click', togglePlayPause);
151
+ rewindBtn.addEventListener('click', rewind);
152
+ forwardBtn.addEventListener('click', forward);
153
+ restartBtn.addEventListener('click', restart);
154
+ function getCoordinates(data, coordinate) {
155
+ return body_part_names.map(part => parseFloat(data[`${part}_${coordinate}`]));
156
+ }
157
+ let frames;
158
+ function processData(results) {
159
+ console.log("Processing data:", results);
160
+ const motion_capture_data = results.data.filter((_, index) => index % 5 === 0);
161
+ frames = motion_capture_data.map((row, index) => ({
162
+ name: index.toString(),
163
+ data: [{
164
+ x: getCoordinates(row, 'x'),
165
+ y: getCoordinates(row, 'y'),
166
+ z: getCoordinates(row, 'z'),
167
+ mode: 'markers',
168
+ type: 'scatter3d',
169
+ marker: { size: 5, color: 'blue' }
170
+ }]
171
+ }));
172
+ if (frames.length === 0) {
173
+ console.error("No frames were created from the data");
174
+ return;
175
+ }
176
+ const initialFrame = frames[0].data[0];
177
+ const layout = {
178
+ title: '3D Motion Capture',
179
+ scene: {
180
+ xaxis: { title: 'X' },
181
+ yaxis: { title: 'Y' },
182
+ zaxis: { title: 'Z' }
183
+ }
184
+ };
185
+ Plotly.newPlot('plotDiv', [initialFrame], layout);
186
+ }
187
+ function update3DVisualization() {
188
+ if (!frames) return;
189
+ const currentTime = laptopVideo.currentTime;
190
+ const totalDuration = laptopVideo.duration;
191
+ const frameIndex = Math.floor((currentTime / totalDuration) * frames.length);
192
+ const frame = frames[Math.min(frameIndex, frames.length - 1)];
193
+ Plotly.animate('plotDiv', frame, {
194
+ transition: { duration: 0 },
195
+ frame: { duration: 0, redraw: true }
196
+ });
197
+ }
198
+ function animate3DVisualization() {
199
+ update3DVisualization();
200
+ if (isPlaying) {
201
+ animationFrameId = requestAnimationFrame(animate3DVisualization);
202
+ }
203
+ }
204
+ function updateVideoAndCSVSource() {
205
+ const selectedOption = document.querySelector('input[name="videoOption"]:checked').value;
206
+ const videoUrl = `https://huggingface.co/datasets/cyberorigin/${selectedOption}/resolve/main/Video/video.mp4`;
207
+ if (selectedOption != "twist_the_tube") {
208
+ csvFilePath = `https://huggingface.co/datasets/cyberorigin/${selectedOption}/resolve/main/MoCap/mocap.csv`;
209
+ }
210
+ else {
211
+ csvFilePath = `https://huggingface.co/datasets/cyberorigin/${selectedOption}/resolve/main/MoCap/MoCap.csv`;
212
+ }
213
+
214
+
215
+ laptopVideo.pause();
216
+
217
+ laptopVideo.querySelector('source').src = videoUrl;
218
+
219
+ laptopVideo.load();
220
+
221
+ isPlaying = false;
222
+ playPauseBtn.textContent = '▶️';
223
+ // Fetch and process the new CSV data
224
+ fetchAndProcessCSV();
225
+ }
226
+ function fetchAndProcessCSV() {
227
+ fetch(csvFilePath)
228
+ .then(response => {
229
+ if (!response.ok) {
230
+ throw new Error(`HTTP error! status: ${response.status}`);
231
+ }
232
+ return response.text();
233
+ })
234
+ .then(csvString => {
235
+ console.log("CSV data loaded successfully");
236
+ Papa.parse(csvString, {
237
+ header: true,
238
+ dynamicTyping: true,
239
+ complete: processData
240
+ });
241
+ })
242
+ .catch(error => console.error('Error loading the CSV file:', error));
243
+ }
244
+ radioButtons.forEach(radio => {
245
+ radio.addEventListener('change', updateVideoAndCSVSource);
246
+ });
247
+ // Initial CSV fetch and processing
248
+ fetchAndProcessCSV();
249
+ </script>
250
+ </body>
251
+
252
+ </html>