Skip to content

RichDragListener

RichDragListener (from scenerystack/scenery) is not a subclass of DragListener — it composes one internal DragListener and one internal KeyboardDragListener, forwarding every scenery input-listener callback (down, up, keydown, focus, …) to whichever of the two applies, and implements TInputListener so it can be attached to a Node exactly like either listener alone. It exists so a draggable object gets pointer and keyboard support from one declaration instead of wiring up both listeners and their shared options by hand — see Drag Listeners for why it's the recommended default for new draggable code, with plain DragListener/KeyboardDragListener reserved for cases needing one modality only or finer control.

ts
import { Node, RichDragListener } from 'scenerystack/scenery';

const bodyNode = new Node( { tagName: 'div', focusable: true, cursor: 'pointer' } );

bodyNode.addInputListener( new RichDragListener( {
  positionProperty: body.positionProperty,
  transform: modelViewTransform,
  dragBoundsProperty: model.dragBoundsProperty,
  start: () => body.userControlledProperty.set( true ),
  end: () => body.userControlledProperty.set( false ),
  keyboardDragListenerOptions: {
    dragSpeed: 150
  }
} ) );

Options

RichDragListenerOptions shares the common drag options (positionProperty, transform, dragBoundsProperty, mapPosition, translateNode, start/drag/end) applied to both internal listeners, plus:

OptionDefaultEffect
dragListenerOptions{}Additional/overriding options passed only to the internal DragListener (e.g. allowTouchSnag, mouseButton)
keyboardDragListenerOptions{}Additional/overriding options passed only to the internal KeyboardDragListener (e.g. dragSpeed, keyboardDragDirection)
tandemTandem.REQUIREDSplit internally into tandem.createTandem('dragListener') / 'keyboardDragListener' for PhET-iO

start/drag/end given directly on RichDragListener fire for either input type; listener-specific callbacks in dragListenerOptions/keyboardDragListenerOptions fire in addition to (not instead of) the shared ones.

Public state and methods

MemberMeaning
dragListenerThe internal DragListener instance — public, so you can inspect/reuse it directly
keyboardDragListenerThe internal KeyboardDragListener instance
isPressedPropertytrue if either internal listener is pressed
interrupt()Interrupts both internal listeners
dispose()Disposes both internal listeners and this listener's own Properties

Starting one input type interrupts the other

When the pointer DragListener starts, it interrupts the KeyboardDragListener (and vice versa) — the two are mutually exclusive at any instant, so a drag can't be simultaneously driven by a mouse and the keyboard. This is handled internally; you don't need to manage it in your start/end callbacks.