feat(web): close remaining editor, layout and persistence gaps
- Area headers get a per-area editor switcher backed by a shared AreaEditorContext; Preferences can hide it. - Animation camera area is a real navigable viewport aligned to the scene camera; Graph Editor adds channel selection, keyframe drag/ insert/delete and interpolation. - Geometry Nodes node locations round-trip through the native writer and reader, so saved graphs keep their layout. - Texture Paint can make linked library images local via a new native makeImageLocal command before packing strokes. - Compositor IMAGE and Render Layers nodes now persist to Main and execute against packed images / the last PBR render. - Spreadsheet row cap raised to 250k; Outliner gains Ctrl+A and arrow/ Home/End navigation. Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { CompositorGraphIR, CompositorLinkIR, CompositorNodeIR, CompositorNodeType } from "./compositor";
|
||||
import type { CompositorGraphIR, CompositorLinkIR, CompositorNodeIR, CompositorNodeType, CompositorResourceIR } from "./compositor";
|
||||
|
||||
function clone(graph: CompositorGraphIR): CompositorGraphIR {
|
||||
return structuredClone(graph);
|
||||
@@ -62,6 +62,18 @@ export const compositorCommands = Object.freeze({
|
||||
if (node) node.properties = { ...node.properties, [key]: value };
|
||||
return next;
|
||||
},
|
||||
upsertResource(graph: CompositorGraphIR, resource: CompositorResourceIR): CompositorGraphIR {
|
||||
const next = clone(graph);
|
||||
const index = next.resources.findIndex((candidate) => candidate.id === resource.id);
|
||||
if (index >= 0) next.resources[index] = { ...resource };
|
||||
else next.resources.push({ ...resource });
|
||||
return next;
|
||||
},
|
||||
removeResource(graph: CompositorGraphIR, resourceId: string): CompositorGraphIR {
|
||||
const next = clone(graph);
|
||||
next.resources = next.resources.filter((resource) => resource.id !== resourceId);
|
||||
return next;
|
||||
},
|
||||
setOutput(graph: CompositorGraphIR, nodeId: string): CompositorGraphIR {
|
||||
const next = clone(graph);
|
||||
if (next.nodes.find((node) => node.id === nodeId)?.type !== "COMPOSITE") return graph;
|
||||
|
||||
Reference in New Issue
Block a user