Éditeur de scène : le canevas remplit vraiment tout l'espace disponible
Le calcul purement CSS du tour précédent (aspect-ratio + height:100% + max-width:100%, pour que le canevas garde ses proportions tout en tenant dans la zone visible) laissait en pratique le canevas bien plus petit que l'espace réellement disponible - le calcul de taille "auto" d'un élément non remplacé dans ce contexte flex n'est pas fiable. Remplacé par un calcul en JavaScript (fitCanvasToFrame()) : mesure la taille réelle de .canvasFrame et calcule la plus grande taille en pixels qui tient à la fois en largeur ET en hauteur pour l'aspect-ratio courant (l'équivalent d'un "object-fit:contain"), posée directement en style inline sur #canvas. Recalculé à l'ouverture de l'écran, au changement de format (Portrait/Paysage/Carré), au redimensionnement de la fenêtre, et à chaque rafraîchissement du panneau (#canvas étant recréé à chaque sélection d'élément, sa taille calculée était perdue à chaque fois). Sous 1300px (mise en page empilée), le style inline est explicitement effacé pour laisser la règle CSS de repli (pleine largeur, page qui défile normalement) reprendre la main. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
dae6da166e
commit
14deba943a
+13
-12
@@ -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
|
davantage (ex. fenêtre très basse) — jamais .builderCanvasArea (voir
|
||||||
plus haut), pour garder la barre d'onglets/d'outils toujours visible. */
|
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);
|
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{
|
.canvas{
|
||||||
/* "Monté le plus haut possible" et "je dois voir tout l'écran" : plutôt
|
/* "Doit prendre toute la place disponible" ET garder son aspect-ratio :
|
||||||
qu'une largeur pleine (l'ancien width:100%, qui pouvait rendre un
|
un pur CSS (aspect-ratio + height:100%/max-width:100%) laissait trop
|
||||||
format Portrait bien plus haut que la fenêtre), la hauteur DISPONIBLE
|
souvent le canevas bien plus petit que l'espace réellement disponible
|
||||||
devient la contrainte principale (height:100%) et la largeur se déduit
|
(le calcul "auto" d'un élément non remplacé dans ce contexte flex
|
||||||
de l'aspect-ratio (posé en style inline, voir screen_edit.html) —
|
n'est pas fiable) — fitCanvasToFrame() (screen_edit.html) calcule donc
|
||||||
max-width:100% prend le relais si jamais c'est la largeur qui manque
|
lui-même, en JS, la plus grande taille en pixels qui tient à la fois en
|
||||||
en premier (fenêtre étroite/écran Paysage). Résultat : le canevas
|
largeur ET en hauteur dans .canvasFrame (comme un "object-fit:contain"),
|
||||||
entier tient toujours dans la zone visible, sans avoir à défiler pour
|
posée directement en style inline. Cette règle ne sert donc que de
|
||||||
voir le bas de l'écran. */
|
valeur de secours avant le premier calcul JS (et en repli < 1300px,
|
||||||
position:relative; height:100%; width:auto; max-width:100%; flex:0 0 auto; margin:0 auto; background:#0b0d12; border-radius:8px;
|
voir le media query plus bas qui la réactive). */
|
||||||
overflow:hidden; border:1px solid var(--border);
|
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,6 +1432,11 @@ 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 () {
|
||||||
@@ -1696,6 +1701,7 @@ function bindAspectButtons() {
|
|||||||
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');
|
||||||
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 }),
|
||||||
@@ -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){
|
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