A boolean operation's box is the first operand's, and never follows what is drawn
_booleanOperation creates the BOOLEAN_OPERATION node with the first operand's x, y, width
and height, and nothing changes that box afterwards. What is drawn, though, comes from the
operands: makeBooleanOperationPath combines each visible child's path through their own
transforms, and never reads the node's own size.
So the box and the drawing agree only by chance at the moment the operation is made, and part ways
as soon as an operand moves or is resized — and they do not agree even then, since a union of two
shapes is larger than the first operand alone. Everything that reads the node's box rather than its
path reads the wrong thing: get_node's bounds, an auto-layout parent that places the node by its
size, hit-testing and selection handles, and an exported SVG's viewport.
What happens
- At once. Union a 30 by 30 rectangle at (10, 20) with a 20 by 20 one at (60, 70). The node's box is reported as 30 by 30 at (10, 20); what is drawn spans (10, 20) to (80, 90).
- Afterwards. Move the first operand 100 up and to the left. The drawing follows it; the box does not move at all, and now lies outside the drawing entirely.
- In an auto-layout frame. The row places the operation by that box, so it overlaps its neighbours or leaves a gap, by however much the box is wrong.
Reproduction, against OpenPencil's own tools
- Open a document and draw two rectangles in one frame: 30 by 30 at (10, 20), and 20 by 20 at (60, 70).
- Call
boolean_unionon the two of them, and read the new node withget_node: its box is the first rectangle's, 30 by 30 at (10, 20), while the canvas draws the union of both. - Move the first operand to (-100, -100) with
update_node, and read the node again: its box has not changed, though the drawing has moved with the operand.
What was expected
The node's box holds what it draws, and keeps holding it as the operands change — as a group's box
does in Figma, and as the editor's own wrapSelectionInContainer does when it makes a group. The
union of the visible operands' boxes is the box available without a path engine; it is exact for a
union and holds the drawing for the other three operations.
Where
packages/core/src/figma-api/index.ts,_booleanOperation, lines 365-388 ate2de247(x: first.x, y: first.y, width: first.width, height: first.height).- What is drawn instead:
packages/core/src/canvas/boolean.ts,makeBooleanOperationPath. - The tools that reach it:
packages/core/src/tools/vector/boolean.ts—boolean_union,boolean_subtract,boolean_intersect,boolean_exclude.
Source: open-pencil/open-pencil