diff --git a/screens/scenes/ensure_scene_schema.py b/screens/scenes/ensure_scene_schema.py index 17616e7b..d812639c 100644 --- a/screens/scenes/ensure_scene_schema.py +++ b/screens/scenes/ensure_scene_schema.py @@ -18,8 +18,8 @@ def ensure_scene_schema(slug): name TEXT, x REAL NOT NULL DEFAULT 100, y REAL NOT NULL DEFAULT 100, - width REAL NOT NULL DEFAULT 64, - height REAL NOT NULL DEFAULT 64, + width REAL NOT NULL DEFAULT 128, + height REAL NOT NULL DEFAULT 128, z_index INTEGER NOT NULL DEFAULT 1, attributes TEXT NOT NULL DEFAULT '{}', created_at TEXT DEFAULT CURRENT_TIMESTAMP diff --git a/screens/scenes/render_scene_object.py b/screens/scenes/render_scene_object.py index b5418a4b..5fa13253 100644 --- a/screens/scenes/render_scene_object.py +++ b/screens/scenes/render_scene_object.py @@ -23,10 +23,28 @@ def render_scene_object(obj): # voir static/js/play/actions.js/conditions.js. Sans risque de # collision d'id : un jeu est ENTIÈREMENT "document" (_screen_elements) # OU "jeu_2d" (_scene_objects), jamais les deux à la fois. + # data-anim-target (Timeline d'animation, Bug corrigé) : applyAnimationClip() + # (static/js/play/screens.js) et son équivalent d'aperçu éditeur + # (animation-timeline.js) sélectionnent TOUJOURS leur cible via + # [data-anim-target=...] (jamais data-element-id/data-object-id, posé + # sur .canvasElement/.playElement pour le DOM, voir visible_attrs.py) — + # un objet de scène n'ayant pas de wrapper équivalent, cet attribut est + # posé directement sur son : SANS lui, aucun clip de Timeline (ni + # même une action de flow "Jouer une animation") ne trouvait jamais sa + # cible pour un objet de scène, quel que soit son type d'animation. + # class="sceneObjectSprite" (object-fit:contain, voir static/style.css) : + # les frames CraftPix (screens/labels/animal_sprite_library.py) sont de + # GRANDS canevas très paddés (~788×504 px, très différent des sprites + # Kenney déjà bien recadrés, ~96×128 px) — sans object-fit, l'image + # remplirait quand même son cadre (width/height:100%, voir la règle + # `.canvasElementInner > img` dans scene_edit.html) mais DÉFORMÉE, + # rendant le personnage minuscule/écrasé dans sa boîte de sélection. if obj["kind"] == "personnage": src = resolve_personnage_idle_frame(obj) src_attr = f' src="{html_lib.escape(src)}"' if src else "" - return f'' + return (f'') src = (obj.get("attributes") or {}).get("src", "") src_attr = f' src="{html_lib.escape(src)}"' if src else "" - return f'' + return (f'') diff --git a/static/style.css b/static/style.css index 4392469c..193112b1 100644 --- a/static/style.css +++ b/static/style.css @@ -473,7 +473,11 @@ body.builderBody > main.content{ flex:1 1 auto; min-height:0; overflow:hidden; d .iconGalleryTile.selected{ border-color:var(--accent); box-shadow:0 0 0 2px var(--accent) inset; } /* Phase 8 — galerie de personnages : réutilise .iconGallery/.iconGalleryTile (grille + tuile), mais avec de VRAIES miniatures (, pas un masque - SVG monochrome) — voir screen_edit.html et personnage-panel.js. */ + SVG monochrome) — voir screen_edit.html et personnage-panel.js. + .personnageGallery : tuiles ~3x plus grandes que la grille d'icônes + générique (2 colonnes au lieu de 6) — un personnage doit rester + reconnaissable, contrairement à une icône. */ +.iconGallery.personnageGallery{ grid-template-columns:repeat(2, 1fr); gap:10px; max-height:420px; } .personnageThumb{ width:100%; height:100%; object-fit:contain; image-rendering:pixelated; } .widgetBtnForm{ margin:0; } .widgetBtn{ @@ -520,6 +524,12 @@ body.builderBody > main.content{ flex:1 1 auto; min-height:0; overflow:hidden; d .canvasElement:hover{ border-color:rgba(91,140,255,.5); } .canvasElement.selected{ border:2px solid var(--accent); } .canvasElementInner{ width:100%; height:100%; pointer-events:none; } +/* Objet de scène (screens/scenes/render_scene_object.py, éditeur ET jeu + jouable) : object-fit:contain — les frames CraftPix (screens/labels/ + animal_sprite_library.py) sont de grands canevas très paddés, très + différents des sprites Kenney déjà recadrés serré ; sans ça l'image + remplirait quand même sa boîte (width/height:100%) mais DÉFORMÉE. */ +.sceneObjectSprite{ object-fit:contain; } /* Surbrillance de l'élément sélectionné dans l'arborescence, posée en JS sur sa propre balise (voir applySelectionHighlight) — seul moyen de la voir