These examples demonstrate common ways of using layout containers in Scenery. It is recommended to review the layout documentation before diving into these examples.

All of the code examples here are editable. You can change the code and see the results immediately.

Basic Layout

Panel Alignment

To have a vertical stack of Panels keep the same width, provide stretch: true either on the parent container, or on the layoutOptions of each Panel individually.

Match Button Sizes

AlignGroup can be used to match the sizes of Nodes in a layout, and the align:stretch option can be used on sizable content (e.g. buttons) to make them match the size of the largest button.

Wrap Content

Use wrap: true if you would like content in a FlowBox to wrap onto the next row or column if a string or other dynamic element becomes too long. This example shows a panel that acts as a type of legend. As the label width changes for one of the legend entries the others wrap accordingly.

Button Alignment

Buttons can maintain alignment as their content resizes. This example uses a GridBox and stretch: true to align buttons in the first column as the width in one of the buttons changes. Notice how the width of the second column is unaffected.

Resizable Buttons

When provided resizing/dynamic content, buttons can automatically adjust to the content's width. By default buttons are sizable: true.

Checkboxes

Icons

Checkboxes are WidthSizable, and act like a container for their label. For icons, this means you can pass in HBoxes to the label with two items, and the default justification will expand items out to the desired bounds:

Indentation

Margins can be used for indenting checkboxes:

Transforms

Sizable nodes within layout containers CAN be transformed in some specific ways that will be respected. It's generally preferred to avoid transforms on direct children of layout containers, but sometimes it's necessary.

Scale

Scale should be maintained and respected by layout containers. In cases like these, the preferredWidth and localPreferredWidth of sizable nodes will be different (based on the current transform). In general, set preferredWidth as normal, regardless of the scale.

Reflection

Reflection is also supported (but hopefully rarely needed)

Rotation

Rotation is also supported.

Flow Constraint

Disconnected Flow

Flow constraint allows a parent and child to have disconnected position and bounds.

Flow Stress Test

300 rectangles are created with random sizes inside a Flowbox to demonstrate a horizontal orientation with wrapping. Stress test demonstrates how layout successfully handles a variety of rectangle sizes while still aligning content as expected.

Grid Constraint

Grid Stress Test

900 rectangles are created with random sizes inside a gridBox. Each rectangle is inside its own cell. Stress test demonstrates how layout successfully adjusts row and column sizes to accommodate a variety of rectangle sizes.

Manual Constraint

Disconnected Nodes Alignment

A resizer animates to demonstrate how Manual Constraint can connect the layout of two separate nodes. The position of the leftText stays aligned with the position of the rightText as the rightText's y coordinate changes.

DynamicCentering

This example comes from a use case in Greenhouse Effect. In this sim the developer was looking for a way to dynamically center a button in a play area Observation Window. Manual Constraint became the perfect tool to accomplish this. By triggering a callback each time the bounds of the button changed, Manual Constraint created seamless centering based off of another node's layout bounds.

Use ManualConstraint.create to set up your custom positioning. The first argument is the ancestorNode (this node must be common to all nodes we will be listening to). The second argument is an array of nodes you want to trigger the manual constraint and/or manipulate in the constraint. The third argument is a callback that will be triggered anytime the bounds of our nodes in the second argument change.

Conditional Alignment

This example comes from a use case in Build a Nucleus

Dynamic Labels

This example comes from a use case in Density. In this sim an arrow shows where a cube lands on the density spectrum. A label must accompany this arrow adding more clarity to to the data a user is seeing. ManualConstraint.create allows developers to connect two separate nodes together so that when a node's x or y position changes another node can respond accordingly.

Align Group

Cross Screen Alignment

It is common for PhET sims to have panels that exist across multiple screens. These panels may have different content but a design standard is that their width/height matches across those screens. This example shows how AlignGroup can easily accomplish this with little effort on the developer's part. This example may require a bit of imagination. Imagine each Panel is located in a different screen, and notice how their widths and heights synchronize.

Origin

As seen in fractions LabScreen

Origin Orientation

Demos the orientation feature for alignment in flow and grid layouts. Essentially the x=0 or y=0 point of the nodes are placed in the same vertical or horizontal line when 'origin' is used for alignment.

Separators

Disappearing Node

A disappearing node demonstrates how separators dynamically react to content being added or removed in a panel.