Skip to content

Commit 4f6ce5c

Browse files
authored
Merge pull request #5 from centralelyon/dev
Main
2 parents 2052a66 + 79ec86b commit 4f6ce5c

13 files changed

Lines changed: 311 additions & 67 deletions

File tree

assets/css/custom.css

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,19 +440,62 @@ table {
440440
background-color: #232157;
441441
}
442442

443+
.radio-option input[type="checkbox"] {
444+
appearance: none;
445+
width: 20px;
446+
height: 20px;
447+
border: 2px solid #232157;
448+
border-radius: 4px;
449+
outline: none;
450+
margin-right: 8px;
451+
cursor: pointer;
452+
transition: background 0.2s ease-in-out;
453+
position: relative;
454+
}
455+
456+
.radio-option input[type="checkbox"]:checked {
457+
background-color: #232157;
458+
}
459+
460+
.radio-option input[type="checkbox"]:checked::after {
461+
content: "";
462+
position: absolute;
463+
left: 5px;
464+
top: 1px;
465+
width: 5px;
466+
height: 10px;
467+
border: solid #ffffff;
468+
border-width: 0 2px 2px 0;
469+
transform: rotate(45deg);
470+
}
471+
443472
.radio-option label {
444473
cursor: pointer;
445474
color: #000000;
446475
font-weight: bold;
447476
margin-right: 12px;
448477
}
478+
479+
.checkbox-option label {
480+
margin-right: 0;
481+
}
449482
#bottom_data .radio-group {
450483
display: inline-flex; /* inline pour centrer avec text-align */
451484
justify-content: center;
452485
gap: 1rem; /* espace entre les boutons */
453486
margin-top: 10px; /* si tu veux un peu d'air */
454487
}
455488

489+
.pool_boundary_line {
490+
position: absolute;
491+
height: 0;
492+
border-top: 3px solid rgba(46, 163, 221, 0.95);
493+
box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.35);
494+
transform-origin: left top;
495+
z-index: 998;
496+
pointer-events: none;
497+
}
498+
456499

457500

458501
/* The switch - the box around the slider */
@@ -1076,4 +1119,3 @@ padding: 20px;
10761119
max-width: 140px;
10771120
box-sizing: border-box;
10781121
}
1079-

assets/js/loader.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,19 @@ export let n_camera = 2;
7676
window.curr_swims = curr_swims; // Pour que curr_swims soit accessible au html
7777
window.selected_comp = selected_comp; // Pour que selected_comp soit accessible au html
7878

79+
function syncLoaderGlobals() {
80+
if (typeof window === "undefined") {
81+
return;
82+
}
83+
window.curr_swims = curr_swims;
84+
window.selected_comp = selected_comp;
85+
window.megaData = megaData;
86+
window.frame_rate = frame_rate;
87+
window.temp_end = temp_end;
88+
}
89+
90+
syncLoaderGlobals();
91+
7992
function extractLaneNumber(laneKey) {
8093
const match = String(laneKey).match(/\d+/);
8194
return match ? parseInt(match[0], 10) : Number.MAX_SAFE_INTEGER;
@@ -326,6 +339,7 @@ export async function getCompets() {
326339
$("#competition").val(selected_comp);
327340

328341
c.map(d => compets[d.name] = []);
342+
syncLoaderGlobals();
329343
return Promise.resolve();
330344
} else {
331345
const url = getApiUrl("/getCompets");
@@ -368,6 +382,7 @@ export async function getCompets() {
368382
$("#competition").val(selected_comp);
369383

370384
c.map(d => compets[d.name] = []);
385+
syncLoaderGlobals();
371386
},
372387
error: function(xhr, status, error) {
373388
console.error("getCompets: Error callback:", status, error, xhr);
@@ -858,6 +873,7 @@ export async function load_run(run, data, starTime = null) {
858873

859874
}
860875
}
876+
syncLoaderGlobals();
861877
$("#swim_switch").html("");
862878
clampSelectedSwim(laneCount);
863879
displaySwimmers(t["lignes"]);

assets/js/plot_handler.js

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { get_meter_plot_label } from './cycles_handler.js';
99
import { getMeta } from './utils.js';
1010

1111
export let show_indicator_lines = false;// Boolean correspondant au bouton Ligne Ref : true -> affichage et aide à la visée des lignes indicatrices, false -> pas d'affichage ni aide
12+
export let show_pool_boundaries = false;// Boolean correspondant à l'affichage des limites de la piscine calibrées dans le JSON
1213
let last_mode = "enter";// Dernier Mode d'annotation : quand on active les lignes ref on passe automatiquement en mode intermed, et quand on les désactive, on repasse en last_mode
1314
let ecart_bord_premiere_barre=5;
1415
let ecart_barres=10;
@@ -107,6 +108,113 @@ export function plot_indicator_lines(isPlot){
107108
}
108109
}
109110

111+
function getPoolBoundaryDisplayPoints(meta, container) {
112+
if (!meta?.srcPts || meta.srcPts.length < 2) {
113+
return [];
114+
}
115+
116+
const videoElement = document.getElementById("vid");
117+
if (!container || !videoElement) {
118+
return [];
119+
}
120+
121+
const [fallbackWidth, fallbackHeight] = getSize(meta);
122+
const sourceWidth = videoElement.videoWidth || meta.width || fallbackWidth;
123+
const sourceHeight = videoElement.videoHeight || meta.height || fallbackHeight;
124+
125+
if (sourceWidth <= 0 || sourceHeight <= 0) {
126+
return [];
127+
}
128+
129+
const containerRect = container.getBoundingClientRect();
130+
const videoRect = videoElement.getBoundingClientRect();
131+
const displayWidth = videoRect.width;
132+
const displayHeight = videoRect.height;
133+
134+
if (displayWidth <= 0 || displayHeight <= 0) {
135+
return [];
136+
}
137+
138+
const offsetLeft = videoRect.left - containerRect.left;
139+
const offsetTop = videoRect.top - containerRect.top;
140+
141+
return meta.srcPts.map(([x, y]) => [
142+
offsetLeft + (x / sourceWidth) * displayWidth,
143+
offsetTop + (y / sourceHeight) * displayHeight,
144+
]);
145+
}
146+
147+
export function plot_pool_boundaries(isPlot) {
148+
$(".pool_boundary_line").remove();
149+
150+
if (!isPlot) {
151+
return;
152+
}
153+
154+
const container = document.getElementById("video");
155+
let meta = null;
156+
try {
157+
meta = getMeta();
158+
} catch {
159+
return;
160+
}
161+
162+
if (!container || !meta) {
163+
return;
164+
}
165+
166+
const points = getPoolBoundaryDisplayPoints(meta, container);
167+
if (points.length < 2) {
168+
return;
169+
}
170+
171+
for (let i = 0; i < points.length; i++) {
172+
const start = points[i];
173+
const end = points[(i + 1) % points.length];
174+
const dx = end[0] - start[0];
175+
const dy = end[1] - start[1];
176+
const distance = Math.sqrt((dx * dx) + (dy * dy));
177+
const angle = Math.atan2(dy, dx) * (180 / Math.PI);
178+
179+
const line = document.createElement("div");
180+
line.setAttribute("class", "pool_boundary_line");
181+
line.style.left = `${start[0]}px`;
182+
line.style.top = `${start[1]}px`;
183+
line.style.width = `${distance}px`;
184+
line.style.transform = `rotate(${angle}deg)`;
185+
186+
container.append(line);
187+
}
188+
}
189+
190+
function syncPoolBoundariesToggle(checked) {
191+
show_pool_boundaries = checked;
192+
plot_pool_boundaries(show_pool_boundaries);
193+
}
194+
195+
window.addEventListener('DOMContentLoaded', function() {
196+
const boundariesToggle = document.getElementById('show_pool_boundaries');
197+
boundariesToggle?.addEventListener('change', function(e) {
198+
syncPoolBoundariesToggle(e.target.checked);
199+
});
200+
201+
document.getElementById('vid')?.addEventListener('loadedmetadata', function() {
202+
if (show_pool_boundaries) {
203+
plot_pool_boundaries(true);
204+
}
205+
});
206+
207+
document.getElementById('vid')?.addEventListener('loadstart', function() {
208+
plot_pool_boundaries(false);
209+
});
210+
211+
window.addEventListener('resize', function() {
212+
if (show_pool_boundaries) {
213+
plot_pool_boundaries(true);
214+
}
215+
});
216+
});
217+
110218
/**
111219
* Corrige la position du curseur selon les lignes indicatrices :
112220
* Si les lignes indicatrices sont actives et que le curseur est à moins de 1 mètre d'une ligne indicatrice : le curseur s'y colle
@@ -131,4 +239,4 @@ export function indicator_correction(x){
131239
return (x)
132240
}
133241
return x;
134-
}
242+
}

assets/js/refactor-script.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,25 @@ const codeNaNforDownload = "";// Lors du téléchargement des données, si une d
4242
choose_tab(null,"data_entry",'side_tab_content','sideTabLinks')
4343
construct_modify_selected_annotation_table(true)
4444

45+
function syncRefactorGlobals() {
46+
if (typeof window === "undefined") {
47+
return;
48+
}
49+
window.temp_start = temp_start;
50+
window.displayMode = displayMode;
51+
window.selected_swim = selected_swim;
52+
}
53+
54+
syncRefactorGlobals();
55+
4556
export function clampSelectedSwim(laneCount) {
4657
if (laneCount <= 0) {
4758
selected_swim = 0;
59+
syncRefactorGlobals();
4860
return;
4961
}
5062
selected_swim = Math.max(0, Math.min(selected_swim, laneCount - 1));
63+
syncRefactorGlobals();
5164
}
5265

5366
document.querySelectorAll(".__range-step").forEach(function (ctrl) {
@@ -99,6 +112,7 @@ export function clampSelectedSwim(laneCount) {
99112

100113
$("#kmod").on("input", function () {
101114
displayMode = $(this).val();
115+
syncRefactorGlobals();
102116
updateBarsFromEvent(selected_swim, true);
103117
})
104118

@@ -1138,6 +1152,7 @@ let pt=[0,0];
11381152
window.get_run_selected = get_run_selected;
11391153
export function edit_temp_start(x){
11401154
temp_start =x;
1155+
syncRefactorGlobals();
11411156
}
11421157
export function edit_selected_cycle(x){
11431158
selected_cycle=x;

index.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@
224224
<input type="radio" name="cote_action" id="droite" value="2">
225225
<label for="droite">droite</label>
226226
</div>
227+
<div class="radio-option checkbox-option">
228+
<input type="checkbox" id="show_pool_boundaries">
229+
<label for="show_pool_boundaries">piscine</label>
230+
</div>
227231
</div>
228232
<br>
229233

playwright-report/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,4 @@
7878
</body>
7979
</html>
8080
<script>
81-
window.playwrightReportBase64 = "data:application/zip;base64,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";</script>
81+
window.playwrightReportBase64 = "data:application/zip;base64,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";</script>

0 commit comments

Comments
 (0)