perf(fig): index override convergence candidates (#430)
- Reuse component-linked nodes across resolved fill passes - Reuse corresponding instance child pairs across placement passes - Preserve global fixed-point order and nested override behavior
This commit is contained in:
parent
1415640718
commit
da67e8dfb6
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
- Match regional browser languages to supported locales without selecting a secondary language. (#417)
|
||||
- Save auto-layout frames that stretch their children to `.fig` without failing. (#427)
|
||||
- Reduce large `.fig` page-switch work to the active page and coalesce Layers tree rebuilds. (#420)
|
||||
- Reduce large `.fig` page-switch work to the active page, reuse fixed-point propagation indexes, and coalesce Layers tree rebuilds. (#420)
|
||||
- Center text glyphs within explicit line-height leading in CanvasKit paragraph rendering.
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -85,10 +85,35 @@ function buildKiwiGeometryNodes(
|
|||
return result
|
||||
}
|
||||
|
||||
function propagateResolvedFills(graph: SceneGraph, protectedNodes: Set<string>): void {
|
||||
function componentLinkedNodes(graph: SceneGraph): SceneNode[] {
|
||||
const nodes: SceneNode[] = []
|
||||
for (const node of graph.getAllNodes()) if (node.componentId) nodes.push(node)
|
||||
return nodes
|
||||
}
|
||||
|
||||
function instancePlacementPairs(
|
||||
graph: SceneGraph
|
||||
): Array<{ sourceChildId: string; childId: string }> {
|
||||
const pairs: Array<{ sourceChildId: string; childId: string }> = []
|
||||
for (const node of graph.getAllNodes()) {
|
||||
if (node.type !== 'INSTANCE' || !node.componentId) continue
|
||||
const source = graph.getNode(node.componentId)
|
||||
if (!source || source.childIds.length !== node.childIds.length) continue
|
||||
for (let index = 0; index < node.childIds.length; index++) {
|
||||
pairs.push({ sourceChildId: source.childIds[index], childId: node.childIds[index] })
|
||||
}
|
||||
}
|
||||
return pairs
|
||||
}
|
||||
|
||||
function propagateResolvedFills(
|
||||
graph: SceneGraph,
|
||||
protectedNodes: Set<string>,
|
||||
candidates = componentLinkedNodes(graph)
|
||||
): void {
|
||||
for (let pass = 0; pass < 10; pass++) {
|
||||
let changed = false
|
||||
for (const node of graph.getAllNodes()) {
|
||||
for (const node of candidates) {
|
||||
if (!node.componentId) continue
|
||||
const source = graph.getNode(node.componentId)
|
||||
if (!source || isEqual(source.fills, node.fills)) continue
|
||||
|
|
@ -100,32 +125,30 @@ function propagateResolvedFills(graph: SceneGraph, protectedNodes: Set<string>):
|
|||
}
|
||||
}
|
||||
|
||||
function propagateResolvedChildPlacementClones(graph: SceneGraph): void {
|
||||
function propagateResolvedChildPlacementClones(
|
||||
graph: SceneGraph,
|
||||
pairs = instancePlacementPairs(graph)
|
||||
): void {
|
||||
for (let pass = 0; pass < 10; pass++) {
|
||||
let changed = false
|
||||
for (const node of graph.getAllNodes()) {
|
||||
if (node.type !== 'INSTANCE' || !node.componentId) continue
|
||||
const source = graph.getNode(node.componentId)
|
||||
if (!source || source.childIds.length !== node.childIds.length) continue
|
||||
for (let i = 0; i < node.childIds.length; i++) {
|
||||
const sourceChild = graph.getNode(source.childIds[i])
|
||||
const child = graph.getNode(node.childIds[i])
|
||||
if (!sourceChild || !child) continue
|
||||
if (
|
||||
sourceChild.overrideKey &&
|
||||
child.overrideKey &&
|
||||
sourceChild.overrideKey !== child.overrideKey
|
||||
) {
|
||||
continue
|
||||
}
|
||||
const updates: Partial<SceneNode> = {}
|
||||
if (!sourceChild.visible && child.visible) updates.visible = false
|
||||
if (sourceChild.x !== child.x) updates.x = sourceChild.x
|
||||
if (sourceChild.y !== child.y) updates.y = sourceChild.y
|
||||
if (Object.keys(updates).length === 0) continue
|
||||
graph.updateNode(child.id, updates)
|
||||
changed = true
|
||||
for (const pair of pairs) {
|
||||
const sourceChild = graph.getNode(pair.sourceChildId)
|
||||
const child = graph.getNode(pair.childId)
|
||||
if (!sourceChild || !child) continue
|
||||
if (
|
||||
sourceChild.overrideKey &&
|
||||
child.overrideKey &&
|
||||
sourceChild.overrideKey !== child.overrideKey
|
||||
) {
|
||||
continue
|
||||
}
|
||||
const updates: Partial<SceneNode> = {}
|
||||
if (!sourceChild.visible && child.visible) updates.visible = false
|
||||
if (sourceChild.x !== child.x) updates.x = sourceChild.x
|
||||
if (sourceChild.y !== child.y) updates.y = sourceChild.y
|
||||
if (Object.keys(updates).length === 0) continue
|
||||
graph.updateNode(child.id, updates)
|
||||
changed = true
|
||||
}
|
||||
if (!changed) return
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue