Fix éditeur de scène 2D : personnage déformé, animations muettes, galerie petite
Trois correctifs remontés en test manuel sur l'éditeur de scène : 1. Personnage écrasé/déformé dans sa boîte de sélection : les frames CraftPix (screens/labels/animal_sprite_library.py) sont de grands canevas très paddés (~788×504 px), très différents des sprites Kenney déjà recadrés serré (~96×128 px) — sans object-fit, l'image remplissait quand même sa boîte (width/height:100%, voir la règle .canvasElementInner > img de scene_edit.html) mais DÉFORMÉE. Nouvelle classe .sceneObjectSprite (object-fit:contain) posée sur le <img> rendu par render_scene_object.py, éditeur ET jeu jouable. 2. Aucun clip de Timeline (sprite, Animate.css ou personnalisé) ne se jouait jamais sur un objet de scène : applyAnimationClip() (static/js/play/screens.js) et animation-timeline.js sélectionnent TOUJOURS leur cible via l'attribut data-anim-target (posé sur .canvasElement/.playElement pour le DOM), jamais data-element-id/ data-object-id — cet attribut n'était simplement jamais posé sur les objets de scène. Ajouté sur le <img> rendu (render_scene_object.py). 3. Boîte par défaut d'un nouvel objet de scène trop petite (64×64 px sur une scène de 960×540) pour bien voir le personnage ou saisir la poignée de redimensionnement confortablement — portée à 128×128 (ensure_scene_schema.py ; n'affecte que les NOUVEAUX objets, les objets déjà posés gardent leur taille actuelle). Au passage : galerie de personnages ~3x plus grande (2 colonnes au lieu de 6 dans .iconGallery.personnageGallery) — les tuiles étaient trop petites pour bien distinguer les personnages. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
a27d08c6b0
commit
c240181518
@@ -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
|
||||
|
||||
@@ -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 <img> : 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'<img data-object-id="{obj["id"]}" data-element-id="{obj["id"]}" data-personnage="1" style="{style}"{src_attr}>'
|
||||
return (f'<img class="sceneObjectSprite" data-object-id="{obj["id"]}" data-element-id="{obj["id"]}" '
|
||||
f'data-anim-target="{obj["id"]}" data-personnage="1" style="{style}"{src_attr}>')
|
||||
src = (obj.get("attributes") or {}).get("src", "")
|
||||
src_attr = f' src="{html_lib.escape(src)}"' if src else ""
|
||||
return f'<img data-object-id="{obj["id"]}" data-element-id="{obj["id"]}" style="{style}"{src_attr}>'
|
||||
return (f'<img class="sceneObjectSprite" data-object-id="{obj["id"]}" data-element-id="{obj["id"]}" '
|
||||
f'data-anim-target="{obj["id"]}" style="{style}"{src_attr}>')
|
||||
|
||||
+11
-1
@@ -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 (<img>, 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
|
||||
|
||||
Reference in New Issue
Block a user