Éditeur de scène : le canevas remplit exactement l'espace disponible, plus de marges
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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
14deba943a
commit
11b08c8503
+14
-18
@@ -244,26 +244,22 @@ body.builderBody > main.content{ flex:1 1 auto; min-height:0; overflow:hidden; d
|
|||||||
|
|
||||||
.canvasFrame{
|
.canvasFrame{
|
||||||
/* flex:1 1 auto + min-height:0 : occupe tout l'espace restant sous la
|
/* 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
|
barre d'outils dans .builderTabPanel (voir screen_edit.html). Le
|
||||||
LUI qui défile (overflow:auto) si le canevas ne peut pas être réduit
|
canevas (voir .canvas ci-dessous) est réglé pour remplir EXACTEMENT
|
||||||
davantage (ex. fenêtre très basse) — jamais .builderCanvasArea (voir
|
ce cadre (100% x 100%, sans respecter l'aspect-ratio Portrait/Paysage/
|
||||||
plus haut), pour garder la barre d'onglets/d'outils toujours visible. */
|
Carré dans l'éditeur — ce réglage ne sert qu'à l'aperçu jouable/"Jouer",
|
||||||
flex:1 1 auto; min-height:0; width:100%; padding:10px; border:1px solid var(--border); border-radius:16px; background:var(--panel);
|
voir screen_set_aspect.py) : "prendre toute la place disponible" et
|
||||||
display:flex; align-items:center; justify-content:center; overflow:auto;
|
"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{
|
.canvas{
|
||||||
/* "Doit prendre toute la place disponible" ET garder son aspect-ratio :
|
position:relative; width:100%; height:100%; flex:1 1 auto; margin:0; background:#0b0d12; border-radius:8px;
|
||||||
un pur CSS (aspect-ratio + height:100%/max-width:100%) laissait trop
|
overflow:hidden; border:1px solid var(--border);
|
||||||
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{
|
.canvasElement{
|
||||||
/* Pas d'overflow:hidden ici : une échelle (transform:scale) ou une
|
/* Pas d'overflow:hidden ici : une échelle (transform:scale) ou une
|
||||||
|
|||||||
@@ -1432,11 +1432,6 @@ function initBuilderPanel() {
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
bindAspectButtons();
|
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) {
|
document.querySelectorAll('.uploadInput').forEach(function (input) {
|
||||||
input.addEventListener('change', function () {
|
input.addEventListener('change', function () {
|
||||||
@@ -1700,8 +1695,11 @@ function bindAspectButtons() {
|
|||||||
btn.addEventListener('click', function () {
|
btn.addEventListener('click', function () {
|
||||||
document.querySelectorAll('.aspectBtn').forEach(function (b) { b.classList.remove('active'); });
|
document.querySelectorAll('.aspectBtn').forEach(function (b) { b.classList.remove('active'); });
|
||||||
btn.classList.add('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;
|
document.getElementById('canvas').style.aspectRatio = btn.dataset.aspect;
|
||||||
fitCanvasToFrame();
|
|
||||||
fetch("/game/{{ game.slug }}/screens/{{ screen.id }}/aspect", {
|
fetch("/game/{{ game.slug }}/screens/{{ screen.id }}/aspect", {
|
||||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ aspect: btn.dataset.aspect }),
|
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){
|
document.querySelectorAll('.uploadInput').forEach(function(input){
|
||||||
input.addEventListener('change', function(){
|
input.addEventListener('change', function(){
|
||||||
if (!input.files.length) return;
|
if (!input.files.length) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user