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
@@ -1,5 +1,4 @@
|
||||
import {
|
||||
type KeyRef,
|
||||
RemoveAnimationKeysCommand,
|
||||
RemoveAnimationTracksCommand,
|
||||
SetAnimationKeyCommand,
|
||||
@@ -8,8 +7,11 @@ import {
|
||||
} from '../../core/commands/animationCommands';
|
||||
import {
|
||||
blends,
|
||||
findKey,
|
||||
findTrack,
|
||||
interpolationOf,
|
||||
KEY_INTERPOLATIONS,
|
||||
type KeyRef,
|
||||
trackDef,
|
||||
trackLabel,
|
||||
} from '../../core/model/animation';
|
||||
@@ -28,10 +30,9 @@ export function trackSignature(
|
||||
project: Project,
|
||||
assetId: string,
|
||||
trackId: string,
|
||||
keys: readonly { trackId: string; frame: number }[],
|
||||
keys: readonly KeyRef[],
|
||||
): string {
|
||||
const asset = findAssetOf(project, assetId, 'animation');
|
||||
const track = asset?.tracks.find((t) => t.id === trackId);
|
||||
const { asset, track } = rowOf(project, assetId, trackId);
|
||||
if (!asset || !track) return 'missing';
|
||||
const kind = kindOf(project, asset, track) ?? 'missing';
|
||||
const key = keys.length === 1 ? `${keys[0]!.trackId}@${keys[0]!.frame}` : String(keys.length);
|
||||
@@ -46,10 +47,9 @@ export function buildTrackSection(
|
||||
host: InspectorHost,
|
||||
assetId: string,
|
||||
trackId: string,
|
||||
keys: readonly { trackId: string; frame: number }[],
|
||||
keys: readonly KeyRef[],
|
||||
): void {
|
||||
const asset = findAssetOf(host.state.project, assetId, 'animation');
|
||||
const track = asset?.tracks.find((t) => t.id === trackId);
|
||||
const { asset, track } = rowOf(host.state.project, assetId, trackId);
|
||||
if (!asset || !track) return;
|
||||
const kind = kindOf(host.state.project, asset, track);
|
||||
|
||||
@@ -68,9 +68,8 @@ export function buildTrackSection(
|
||||
host.body.add(
|
||||
new Button('Change target…', {
|
||||
onClick: () => {
|
||||
const current = findAssetOf(host.state.project, assetId, 'animation');
|
||||
const row = current?.tracks.find((t) => t.id === trackId);
|
||||
if (current && row) openRowDialog(new RowDialog(host.state, current, row));
|
||||
const now = rowOf(host.state.project, assetId, trackId);
|
||||
if (now.asset && now.track) openRowDialog(new RowDialog(host.state, now.asset, now.track));
|
||||
},
|
||||
}),
|
||||
);
|
||||
@@ -114,10 +113,10 @@ export function buildTrackSection(
|
||||
}
|
||||
|
||||
/** The value of the one picked key, editable in the widget its kind calls for. */
|
||||
function buildKey(host: InspectorHost, asset: AnimationAsset, ref: { trackId: string; frame: number }): void {
|
||||
const track = asset.tracks.find((t) => t.id === ref.trackId);
|
||||
const key = track?.keys.find((k) => k.frame === ref.frame);
|
||||
const def = track && defOf(host.state.project, asset, track);
|
||||
function buildKey(host: InspectorHost, asset: AnimationAsset, ref: KeyRef): void {
|
||||
const track = findTrack(asset, ref.trackId);
|
||||
const key = findKey(asset, ref);
|
||||
const def = track && trackDef(host.state.project, asset, track);
|
||||
if (!track || !key || !def) return;
|
||||
addGap(host);
|
||||
addTitle(host, `KEY AT FRAME ${ref.frame}`);
|
||||
@@ -167,10 +166,10 @@ function easingKey(
|
||||
keys: readonly KeyRef[],
|
||||
): AnimationKey | undefined {
|
||||
for (const ref of [...keys].reverse()) {
|
||||
const track = asset.tracks.find((t) => t.id === ref.trackId);
|
||||
const track = findTrack(asset, ref.trackId);
|
||||
const kind = track && kindOf(project, asset, track);
|
||||
if (!kind || !blends(kind)) continue;
|
||||
const key = track.keys.find((k) => k.frame === ref.frame);
|
||||
const key = findKey(asset, ref);
|
||||
if (key) return key;
|
||||
}
|
||||
return undefined;
|
||||
@@ -181,15 +180,14 @@ export function refreshTrackSection(
|
||||
host: InspectorHost,
|
||||
assetId: string,
|
||||
trackId: string,
|
||||
keys: readonly { trackId: string; frame: number }[],
|
||||
keys: readonly KeyRef[],
|
||||
): boolean {
|
||||
const asset = findAssetOf(host.state.project, assetId, 'animation');
|
||||
const track = asset?.tracks.find((t) => t.id === trackId);
|
||||
const { asset, track } = rowOf(host.state.project, assetId, trackId);
|
||||
if (!asset || !track) return false;
|
||||
host.fields.get('relative')?.setValue(Boolean(track.relative));
|
||||
const ref = keys.length === 1 ? keys[0] : undefined;
|
||||
if (ref) {
|
||||
const key = asset.tracks.find((t) => t.id === ref.trackId)?.keys.find((k) => k.frame === ref.frame);
|
||||
const key = findKey(asset, ref);
|
||||
if (!key) return false;
|
||||
host.fields.get('value')?.setValue(key.value);
|
||||
}
|
||||
@@ -199,10 +197,15 @@ export function refreshTrackSection(
|
||||
return true;
|
||||
}
|
||||
|
||||
function defOf(project: Project, asset: AnimationAsset, track: AnimationTrack) {
|
||||
return trackDef(project, asset, track);
|
||||
function rowOf(
|
||||
project: Project,
|
||||
assetId: string,
|
||||
trackId: string,
|
||||
): { asset?: AnimationAsset; track?: AnimationTrack } {
|
||||
const asset = findAssetOf(project, assetId, 'animation');
|
||||
return { asset, track: asset && findTrack(asset, trackId) };
|
||||
}
|
||||
|
||||
function kindOf(project: Project, asset: AnimationAsset, track: AnimationTrack): string | undefined {
|
||||
return defOf(project, asset, track)?.kind;
|
||||
return trackDef(project, asset, track)?.kind;
|
||||
}
|
||||
Reference in new issue
Block a user