feat(web): add an interactive Compositor node canvas
Author Compositor graphs in the web UI with React Flow and execute them locally. The native writer materializes RGB/Exposure/Invert/Blur/ Mix/Alpha Over/Transform/Viewer/Composite nodes into a real CompositorNodeTree, the reader returns node locations and more node types, and save/reopen keeps nodes, links, positions and properties. Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -67,6 +67,8 @@ export interface CompositorNodeIR {
|
||||
name: string;
|
||||
blenderType?: string;
|
||||
properties: Record<string, unknown>;
|
||||
/** Canvas position in Blender node-space units. */
|
||||
location?: { x: number; y: number };
|
||||
}
|
||||
|
||||
export interface CompositorLinkIR {
|
||||
@@ -279,7 +281,11 @@ export function parseCompositorGraph(value: unknown): CompositorGraphIR {
|
||||
const id = text(item.id, `nodes[${index}].id`);
|
||||
if (nodeIds.has(id)) throw new CompositorValidationError("COMPOSITOR_GRAPH_INVALID", `Duplicate node ${id}`);
|
||||
nodeIds.add(id);
|
||||
const node = { id, type: item.type as CompositorNodeType, name: text(item.name, `nodes[${index}].name`), properties: properties(item.properties ?? {}, index), blenderType: item.blenderType === undefined ? undefined : text(item.blenderType, `nodes[${index}].blenderType`) };
|
||||
const node: CompositorNodeIR = { id, type: item.type as CompositorNodeType, name: text(item.name, `nodes[${index}].name`), properties: properties(item.properties ?? {}, index), blenderType: item.blenderType === undefined ? undefined : text(item.blenderType, `nodes[${index}].blenderType`) };
|
||||
if (item.location !== undefined) {
|
||||
if (!record(item.location)) throw new CompositorValidationError("COMPOSITOR_GRAPH_INVALID", `nodes[${index}].location is invalid`);
|
||||
node.location = { x: finite(item.location.x, `nodes[${index}].location.x`, -1_000_000, 1_000_000), y: finite(item.location.y, `nodes[${index}].location.y`, -1_000_000, 1_000_000) };
|
||||
}
|
||||
validateNodeProperties(node, index);
|
||||
return node;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user