From 11b08c850377d5b90483a036d89f82fb16689ac4 Mon Sep 17 00:00:00 2001 From: william Date: Tue, 25 Aug 2026 11:50:50 +0200 Subject: [PATCH] =?UTF-8?q?=C3=89diteur=20de=20sc=C3=A8ne=20:=20le=20canev?= =?UTF-8?q?as=20remplit=20exactement=20l'espace=20disponible,=20plus=20de?= =?UTF-8?q?=20marges?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le calcul JS "object-fit:contain" du tour précédent gardait l'aspect-ratio (Portrait/Paysage/Carré) au prix de marges vides sur les côtés dès que la fenêtre n'avait pas exactement ce ratio - "prendre toute la place disponible" et "garder l'aspect-ratio" sont deux exigences contradictoires dans ce cas, et c'est la première qui doit l'emporter dans l'éditeur. Le canevas (#canvas) remplit donc maintenant .canvasFrame à 100% x 100%, sans plus tenir compte de l'aspect-ratio choisi dans l'éditeur - ce réglage continue de s'appliquer normalement à l'aperçu jouable ("Jouer", voir screen_set_aspect.py/play.html), qui reste la référence pour le rendu final. Padding de .canvasFrame réduit au minimum. fitCanvasToFrame() et son calcul en pixels n'ont plus lieu d'être - retirés entièrement. Co-Authored-By: Claude Sonnet 5 --- static/style.css | 32 +++++++++++++---------------- templates/screen_edit.html | 42 ++++---------------------------------- 2 files changed, 18 insertions(+), 56 deletions(-) diff --git a/static/style.css b/static/style.css index 849f1b5e..9f5dad8b 100644 --- a/static/style.css +++ b/static/style.css @@ -244,26 +244,22 @@ body.builderBody > main.content{ flex:1 1 auto; min-height:0; overflow:hidden; d .canvasFrame{ /* flex:1 1 auto + min-height:0 : occupe tout l'espace restant sous la - barre d'outils dans .builderTabPanel (voir screen_edit.html), et c'est - LUI qui défile (overflow:auto) si le canevas ne peut pas être réduit - 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:center; justify-content:center; overflow:auto; + barre d'outils dans .builderTabPanel (voir screen_edit.html). Le + canevas (voir .canvas ci-dessous) est réglé pour remplir EXACTEMENT + ce cadre (100% x 100%, sans respecter l'aspect-ratio Portrait/Paysage/ + Carré dans l'éditeur — ce réglage ne sert qu'à l'aperçu jouable/"Jouer", + voir screen_set_aspect.py) : "prendre toute la place disponible" et + "garder l'aspect-ratio" sont deux exigences contradictoires dès que la + fenêtre n'a pas exactement ce ratio, la première l'emporte ici. C'est + LUI qui défile (overflow:auto) si jamais le contenu déborde malgré + tout — 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:4px; border:1px solid var(--border); border-radius:16px; background:var(--panel); + display:flex; overflow:auto; } .canvas{ - /* "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; + position:relative; width:100%; height:100%; flex:1 1 auto; margin:0; background:#0b0d12; border-radius:8px; + overflow:hidden; border:1px solid var(--border); } .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 15735505..10e110a0 100644 --- a/templates/screen_edit.html +++ b/templates/screen_edit.html @@ -1432,11 +1432,6 @@ 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 () { @@ -1700,8 +1695,11 @@ function bindAspectButtons() { btn.addEventListener('click', function () { document.querySelectorAll('.aspectBtn').forEach(function (b) { b.classList.remove('active'); }); btn.classList.add('active'); + // Dans l'éditeur (≥1300px), le canevas remplit tout .canvasFrame + // (voir .canvas dans style.css) — cet aspect-ratio ne sert donc plus + // qu'au repli en page empilée (<1300px, voir le media query) et à + // l'aperçu jouable ("Jouer"), pas à la mise en page ici. 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 }), @@ -1710,38 +1708,6 @@ 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;