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.
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.
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.
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.
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.
When provided resizing/dynamic content, buttons can automatically adjust to the content's width. By default
buttons are sizable: true
.
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:
Margins can be used for indenting checkboxes:
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 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 is also supported (but hopefully rarely needed)
Rotation is also supported.
Flow constraint allows a parent and child to have disconnected position and bounds.
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.
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.
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.
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.
This example comes from a use case in Build a Nucleus
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.
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.
As seen in fractions LabScreen
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.
A disappearing node demonstrates how separators dynamically react to content being added or removed in a panel.