fix(vwb): image plein écran — calcul dimensions JS explicite (fix définitif)
Some checks failed
security-audit / Bandit (scan statique) (push) Successful in 12s
security-audit / pip-audit (CVE dépendances) (push) Successful in 11s
security-audit / Scan secrets (grep) (push) Successful in 9s
tests / Lint (ruff + black) (push) Successful in 14s
tests / Tests unitaires (sans GPU) (push) Failing after 14s
tests / Tests sécurité (critique) (push) Has been skipped

Cause racine : max-width/max-height CSS ne font pas GRANDIR une image.
Fix : calcul explicite width/height en JS via Math.min(ratio).
min-height:0 sur le conteneur flex.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dom
2026-04-21 12:19:30 +02:00
parent 8ce63fcba2
commit 3e227d28ad
2 changed files with 54 additions and 16 deletions

View File

@@ -412,6 +412,11 @@ function FullscreenSelector({
// Scale de l'image affichee par rapport a l'image naturelle
const [imageScale, setImageScale] = useState({ x: 1, y: 1 });
// Dimensions explicites de l'image (calculees pour remplir le conteneur en contain)
// Resout le bug "timbre poste" : max-width/max-height seuls ne font PAS grandir
// une image plus petite que le conteneur. On calcule la taille explicitement.
const [imgDisplaySize, setImgDisplaySize] = useState<{ width: number; height: number } | null>(null);
// ── Detection automatique des elements UI ──
useEffect(() => {
const runDetection = async () => {
@@ -433,17 +438,38 @@ function FullscreenSelector({
runDetection();
}, [capture.screenshot_base64]);
// ── Calcul de imageRect et imageScale ──
// ── Calcul des dimensions image + imageRect + imageScale ──
// Appele au chargement de l'image ET au redimensionnement de la fenetre.
// Calcule la taille "contain" (remplir le conteneur en gardant le ratio)
// et l'applique comme width/height explicite sur l'img.
const recalcImageRect = useCallback(() => {
if (!imgRef.current || !contentRef.current) return;
const containerRect = contentRef.current.getBoundingClientRect();
const natW = imgRef.current.naturalWidth;
const natH = imgRef.current.naturalHeight;
if (natW > 0 && natH > 0) {
// Calcul "contain" : ratio le plus contraignant
const scale = Math.min(
containerRect.width / natW,
containerRect.height / natH
);
const displayW = Math.round(natW * scale);
const displayH = Math.round(natH * scale);
setImgDisplaySize({ width: displayW, height: displayH });
}
// Apres le render avec les nouvelles dimensions, recalculer imageRect
// On utilise requestAnimationFrame pour lire le layout apres le paint
requestAnimationFrame(() => {
if (!imgRef.current || !contentRef.current) return;
const cRect = contentRef.current.getBoundingClientRect();
const imgBounds = imgRef.current.getBoundingClientRect();
setImageRect({
left: imgBounds.left - containerRect.left,
top: imgBounds.top - containerRect.top,
left: imgBounds.left - cRect.left,
top: imgBounds.top - cRect.top,
width: imgBounds.width,
height: imgBounds.height,
});
@@ -452,6 +478,7 @@ function FullscreenSelector({
x: imgBounds.width / imgRef.current.naturalWidth,
y: imgBounds.height / imgRef.current.naturalHeight,
});
});
}, []);
const handleImageLoad = () => {
@@ -601,7 +628,7 @@ function FullscreenSelector({
<button onClick={onClose}>Fermer (Echap)</button>
</div>
{/* Zone de contenu : flex center, l'image se dimensionne via max-width/max-height */}
{/* Zone de contenu : flex center, l'image se dimensionne via imgDisplaySize (contain calcule en JS) */}
<div
className="fullscreen-content"
ref={contentRef}
@@ -615,7 +642,13 @@ function FullscreenSelector({
alt="Capture plein ecran"
draggable={false}
onLoad={handleImageLoad}
style={{ maxWidth: '100%', maxHeight: 'calc(100vh - 70px)', objectFit: 'contain' }}
style={imgDisplaySize ? {
width: imgDisplaySize.width,
height: imgDisplaySize.height,
} : {
maxWidth: '100%',
maxHeight: '100%',
}}
/>
{/* Overlay : positionne exactement sur l'image via imageRect.

View File

@@ -1085,12 +1085,17 @@ body {
justify-content: center;
overflow: hidden;
position: relative;
/* min-height: 0 — indispensable pour que flex:1 fonctionne dans un
conteneur flex column. Sans ca, min-height:auto empeche le conteneur
de se dimensionner correctement et l'image reste minuscule. */
min-height: 0;
}
.fullscreen-content img {
max-width: 100%;
max-height: calc(100vh - 70px);
object-fit: contain;
/* Les dimensions width/height sont calculees en JS (contain manuel)
pour garantir que l'image remplit le conteneur quel que soit sa
taille naturelle (y compris thumbnails 320x240 de la bibliotheque). */
display: block;
cursor: crosshair;
}