Skip to content

Commit f81cd21

Browse files
committed
Add a checkbox in the UI that shows the swimming pool boundaries from the json file button should be next to droite
1 parent 7e971bc commit f81cd21

4 files changed

Lines changed: 163 additions & 3 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/plot_handler.js

Lines changed: 111 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,115 @@ 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 [videoWidth, videoHeight] = getSize(meta);
117+
const containerWidth = container?.clientWidth || videoWidth;
118+
const containerHeight = container?.clientHeight || videoHeight;
119+
120+
if (containerWidth <= 0 || containerHeight <= 0 || videoWidth <= 0 || videoHeight <= 0) {
121+
return [];
122+
}
123+
124+
const containerRatio = containerWidth / containerHeight;
125+
const videoRatio = videoWidth / videoHeight;
126+
let visibleWidth = videoWidth;
127+
let visibleHeight = videoHeight;
128+
let cropLeft = 0;
129+
let cropTop = 0;
130+
131+
if (videoRatio > containerRatio) {
132+
visibleWidth = videoHeight * containerRatio;
133+
cropLeft = (videoWidth - visibleWidth) / 2;
134+
} else if (videoRatio < containerRatio) {
135+
visibleHeight = videoWidth / containerRatio;
136+
cropTop = (videoHeight - visibleHeight) / 2;
137+
}
138+
139+
if (visibleWidth <= 0 || visibleHeight <= 0) {
140+
return [];
141+
}
142+
143+
return meta.srcPts.map(([x, y]) => [
144+
((x - cropLeft) / visibleWidth) * containerWidth,
145+
((y - cropTop) / visibleHeight) * containerHeight,
146+
]);
147+
}
148+
149+
export function plot_pool_boundaries(isPlot) {
150+
$(".pool_boundary_line").remove();
151+
152+
if (!isPlot) {
153+
return;
154+
}
155+
156+
const container = document.getElementById("video");
157+
let meta = null;
158+
try {
159+
meta = getMeta();
160+
} catch {
161+
return;
162+
}
163+
164+
if (!container || !meta) {
165+
return;
166+
}
167+
168+
const points = getPoolBoundaryDisplayPoints(meta, container);
169+
if (points.length < 2) {
170+
return;
171+
}
172+
173+
for (let i = 0; i < points.length; i++) {
174+
const start = points[i];
175+
const end = points[(i + 1) % points.length];
176+
const dx = end[0] - start[0];
177+
const dy = end[1] - start[1];
178+
const distance = Math.sqrt((dx * dx) + (dy * dy));
179+
const angle = Math.atan2(dy, dx) * (180 / Math.PI);
180+
181+
const line = document.createElement("div");
182+
line.setAttribute("class", "pool_boundary_line");
183+
line.style.left = `${start[0]}px`;
184+
line.style.top = `${start[1]}px`;
185+
line.style.width = `${distance}px`;
186+
line.style.transform = `rotate(${angle}deg)`;
187+
188+
container.append(line);
189+
}
190+
}
191+
192+
function syncPoolBoundariesToggle(checked) {
193+
show_pool_boundaries = checked;
194+
plot_pool_boundaries(show_pool_boundaries);
195+
}
196+
197+
window.addEventListener('DOMContentLoaded', function() {
198+
const boundariesToggle = document.getElementById('show_pool_boundaries');
199+
boundariesToggle?.addEventListener('change', function(e) {
200+
syncPoolBoundariesToggle(e.target.checked);
201+
});
202+
203+
document.getElementById('vid')?.addEventListener('loadedmetadata', function() {
204+
if (show_pool_boundaries) {
205+
plot_pool_boundaries(true);
206+
}
207+
});
208+
209+
document.getElementById('vid')?.addEventListener('loadstart', function() {
210+
plot_pool_boundaries(false);
211+
});
212+
213+
window.addEventListener('resize', function() {
214+
if (show_pool_boundaries) {
215+
plot_pool_boundaries(true);
216+
}
217+
});
218+
});
219+
110220
/**
111221
* Corrige la position du curseur selon les lignes indicatrices :
112222
* 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 +241,4 @@ export function indicator_correction(x){
131241
return (x)
132242
}
133243
return x;
134-
}
244+
}

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

workflow/test/index-test.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@
240240
<input type="radio" name="cote_action" id="droite" value="2">
241241
<label for="droite">droite</label>
242242
</div>
243+
<div class="radio-option checkbox-option">
244+
<input type="checkbox" id="show_pool_boundaries">
245+
<label for="show_pool_boundaries">piscine</label>
246+
</div>
243247
</div>
244248
<br>
245249

@@ -473,4 +477,4 @@
473477

474478
</body>
475479

476-
</html>
480+
</html>

0 commit comments

Comments
 (0)