Preview a sprite at the end of its inspector, placed or as an asset
A sprite's inspector listed its rows but never showed what they add up to. The picture, its frame, nine-slice, tint and shader could only be judged in the scene, often far from the object being edited. - SpritePreview draws the sprite through syncSpriteMesh, the function the scene draws it with. Slices, padding, tint and shader come out the same without a second path. syncSpriteMesh now takes only the three fields of a DrawItem it reads. - The subject is resolved by previewPicture from the Shader tab, so a placed sprite shows its own overrides. - previewFit is the rule for size and place: whole device pixels per unit from 1 on, at most 8, and the corner on a whole device pixel. Pixel art stays sharp. A sprite larger than the group shrinks freely. - A shader with a Time node keeps the preview redrawing once a frame while it is on screen. A folded group or a hidden panel stops it. - New test hook __gm.inspectorSpritePreview(). Finding: the preview redrew on a model change in a microtask at first. A drawn picture whose revision moved on is retried once, in a microtask queued by the scene's synchronous redraw. That retry ran before the preview had let go, and the old pixel art sheet stayed waiting (e2e 48l-iii read waiting [1,1,1]). The preview now redraws at once on a model change, as the scene does. Tests: - unit: 238 files, 3592 tests (+5 in preview-fit.test.ts), and the group list of a placed sprite in sections.test.ts ends in PREVIEW - e2e 48: ALL PASSED, 47 checks (+2: 48l-i asset preview with the frame, 48l-iii placed preview with its shader values) - counter-checks: without whole-pixel zoom 2 unit tests fail; with the microtask redraw 48l-iii fails with waiting [1,1,1] Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1665576fb9
commit
3f12a77aea
10 files changed
+239
-4
No files matched your search
@@ -18,6 +18,7 @@ import { generalSettings, keepGeneralSettings } from '../generalSettings';
|
||||
import { currentGroupDialog } from '../panels/GroupNameDialog';
|
||||
import { currentSoundPicker } from '../sound/SoundPicker';
|
||||
import { rectOf, textProbe } from '../textProbe';
|
||||
import { SpritePreview } from '../inspector/SpritePreview';
|
||||
import { currentImagePicker } from '../texture/ImagePicker';
|
||||
import type { UsersPane } from '../users/UsersPane';
|
||||
import { Color, type ColorSource, type Container, Text } from 'pixi.js';
|
||||
@@ -167,6 +168,21 @@ export function uiHooks({ app, state, editor }: HookContext) {
|
||||
return (last ? hits.at(-1) : hits[0]) ?? null;
|
||||
},
|
||||
inspectorField: fieldOf,
|
||||
/** A sprite's preview in the inspector, scrolled into view: where its picture is drawn, on screen. */
|
||||
inspectorSpritePreview: () => {
|
||||
let preview: SpritePreview | null = null;
|
||||
const walk = (node: Container): void => {
|
||||
if (node instanceof SpritePreview) preview = node;
|
||||
else for (const child of node.children) walk(child);
|
||||
};
|
||||
walk(inspector);
|
||||
const found = preview as SpritePreview | null;
|
||||
if (!found) return null;
|
||||
inspector.reveal(found);
|
||||
const at = found.getGlobalPosition();
|
||||
const { x, y, w, h } = found.drawn;
|
||||
return { x: at.x + x, y: at.y + y, w, h, animates: found.animates };
|
||||
},
|
||||
/** The mark in front of the row named `label` – what a variable, a field or a port is dragged by (#310). */
|
||||
inspectorMark: (label: string, last = false) => {
|
||||
const mark = besideOf(label, last, -1);
|
||||
|
||||
Reference in new issue
Block a user