Dragging previews once per frame instead of on every move (#213)
Scene view, texture tab and graph called state.preview() on every pointer move. Each call rebuilds panels, the editor run and generated images, so a drag in a busy project cost up to 34 ms per move. The model is still written on every move. Only the preview now waits for the next frame. - New FramePreview in src/editor/framePreview.ts. request() goes into the move handler, cancel() into the release. The rule lives in one place instead of six copies. - Scene view: object drag, polygon corners and tilemap strokes use it. - Texture tab: frames, slice edges and collision corners use it. - Graph: nodes, groups and comments use it through GraphDrags. That covers the state machine, shader and particle tabs as well. - Vector art is unchanged. Its frame already writes the model since #129. Findings: - The texture tab paid twice per move (232 project events for 120 moves). Pixi sends a second pointer event 4 to 8 ms after each real move as a hover update. It now lands in the same frame for free. - Inspector scrubbing and gradient stop dragging still preview on every input. Both lie outside the three canvases of the issue. Measured with a throwaway probe, 120 moves at 8 ms, 120 extra objects: scene 26.2 -> 18.5 ms/move, texture 34.2 -> 17.9, graph 28.8 -> 17.0. Project events dropped from 120/232/119 to 48/48/41. Tests: - ./check.sh: 147 files, 2204 tests, exit 0 (before 146 / 2199). - 5 new unit tests in tests/editor/frame-preview.test.ts, including the real GraphDrags. Counter-checks (direct preview in the graph, no cancel on release, one key per name) each fail the expected test. - e2e 1-16,29,31,36,37,39-43: 708 checks passed. - e2e 1-16,26,28: 634 checks passed. - No new e2e check, the check sum stays at 1314. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f9d5e8bca5
commit
30fb3a2316
7 files changed
+182
-10
No files matched your search
@@ -33,6 +33,7 @@ import {
|
||||
} from '../polygonEdit';
|
||||
import { dashedLine } from '../../viewport/symbols';
|
||||
import { textureLibrary } from '../../viewport/TextureLibrary';
|
||||
import { FramePreview } from '../framePreview';
|
||||
import type { EditorState } from '../state';
|
||||
import { drawChecker } from './checker';
|
||||
import { SheetCanvas } from './SheetCanvas';
|
||||
@@ -118,9 +119,11 @@ export class TextureCanvas extends SheetCanvas<TextureAsset> {
|
||||
/** The outline a click adds corners to; for another frame, or one gone, the frame's last one. */
|
||||
private active = { frameId: '', index: -1 };
|
||||
private readonly stopPictures: () => void;
|
||||
private readonly perFrame: FramePreview;
|
||||
|
||||
constructor(private readonly state: EditorState) {
|
||||
super();
|
||||
this.perFrame = new FramePreview(state, 'texture-drag');
|
||||
this.content.addChild(this.image, this.overlay, this.labelLayer);
|
||||
|
||||
state.on('project', () => this.redraw());
|
||||
@@ -344,7 +347,7 @@ export class TextureCanvas extends SheetCanvas<TextureAsset> {
|
||||
const frame = corner && this.frame(corner.frameId);
|
||||
if (!corner || !frame) return;
|
||||
setFrameCollision(frame, corner.outlines);
|
||||
this.state.preview();
|
||||
this.perFrame.request();
|
||||
}
|
||||
|
||||
private startDrag(
|
||||
@@ -424,10 +427,11 @@ export class TextureCanvas extends SheetCanvas<TextureAsset> {
|
||||
frame,
|
||||
normalizeFrameRect(dragFrame(drag.start, drag.handle, dx, dy), asset.width, asset.height),
|
||||
);
|
||||
this.state.preview();
|
||||
this.perFrame.request();
|
||||
}
|
||||
|
||||
protected release(): void {
|
||||
this.perFrame.cancel();
|
||||
const corner = this.corner;
|
||||
this.corner = null;
|
||||
const frame = corner && this.frame(corner.frameId);
|
||||
|
||||
Reference in new issue
Block a user