Skip to content

Node

Node (from scenerystack/scenery) is the base class for every visual element in a scenery scene graph. On its own a Node draws nothing — it's a container that holds children and applies a transform (translation/rotation/scale), visibility, opacity, input behavior, and layout options to that subtree. Every other page in this section — Path, Text, Image, the layout containers — is a Node subclass, so the options and methods documented here apply everywhere.

ts
import { Node, Circle, Rectangle } from 'scenerystack/scenery';
import { Vector2 } from 'scenerystack/dot';

const group = new Node( {
  children: [
    new Circle( 20, { fill: 'orange' } ),
    new Rectangle( 30, -10, 40, 20, { fill: 'teal' } )
  ],
  x: 100,
  y: 50,
  scale: 1.5,
  visible: true
} );

group.addChild( new Circle( 5, { fill: 'black', x: 60 } ) );

Building the scene graph

MethodEffect
addChild( node )Appends node as the last (topmost) child
insertChild( index, node )Inserts node at a specific position in the children order
removeChild( node )Removes a specific child
removeChildAt( index )Removes the child at a given index
removeAllChildren()Clears all children
mutate( options )Applies a NodeOptions object all at once, in a fixed, documented order

Children later in the list are drawn on top of earlier ones — order matters for visual stacking, not just structure.

Frequently used options

OptionEffect
childrenInitial list of child Nodes, added in order
visibleWhether this Node (and its subtree) is displayed; invisible subtrees are also excluded from picking by default
pickabletrue/false/null — overrides whether this subtree can receive input events
enabledApplication-level enabled state (paired with enabledProperty)
inputEnabledWhether input events are allowed to reach this subtree
inputListenersArray of input listeners attached at construction, e.g. a FireListener
opacity0 (transparent) to 1 (opaque) applied to the whole subtree
cursorCSS cursor shown when the pointer is over this Node
x, y, translationTranslation of this Node relative to its parent
rotationRotation in radians
scaleUniform or Vector2 scale
left, right, top, bottom, centerX, centerY, center, leftTop, rightBottom, …Positioning shortcuts based on this Node's (parent-coordinate-frame) bounds — applied after other transform options
maxWidth / maxHeightAutomatically scales the Node down (never up) to fit within the given local-bounds dimensions
clipAreaA Shape (see kite Shape) outside of which content is hidden
mouseArea / touchAreaOverrides the hit-testing region, independent of the drawn shape
layoutOptionsOptions consumed by a parent layout container, e.g. FlowBox or GridBox

Reading bounds and position

ts
const b = group.bounds;       // Bounds2 in the parent coordinate frame
const local = group.localBounds; // Bounds2 in this Node's own coordinate frame

group.center = new Vector2( 0, 0 ); // reposition using the bounds-based setter

Node also exposes coordinate-conversion helpers: localToGlobalPoint( point ) and globalToLocalPoint( point ) convert between this Node's local frame and the Display's root frame — useful when translating pointer coordinates.

Order of options in mutate()

Node options are applied in a fixed, documented order (transform options like x/scale before bounds-based options like left/center). This is why you can safely pass both a scale and a center in the same options object and get the expected result — the centering happens after scaling.

Dispose subtrees you remove permanently

Removing a Node from its parent does not automatically dispose it. If a subtree is being discarded for good (not just hidden), call dispose() (or disposeSubtree()) to release its listeners, Property links, and other resources — otherwise removed simulation elements can leak memory.