Vector2Property
Vector2Property (from scenerystack/dot) is a Property<Vector2> subclass — the standard type for a model's positionProperty, a drag target's location, or any other Vector2-valued piece of observable state. Beyond fixing valueType: Vector2 and wiring up Vector2.Vector2IO for PhET-iO, it adds two validators of its own: it always rejects a vector with a NaN component, and it optionally confines every value to a Bounds2 region via the validBounds option.
import { Vector2Property } from 'scenerystack/dot';
import { Vector2, Bounds2 } from 'scenerystack/dot';
const positionProperty = new Vector2Property( new Vector2( 0, 0 ), {
validBounds: new Bounds2( -100, -100, 100, 100 )
} );
positionProperty.link( position => console.log( 'position:', position ) );
positionProperty.value = new Vector2( 50, 50 ); // fine, inside validBounds
// positionProperty.value = new Vector2( 500, 0 ); // assertion failure: outside validBoundsAside from these extra validators, Vector2Property behaves exactly like a plain Property<Vector2>: .value, .link(), .reset(), and every other member documented on Property work the same way.
Constructor
new Vector2Property( initialValue: Vector2, providedOptions?: Vector2PropertyOptions )Vector2PropertyOptions is PropertyOptions<Vector2> (see Property's options) minus valueType/phetioValueType (which Vector2Property fixes for you), plus:
| Option | Effect |
|---|---|
validBounds | If provided, every value set on the Property must satisfy validBounds.containsPoint( value ); enforced via an assertion-only validator, so it has no effect in production builds without assertions |
Mutating the stored Vector2 in place bypasses validation and listeners
Because Vector2Property's validators (including validBounds) only run inside set()/value=, calling a mutating method directly on the currently-stored vector — positionProperty.value.add( delta ) instead of positionProperty.value = positionProperty.value.plus( delta ) — skips both the bounds check and listener notification entirely. Always reassign .value with a new Vector2 (via plus, plusXY, etc.) rather than mutating the existing one in place; see the same caveat on Vector2.