openpencil/packages/fig/src/node-change/export/resolved-bindings.ts
Danila Poyarkov 4939cd4982
fix(fig): write bound fields resolved when exporting .fig (#859)
Figma draws the value a bound paint or number stores until something makes
it resolve the variable again. OpenPencil resolves bound colours only when
drawing, so exports wrote the colour from before the binding, and a graph
bound without the editor kept stale numbers too: a file opened in Figma
showed bound fills in their old colour.

The exporter now writes each node with its bindings resolved, without
changing the document: colours as the variable's RGB at full alpha with
its alpha as the paint's opacity, which is how Figma stores them in every
fixture, and numbers in scene units. Nodes without an explicit mode take
the collection's default, because the mode the editor shows is not saved.

The resolution moves into scene-graph as resolvedPaintBindings and
resolvedNumericBindings, which the reader and reconcileNumericVariableBindings
now share, and the node resolvers take a fallback of 'active' or 'default'.
2026-10-04 08:59:42 +00:00

22 lines
877 B
TypeScript

import {
resolvedNumericBindings,
resolvedPaintBindings,
type SceneGraph,
type SceneNode
} from '@open-pencil/scene-graph'
/**
* Figma draws the value a bound field stores until something makes it resolve the binding
* again, so each node is written with its bindings resolved for its mode. The editor resolves
* colors only when drawing, and a graph bound without the editor keeps stale numbers too.
* A node without an explicit mode takes its collection's default: the mode the editor happens
* to show is not saved, and Figma opens the file in the default.
*/
export function nodeWithResolvedBindings(graph: SceneGraph, node: SceneNode): SceneNode {
const changes = {
...resolvedNumericBindings(graph, node, 'default'),
...resolvedPaintBindings(graph, node, 'default')
}
return Object.keys(changes).length > 0 ? { ...node, ...changes } : node
}