diff --git a/static/style.css b/static/style.css index f282a292..849f1b5e 100644 --- a/static/style.css +++ b/static/style.css @@ -249,20 +249,21 @@ body.builderBody > main.content{ flex:1 1 auto; min-height:0; overflow:hidden; d davantage (ex. fenêtre très basse) — jamais .builderCanvasArea (voir plus haut), pour garder la barre d'onglets/d'outils toujours visible. */ flex:1 1 auto; min-height:0; width:100%; padding:10px; border:1px solid var(--border); border-radius:16px; background:var(--panel); - display:flex; align-items:flex-start; justify-content:center; overflow:auto; + display:flex; align-items:center; justify-content:center; overflow:auto; } .canvas{ - /* "Monté le plus haut possible" et "je dois voir tout l'écran" : plutôt - qu'une largeur pleine (l'ancien width:100%, qui pouvait rendre un - format Portrait bien plus haut que la fenêtre), la hauteur DISPONIBLE - devient la contrainte principale (height:100%) et la largeur se déduit - de l'aspect-ratio (posé en style inline, voir screen_edit.html) — - max-width:100% prend le relais si jamais c'est la largeur qui manque - en premier (fenêtre étroite/écran Paysage). Résultat : le canevas - entier tient toujours dans la zone visible, sans avoir à défiler pour - voir le bas de l'écran. */ - position:relative; height:100%; width:auto; max-width:100%; flex:0 0 auto; margin:0 auto; background:#0b0d12; border-radius:8px; - overflow:hidden; border:1px solid var(--border); + /* "Doit prendre toute la place disponible" ET garder son aspect-ratio : + un pur CSS (aspect-ratio + height:100%/max-width:100%) laissait trop + souvent le canevas bien plus petit que l'espace réellement disponible + (le calcul "auto" d'un élément non remplacé dans ce contexte flex + n'est pas fiable) — fitCanvasToFrame() (screen_edit.html) calcule donc + lui-même, en JS, la plus grande taille en pixels qui tient à la fois en + largeur ET en hauteur dans .canvasFrame (comme un "object-fit:contain"), + posée directement en style inline. Cette règle ne sert donc que de + valeur de secours avant le premier calcul JS (et en repli < 1300px, + voir le media query plus bas qui la réactive). */ + position:relative; width:100%; margin:0 auto; background:#0b0d12; border-radius:8px; + overflow:hidden; border:1px solid var(--border); flex:0 0 auto; } .canvasElement{ /* Pas d'overflow:hidden ici : une échelle (transform:scale) ou une diff --git a/templates/screen_edit.html b/templates/screen_edit.html index ac002e93..15735505 100644 --- a/templates/screen_edit.html +++ b/templates/screen_edit.html @@ -1432,6 +1432,11 @@ function initBuilderPanel() { })(); bindAspectButtons(); + // #canvas est recréé à chaque rafraîchissement du panneau (voir + // refreshBuilderPanel ci-dessus, qui remplace tout #builder3.innerHTML) + // — sa taille en pixels calculée par fitCanvasToFrame() est donc perdue + // à chaque fois et doit être reposée ici. + fitCanvasToFrame(); document.querySelectorAll('.uploadInput').forEach(function (input) { input.addEventListener('change', function () { @@ -1696,6 +1701,7 @@ function bindAspectButtons() { document.querySelectorAll('.aspectBtn').forEach(function (b) { b.classList.remove('active'); }); btn.classList.add('active'); document.getElementById('canvas').style.aspectRatio = btn.dataset.aspect; + fitCanvasToFrame(); fetch("/game/{{ game.slug }}/screens/{{ screen.id }}/aspect", { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ aspect: btn.dataset.aspect }), @@ -1704,6 +1710,38 @@ function bindAspectButtons() { }); } +// Le canevas doit "prendre toute la place disponible" dans .canvasFrame +// tout en gardant son aspect-ratio (Portrait/Paysage/Carré) : calcule la +// plus grande taille en pixels qui tient à la fois en largeur ET en +// hauteur (comme un "object-fit:contain"), posée en style inline — un pur +// CSS (aspect-ratio + height:100%) s'est révélé peu fiable ici (voir le +// commentaire sur .canvas dans style.css). Sous 1300px (mise en page +// empilée, une seule colonne, page qui défile normalement), la taille en +// pixels n'a plus lieu d'être : on efface le style inline pour laisser la +// règle CSS de repli (largeur pleine) reprendre la main. +function fitCanvasToFrame() { + var canvas = document.getElementById('canvas'); + var frame = document.querySelector('.canvasFrame'); + if (!canvas || !frame) return; + if (window.innerWidth <= 1300) { + canvas.style.width = ''; + canvas.style.height = ''; + return; + } + var cs = getComputedStyle(frame); + var availW = frame.clientWidth - parseFloat(cs.paddingLeft) - parseFloat(cs.paddingRight); + var availH = frame.clientHeight - parseFloat(cs.paddingTop) - parseFloat(cs.paddingBottom); + if (availW <= 0 || availH <= 0) return; + var parts = (canvas.style.aspectRatio || '9/16').split('/'); + var ratio = parseFloat(parts[0]) / parseFloat(parts[1]); + if (!ratio) return; + var w = availW, h = w / ratio; + if (h > availH) { h = availH; w = h * ratio; } + canvas.style.width = w + 'px'; + canvas.style.height = h + 'px'; +} +window.addEventListener('resize', fitCanvasToFrame); + document.querySelectorAll('.uploadInput').forEach(function(input){ input.addEventListener('change', function(){ if (!input.files.length) return;