Update index.html
Browse files- index.html +108 -14
index.html
CHANGED
@@ -29,6 +29,7 @@
|
|
29 |
display: flex;
|
30 |
width: 100%;
|
31 |
max-width: 1500px;
|
|
|
32 |
}
|
33 |
|
34 |
.episode-list {
|
@@ -47,14 +48,23 @@
|
|
47 |
justify-content: space-between;
|
48 |
flex-grow: 1;
|
49 |
}
|
50 |
-
|
51 |
.video-container {
|
52 |
-
width:
|
53 |
}
|
54 |
|
55 |
#plotDiv {
|
56 |
-
width:
|
57 |
-
height:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
}
|
59 |
|
60 |
video {
|
@@ -67,7 +77,7 @@
|
|
67 |
justify-content: center;
|
68 |
margin-top: 2px;
|
69 |
}
|
70 |
-
|
71 |
button {
|
72 |
margin: 0 5px;
|
73 |
font-size: 20px;
|
@@ -82,7 +92,7 @@
|
|
82 |
display: block;
|
83 |
margin-bottom: 20px;
|
84 |
}
|
85 |
-
|
86 |
#loadingIndicator {
|
87 |
display: none;
|
88 |
position: fixed;
|
@@ -95,6 +105,41 @@
|
|
95 |
border-radius: 5px;
|
96 |
z-index: 1000;
|
97 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
</style>
|
99 |
</head>
|
100 |
|
@@ -102,16 +147,21 @@
|
|
102 |
<h1>Motion Capture Visualization</h1>
|
103 |
|
104 |
<div class="main-container">
|
|
|
105 |
<div class="episode-list">
|
106 |
<h3>Episodes</h3>
|
107 |
-
<!-- Episode checkboxes -->
|
108 |
<label><input type="checkbox"> Episode 1</label>
|
109 |
<label><input type="checkbox"> Episode 2</label>
|
110 |
-
<!-- ... Add all episodes up to 30 ... -->
|
111 |
<label><input type="checkbox"> Episode 29</label>
|
112 |
<label><input type="checkbox"> Episode 30</label>
|
113 |
</div>
|
114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
<div class="content-container">
|
116 |
<div class="checkbox-container">
|
117 |
<h3>Tasks</h3>
|
@@ -162,6 +212,19 @@
|
|
162 |
const forwardBtn = document.getElementById('forwardBtn');
|
163 |
const restartBtn = document.getElementById('restartBtn');
|
164 |
const radioButtons = document.querySelectorAll('input[name="videoOption"]');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
let animationFrameId;
|
166 |
let isPlaying = false;
|
167 |
function togglePlayPause() {
|
@@ -208,7 +271,7 @@
|
|
208 |
z: getCoordinates(row, 'z'),
|
209 |
mode: 'markers',
|
210 |
type: 'scatter3d',
|
211 |
-
marker: { size: 4, color:
|
212 |
}]
|
213 |
}));
|
214 |
if (frames.length === 0) {
|
@@ -217,11 +280,42 @@
|
|
217 |
}
|
218 |
const initialFrame = frames[0].data[0];
|
219 |
const layout = {
|
220 |
-
title:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
221 |
scene: {
|
222 |
-
xaxis: {
|
223 |
-
|
224 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
225 |
}
|
226 |
};
|
227 |
Plotly.newPlot('plotDiv', [initialFrame], layout);
|
|
|
29 |
display: flex;
|
30 |
width: 100%;
|
31 |
max-width: 1500px;
|
32 |
+
margin-top: 100px;
|
33 |
}
|
34 |
|
35 |
.episode-list {
|
|
|
48 |
justify-content: space-between;
|
49 |
flex-grow: 1;
|
50 |
}
|
51 |
+
|
52 |
.video-container {
|
53 |
+
width: 58%;
|
54 |
}
|
55 |
|
56 |
#plotDiv {
|
57 |
+
width: 460px;
|
58 |
+
height: 485px;
|
59 |
+
}
|
60 |
+
|
61 |
+
#episodes-container {
|
62 |
+
display: grid;
|
63 |
+
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
64 |
+
gap: 2px;
|
65 |
+
padding: 0px;
|
66 |
+
background-color: #222;
|
67 |
+
border-radius: 3px;
|
68 |
}
|
69 |
|
70 |
video {
|
|
|
77 |
justify-content: center;
|
78 |
margin-top: 2px;
|
79 |
}
|
80 |
+
·
|
81 |
button {
|
82 |
margin: 0 5px;
|
83 |
font-size: 20px;
|
|
|
92 |
display: block;
|
93 |
margin-bottom: 20px;
|
94 |
}
|
95 |
+
|
96 |
#loadingIndicator {
|
97 |
display: none;
|
98 |
position: fixed;
|
|
|
105 |
border-radius: 5px;
|
106 |
z-index: 1000;
|
107 |
}
|
108 |
+
|
109 |
+
.checkbox-list {
|
110 |
+
max-height: 400px; /* 设置最大高度,超过此高度会出现滚动条 */
|
111 |
+
overflow-y: auto; /* 添加垂直滚动条 */
|
112 |
+
padding-right: 10px; /* 为滚动条留出空间 */
|
113 |
+
}
|
114 |
+
|
115 |
+
.checkbox-list label {
|
116 |
+
display: block;
|
117 |
+
margin-bottom: 0px;
|
118 |
+
color: #ddd;
|
119 |
+
}
|
120 |
+
|
121 |
+
.checkbox-list input[type="checkbox"] {
|
122 |
+
margin-right: 10px;
|
123 |
+
}
|
124 |
+
|
125 |
+
/* 自定义滚动条样式(针对WebKit浏览器) */
|
126 |
+
.checkbox-list::-webkit-scrollbar {
|
127 |
+
width: 0px;
|
128 |
+
}
|
129 |
+
|
130 |
+
.checkbox-list::-webkit-scrollbar-track {
|
131 |
+
background: #333;
|
132 |
+
border-radius: 4px;
|
133 |
+
}
|
134 |
+
|
135 |
+
.checkbox-list::-webkit-scrollbar-thumb {
|
136 |
+
background: #666;
|
137 |
+
border-radius: 4px;
|
138 |
+
}
|
139 |
+
|
140 |
+
.checkbox-list::-webkit-scrollbar-thumb:hover {
|
141 |
+
background: #888;
|
142 |
+
}
|
143 |
</style>
|
144 |
</head>
|
145 |
|
|
|
147 |
<h1>Motion Capture Visualization</h1>
|
148 |
|
149 |
<div class="main-container">
|
150 |
+
<!--
|
151 |
<div class="episode-list">
|
152 |
<h3>Episodes</h3>
|
|
|
153 |
<label><input type="checkbox"> Episode 1</label>
|
154 |
<label><input type="checkbox"> Episode 2</label>
|
|
|
155 |
<label><input type="checkbox"> Episode 29</label>
|
156 |
<label><input type="checkbox"> Episode 30</label>
|
157 |
</div>
|
158 |
+
-->
|
159 |
+
<div id="episodes-container">
|
160 |
+
<h3>Episodes</h3>
|
161 |
+
<div class="checkbox-list">
|
162 |
+
<!-- 复选框将在这里动态生成 -->
|
163 |
+
</div>
|
164 |
+
</div>
|
165 |
<div class="content-container">
|
166 |
<div class="checkbox-container">
|
167 |
<h3>Tasks</h3>
|
|
|
212 |
const forwardBtn = document.getElementById('forwardBtn');
|
213 |
const restartBtn = document.getElementById('restartBtn');
|
214 |
const radioButtons = document.querySelectorAll('input[name="videoOption"]');
|
215 |
+
let totalEpisodes = 30; //获取episode的数量
|
216 |
+
// const container = document.getElementById('episodes-container')
|
217 |
+
// 循环创建复选框
|
218 |
+
const container = document.querySelector('#episodes-container .checkbox-list');
|
219 |
+
for (let i = 1; i <= totalEpisodes; i++) {
|
220 |
+
const label = document.createElement('label');
|
221 |
+
const checkbox = document.createElement('input');
|
222 |
+
checkbox.type = 'checkbox';
|
223 |
+
checkbox.id = `episode-${i}`;
|
224 |
+
label.appendChild(checkbox);
|
225 |
+
label.appendChild(document.createTextNode(` Episode ${i}`));
|
226 |
+
container.appendChild(label);
|
227 |
+
}
|
228 |
let animationFrameId;
|
229 |
let isPlaying = false;
|
230 |
function togglePlayPause() {
|
|
|
271 |
z: getCoordinates(row, 'z'),
|
272 |
mode: 'markers',
|
273 |
type: 'scatter3d',
|
274 |
+
marker: { size: 4.8, color: "blue" }
|
275 |
}]
|
276 |
}));
|
277 |
if (frames.length === 0) {
|
|
|
280 |
}
|
281 |
const initialFrame = frames[0].data[0];
|
282 |
const layout = {
|
283 |
+
title: {
|
284 |
+
text: '3D Motion Capture',
|
285 |
+
font: {
|
286 |
+
color: 'white',
|
287 |
+
size: 20 // 设置字体大小
|
288 |
+
},
|
289 |
+
x: 0.5, // 设置标题在x轴的位置(0.5表示居中)
|
290 |
+
y: 1
|
291 |
+
},
|
292 |
+
paper_bgcolor: 'black',
|
293 |
+
plot_bgcolor: 'black',
|
294 |
scene: {
|
295 |
+
xaxis: {
|
296 |
+
title: 'X',
|
297 |
+
color: 'white',
|
298 |
+
gridcolor: 'gray'
|
299 |
+
},
|
300 |
+
yaxis: {
|
301 |
+
title: 'Y',
|
302 |
+
color: 'white',
|
303 |
+
gridcolor: 'gray'
|
304 |
+
},
|
305 |
+
zaxis: {
|
306 |
+
title: 'Z',
|
307 |
+
color: 'white',
|
308 |
+
gridcolor: 'gray'
|
309 |
+
},
|
310 |
+
bgcolor: 'black'
|
311 |
+
},
|
312 |
+
font: { color: 'white' },
|
313 |
+
margin: {
|
314 |
+
l: 2, // 左边距
|
315 |
+
r: 2, // 右边距
|
316 |
+
b: 2, // 底部边距
|
317 |
+
t: 50, // 顶部边距
|
318 |
+
pad: 4 // 图表内边距
|
319 |
}
|
320 |
};
|
321 |
Plotly.newPlot('plotDiv', [initialFrame], layout);
|