Skip to content

StopwatchNode

StopwatchNode (from scenerystack/scenery-phet) is the view for a Stopwatch model element: a digital mm:ss.cc readout with play/pause and reset buttons, optionally draggable within a set of bounds. Stopwatch itself is a plain PhetioObject model holding positionProperty, isVisibleProperty, isRunningProperty, and timePropertyStopwatchNode only renders and lets the user drag/press it.

ts
import { Stopwatch, StopwatchNode } from 'scenerystack/scenery-phet';
import { Property } from 'scenerystack/axon';
import { Bounds2 } from 'scenerystack/dot';

A minimal example

ts
const stopwatch = new Stopwatch( {
  tandem: tandem.createTandem( 'stopwatch' )
} );

const dragBoundsProperty = new Property( new Bounds2( 0, 0, 768, 504 ) );

const stopwatchNode = new StopwatchNode( stopwatch, {
  dragBoundsProperty: dragBoundsProperty,
  tandem: tandem.createTandem( 'stopwatchNode' )
} );

Call stopwatch.reset() from your model's reset() — resetting only the Node would leave the underlying time/running state untouched.

Constructor

ts
new StopwatchNode( stopwatch: Stopwatch, providedOptions?: StopwatchNodeOptions )

Stopwatch (the model)

MemberDescription
positionPropertyProperty<Vector2> — position in view coordinates
isVisiblePropertyProperty<boolean> — becoming invisible stops the stopwatch and resets its time
isRunningPropertyProperty<boolean> — whether time is currently advancing
timePropertyNumberProperty — elapsed time, in units the client defines (seconds by default)
step( dt )Advances the stopwatch by dt, clamped to timeProperty.range.max, auto-pausing at the max
setTime( t )Sets the time directly (only takes effect while running)
reset()Resets position, visibility, running state, and time
Stopwatch.ZERO_TO_ALMOST_SIXTYStatic Range( 0, 3599.99 ) — the default numberDisplayRange, i.e. up to 59:59.99

StopwatchNode options

OptionDefaultEffect
dragBoundsPropertynullIf provided, the stopwatch is draggable (mouse + keyboard) and constrained within these bounds; null means not draggable
numberDisplayRangeStopwatch.ZERO_TO_ALMOST_SIXTYSizes the internal NumberDisplay so the readout doesn't resize as digits change
numberDisplayOptionsformats mm:ss.ccForwarded to the internal NumberDisplay; set numberFormatter here for custom formatting
includePlayPauseResetButtonstrueWhether the play/pause and reset buttons are shown at all
otherControls[]Extra Nodes stacked below the buttons (e.g. a units selector)
xSpacing / ySpacing6 / 6Horizontal space between buttons / vertical space between readout and buttons
xMargin / yMargin8 / 8Margins of the background panel around the contents
playPauseButtonOptions / resetButtonOptionsForwarded to the respective buttons

Static formatting helpers

Static memberPurpose
StopwatchNode.DEFAULT_FONTThe standard monospace-digit font used for the readout
StopwatchNode.RICH_TEXT_MINUTES_AND_SECONDSDefault numberDisplayOptions.numberFormatter — RichText mm:ss.cc with smaller centiseconds
StopwatchNode.PLAIN_TEXT_MINUTES_AND_SECONDSSame format as plain text, for contexts that can't render RichText
StopwatchNode.createRichTextNumberFormatter( options )Builds a custom formatter — pass units, showAsMinutesAndSeconds, decimal places, etc.

A Stopwatch doesn't step itself

Stopwatch.step( dt ) must be called by something — typically the screen's model step(), gated on stopwatch.isRunningProperty. StopwatchNode never calls it for you; it only reflects timeProperty and toggles isRunningProperty via its buttons.