The scene view and the animation preview share one camera, the three form dialogs one base, and keys are found through one set of helpers (#85)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
bf02c9e8b3
commit
2a390e52ff
22 files changed
+418
-452
No files matched your search
+11
-8
@@ -1,4 +1,5 @@
|
||||
import type { KeyClipboard, KeyRef } from '../core/commands/animationCommands';
|
||||
import type { KeyClipboard } from '../core/commands/animationCommands';
|
||||
import { findKey, findTrack, hasKey, type KeyRef, sameKey } from '../core/model/animation';
|
||||
import { type Command, CommandError } from '../core/commands/Command';
|
||||
import { CommandStack } from '../core/commands/CommandStack';
|
||||
import type { Asset, SceneAsset } from '../core/model/Asset';
|
||||
@@ -126,8 +127,7 @@ export function graphSelection(
|
||||
*/
|
||||
export function trackSelection(assetId: string, keys: readonly KeyRef[], trackId?: string): Selection {
|
||||
const unique: KeyRef[] = [];
|
||||
for (const key of keys)
|
||||
if (!unique.some((k) => k.trackId === key.trackId && k.frame === key.frame)) unique.push(key);
|
||||
for (const key of keys) if (!hasKey(unique, key)) unique.push(key);
|
||||
const last = unique[unique.length - 1];
|
||||
const row = trackId ?? last?.trackId;
|
||||
return row ? { kind: 'track', assetId, trackId: row, keys: unique } : null;
|
||||
@@ -495,10 +495,8 @@ export class EditorState {
|
||||
if (!asset) this.select(null);
|
||||
else {
|
||||
// A key that moved or died leaves the selection; a row that died takes its keys with it.
|
||||
const alive = s.keys.filter((key) =>
|
||||
asset.tracks.some((t) => t.id === key.trackId && t.keys.some((k) => k.frame === key.frame)),
|
||||
);
|
||||
const rowAlive = asset.tracks.some((t) => t.id === s.trackId);
|
||||
const alive = s.keys.filter((key) => findKey(asset, key));
|
||||
const rowAlive = findTrack(asset, s.trackId) !== undefined;
|
||||
if (alive.length !== s.keys.length || !rowAlive)
|
||||
this.select(
|
||||
trackSelection(s.assetId, alive, rowAlive ? s.trackId : undefined) ?? {
|
||||
@@ -525,6 +523,11 @@ export class EditorState {
|
||||
return findAssetOf(this.project, s.assetId, 'animation')?.id ?? null;
|
||||
}
|
||||
|
||||
/** The timeline row the selection is about; undefined when it is about something else. */
|
||||
get selectedTrackId(): string | undefined {
|
||||
return this.selection?.kind === 'track' ? this.selection.trackId : undefined;
|
||||
}
|
||||
|
||||
/** The keys picked in the Animation tab, none when the selection is about something else. */
|
||||
get selectedKeys(): KeyRef[] {
|
||||
return this.selection?.kind === 'track' ? this.selection.keys : [];
|
||||
@@ -627,7 +630,7 @@ export function sameSelection(a: Selection, b: Selection): boolean {
|
||||
a.assetId === b.assetId &&
|
||||
a.trackId === b.trackId &&
|
||||
a.keys.length === b.keys.length &&
|
||||
a.keys.every((key, i) => key.trackId === b.keys[i]!.trackId && key.frame === b.keys[i]!.frame)
|
||||
a.keys.every((key, i) => sameKey(key, b.keys[i]!))
|
||||
);
|
||||
if (a.kind === 'annotation' && b.kind === 'annotation')
|
||||
return (
|
||||
|
||||
Reference in new issue
Block a user