Show a wheel step or Fit as a short zoom transition (#309)
The wheel and the Fit button used to jump to the new view. Now the view takes a short way there, 200 ms by default, everywhere the editor zooms. The zoom steps stay the same, only the change is shown. - viewTween: tweenView is the way between two views as a pure function. The scale moves by equal ratios, and the world point that sits at the same place on screen in both views stays there. After a wheel step that is the point under the pointer. - ViewTween drives it on the ticker. A surface hands it reading, writing and drawing its own view and wraps its wheel and Fit code in change(). A step during a transition starts from where that one was heading, so quick steps add up to exactly as many steps. - Anything else that moves the view ends the transition. A pan jumps to the target first, and saving a view saves the target. - Wired into FreeViewport (Scene, Container, animation preview), SheetCanvas (Texture, Curve, Pixel art, Vector art), GraphCanvas, panAndZoom (Tile board, plugin node board) and the timeline. - Menu > General settings... sets the time in ms, 0 jumps at once. It is kept in this browser like the panel sizes, not in the project, and it is not an undo step. - A document that opens still comes up framed at once. The animation preview frames a new subject itself instead of calling fit(). - The pixel art readout names the step the view is heading for. Measured in the scene view at 200 ms on melektaus-atx, where every frame of the transition is a full redraw: - 500 sprites: redraw 6.7 ms, 16 frames, mean 18 ms - 1000 sprites: redraw 13.0 ms, 9 frames, mean 27 ms - 2000 sprites: redraw 32.2 ms, 5 frames, mean 58 ms Tests: - The harness sets 0 ms on every load, so the existing modules read the step and not the way. - e2e 46i samples one wheel step at 1000 ms a frame later: zoom 1.033 between 1 and 2, the point under the pointer kept at (134, -40). It lands on the view a 0 ms jump reaches. - e2e 46 and 49 expect the new menu entry. - Gate (atx): 234 files, 3563 tests, CHECK EXIT 0 (+15) - e2e 46,49 (atx): ALL PASSED, 43 checks (+3, sum 1735) - Three counter-checks fail view-tween.test.ts as expected. e2e 46i fails when the scene view does not carry its centre along. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8452a99c64
commit
cf6043a066
21 files changed
+779
-49
No files matched your search
@@ -45,6 +45,8 @@ import type { ReleaseStore } from '../core/store/ReleaseStore';
|
||||
import type { ReleaseDialog } from './ReleaseDialog';
|
||||
import type { ProjectSettingsDialog } from './ProjectSettingsDialog';
|
||||
import { dialogSlot } from './FormDialog';
|
||||
import { generalSettings, keepGeneralSettings } from './generalSettings';
|
||||
import { GeneralSettingsDialog } from './GeneralSettingsDialog';
|
||||
import { ContainerEditor } from './container/ContainerEditor';
|
||||
import { EditorRun } from './EditorRun';
|
||||
import { GraphEditor } from './graph/GraphEditor';
|
||||
@@ -256,6 +258,7 @@ export class Editor implements PlayHost {
|
||||
plugins: PluginManager | null = null;
|
||||
private readonly toolbar: Toolbar;
|
||||
private readonly passwordDialog = dialogSlot<PasswordDialog>();
|
||||
private readonly generalDialog = dialogSlot<GeneralSettingsDialog>();
|
||||
/** Drawn-frame count at the last measurement, not a counter of its own. */
|
||||
private fpsFrames = 0;
|
||||
private fpsElapsed = 0;
|
||||
@@ -601,11 +604,22 @@ export class Editor implements PlayHost {
|
||||
const open = () => this.openDocument('management');
|
||||
return [
|
||||
{ separator: true },
|
||||
{ label: 'General settings…', onSelect: () => this.openGeneralSettings() },
|
||||
...(this.usersPane ? [{ label: 'User management', onSelect: open }] : []),
|
||||
{ label: 'Plugins', onSelect: open },
|
||||
];
|
||||
}
|
||||
|
||||
/** What the editor does for whoever sits at it, kept in this browser (#309). */
|
||||
openGeneralSettings(): GeneralSettingsDialog {
|
||||
return this.generalDialog.open(new GeneralSettingsDialog(generalSettings(), keepGeneralSettings));
|
||||
}
|
||||
|
||||
/** The open "General settings" dialog, for the check scripts. */
|
||||
generalSettingsDialog(): GeneralSettingsDialog | null {
|
||||
return this.generalDialog.current();
|
||||
}
|
||||
|
||||
/**
|
||||
* The account menu under its button (#182). The name stands in it as an entry that cannot be
|
||||
* picked: it says who is signed in without costing the crowded toolbar another label.
|
||||
@@ -921,6 +935,7 @@ export class Editor implements PlayHost {
|
||||
for (const cleanup of this.cleanups.splice(0).reverse()) cleanup();
|
||||
// Closed rather than just thrown away with the overlay below, so the slot lets go of it too.
|
||||
this.passwordDialog.current()?.close();
|
||||
this.generalDialog.current()?.close();
|
||||
// The tooltip is not the editor's to destroy: it leaves the overlay before that is emptied.
|
||||
tooltips.dismiss();
|
||||
// A menu or a picker left open belongs to widgets that are about to be destroyed.
|
||||
|
||||
Reference in new issue
Block a user