Display¶
Overview¶
A persistent display of a specific Node and its descendants, which is updated at discrete points in time.
Use display.getDOMElement or display.domElement to retrieve the Display's DOM representation. Use display.updateDisplay() to trigger the visual update in the Display's DOM element.
A standard way of using a Display with Scenery is to: 1. Create a Node that will be the root 2. Create a Display, referencing that node 3. Make changes to the scene graph 4. Call display.updateDisplay() to draw the scene graph into the Display 5. Go to (3)
Common ways to simplify the change/update loop would be to: - Use Node-based events. Initialize it with Display.initializeEvents(), then add input listeners to parts of the scene graph (see Node.addInputListener). - Execute code (and update the display afterwards) by using Display.updateOnRequestAnimationFrame.
Internal documentation:
Lifecycle information: Instance (create,dispose) - out of update: Stateless stub is created synchronously when a Node's children are added where we have no relevant Instance. - start of update: Creates first (root) instance if it doesn't exist (stateless stub). - synctree: Create descendant instances under stubs, fills in state, and marks removed subtree roots for disposal. - update instance disposal: Disposes root instances that were marked. This also disposes all descendant instances, and for every instance, it disposes the currently-attached drawables. Drawable (create,dispose) - synctree: Creates all drawables where necessary. If it replaces a self/group/shared drawable on the instance, that old drawable is marked for disposal. - update instance disposal: Any drawables attached to disposed instances are disposed themselves (see Instance lifecycle). - update drawable disposal: Any marked drawables that were replaced or removed from an instance (it didn't maintain a reference) are disposed.
add/remove drawables from blocks: - stitching changes pending "parents", marks for block update - backbones marked for disposal (e.g. instance is still there, just changed to not have a backbone) will mark drawables for block updates - add/remove drawables phase updates drawables that were marked - disposed backbone instances will only remove drawables if they weren't marked for removal previously (e.g. in case we are from a removed instance)
@author Jonathan Olson <jonathan.olson@colorado.edu>
Class Display¶
Constructor¶
new Display( rootNode : Node, providedOptions? : DisplayOptions )¶
Instance Methods¶
getDOMElement() : HTMLElement¶
updateDisplay()¶
Updates the display's DOM element with the current visual state of the attached root node and its descendants
getPhetioElementAt( point : Vector2 ) : PhetioObject | null¶
Used for Studio Autoselect to determine the leafiest PhET-iO Element under the mouse
isWebGLAllowed() : boolean¶
Whether WebGL is allowed to be used in drawables for this Display
getRootNode() : Node¶
getRootBackbone() : BackboneDrawable¶
getSize() : Dimension2¶
The dimensions of the Display's DOM element
getBounds() : Bounds2¶
setSize( size : Dimension2 )¶
Changes the size that the Display's DOM element will be after the next updateDisplay()
setWidthHeight( width : number, height : number )¶
Changes the size that the Display's DOM element will be after the next updateDisplay()
getWidth() : number¶
The width of the Display's DOM element
setWidth( width : number ) : this¶
Sets the width that the Display's DOM element will be after the next updateDisplay(). Should be an integral value.
getHeight() : number¶
The height of the Display's DOM element
setHeight( height : number ) : this¶
Sets the height that the Display's DOM element will be after the next updateDisplay(). Should be an integral value.
setBackgroundColor( color : Color | string | null ) : this¶
Will be applied to the root DOM element on updateDisplay(), and no sooner.
getBackgroundColor() : Color | string | null¶
addOverlay( overlay : TOverlay )¶
Adds an overlay to the Display. Each overlay should have a .domElement (the DOM element that will be used for display) and an .update() method.
removeOverlay( overlay : TOverlay )¶
Removes an overlay from the display.
getPDOMRootElement() : HTMLElement | null¶
Get the root accessible DOM element which represents this display and provides semantics for assistive technology. If this Display is not accessible, returns null.
isAccessible() : boolean¶
Has this Display enabled accessibility features like PDOM creation and support.
isElementUnderPDOM( element : Element, allowRoot : boolean ) : boolean¶
Returns true if the element is in the PDOM. That is only possible if the display is accessible. @param element @param allowRoot - If true, the root of the PDOM is also considered to be "under" the PDOM.
getUsedRenderersBitmask() : number¶
Returns the bitmask union of all renderers (canvas/svg/dom/webgl) that are used for display, excluding BackboneDrawables (which would be DOM).
canvasDataURL( callback : ( str: string ) => void )¶
canvasSnapshot( callback : ( canvas: HTMLCanvasElement, imageData: ImageData ) => void )¶
Renders what it can into a Canvas (so far, Canvas and SVG layers work fine)
setPointerDisplayVisible( visibility : boolean )¶
TODO: reduce code duplication for handling overlays https://github.com/phetsims/scenery/issues/1581
setPointerAreaDisplayVisible( visibility : boolean )¶
TODO: reduce code duplication for handling overlays https://github.com/phetsims/scenery/issues/1581
setHitAreaDisplayVisible( visibility : boolean )¶
TODO: reduce code duplication for handling overlays https://github.com/phetsims/scenery/issues/1581
setCanvasNodeBoundsVisible( visibility : boolean )¶
TODO: reduce code duplication for handling overlays https://github.com/phetsims/scenery/issues/1581
setFittedBlockBoundsVisible( visibility : boolean )¶
TODO: reduce code duplication for handling overlays https://github.com/phetsims/scenery/issues/1581
resizeOnWindowResize()¶
Sets up the Display to resize to whatever the self inner dimensions will be.
updateOnRequestAnimationFrame( stepCallback? : ( dt: number ) => void )¶
Updates on every request animation frame. If stepCallback is passed in, it is called before updateDisplay() with stepCallback( timeElapsedInSeconds )
cancelUpdateOnRequestAnimationFrame()¶
initializeEvents( options? : InputOptions )¶
Initializes event handling, and connects the browser's input event handlers to notify this Display of events.
NOTE: This can be reversed with detachEvents().
detachEvents()¶
Detach already-attached input event handling (from initializeEvents()).
addInputListener( listener : TInputListener ) : this¶
Adds an input listener.
removeInputListener( listener : TInputListener ) : this¶
Removes an input listener that was previously added with addInputListener.
hasInputListener( listener : TInputListener ) : boolean¶
Returns whether this input listener is currently listening to this Display.
More efficient than checking display.inputListeners, as that includes a defensive copy.
getInputListeners() : TInputListener[]¶
Returns a copy of all of our input listeners.
interruptInput() : this¶
Interrupts all input listeners that are attached to this Display.
interruptPointers() : this¶
Interrupts all pointers associated with this Display, see https://github.com/phetsims/scenery/issues/1582.
interruptOtherPointers( excludePointer : Pointer | null ) : this¶
Interrupts all pointers associated with this Display that are NOT currently having events executed. see https://github.com/phetsims/scenery/issues/1582.
If excludePointer is provided and is non-null, it's used as the "current" pointer that should be excluded from interruption.
loseWebGLContexts()¶
Triggers a loss of context for all WebGL blocks.
NOTE: Should generally only be used for debugging.
inspect()¶
Makes this Display available for inspection.
getDebugHTML() : string¶
Returns an HTML fragment that includes a large amount of debugging information, including a view of the instance tree and drawable tree.
getDebugURI() : string¶
Returns the getDebugHTML() information, but wrapped into a full HTML page included in a data URI.
popupDebug()¶
Attempts to open a popup with the getDebugHTML() information.
iframeDebug()¶
Attempts to open an iframe popup with the getDebugHTML() information in the same self. This is similar to popupDebug(), but should work in browsers that block popups, or prevent that type of data URI being opened.
getPDOMDebugHTML() : string¶
foreignObjectRasterization( callback : ( url: string | null ) => void )¶
Will attempt to call callback( {string} dataURI ) with the rasterization of the entire Display's DOM structure, used for internal testing. Will call-back null if there was an error
Only tested on recent Chrome and Firefox, not recommended for general use. Guaranteed not to work for IE <= 10.
See https://github.com/phetsims/scenery/issues/394 for some details.
popupRasterization()¶
getTrailFromPDOMIndicesString( indicesString : string ) : Trail | null¶
Will return null if the string of indices isn't part of the PDOMInstance tree
refreshSVG()¶
Forces SVG elements to have their visual contents refreshed, by changing state in a non-visually-apparent way. It should trick browsers into re-rendering the SVG elements.
See https://github.com/phetsims/scenery/issues/1507
refreshSVGOnNextFrame()¶
Similar to refreshSVG (see docs above), but will do so on the next frame.
dispose()¶
Releases references.
TODO: this dispose function is not complete. https://github.com/phetsims/scenery/issues/1581
Instance Properties¶
sizeProperty : TProperty<Dimension2>¶
(readonly)
The (integral, > 0) dimensions of the Display's DOM element (only updates the DOM element on updateDisplay())
descriptionUtteranceQueue : UtteranceQueue¶
data structure for managing aria-live alerts the this Display instance
focusManager : FocusManager¶
Manages the various types of Focus that can go through the Display, as well as Properties controlling which forms of focus should be displayed in the HighlightOverlay.
Static Methods¶
elementToSVGDataURL( domElement : HTMLElement, width : number, height : number, callback : ( url: string | null ) => void )¶
Takes a given DOM element, and asynchronously renders it to a string that is a data URL representing an SVG file.
@param domElement @param width - The width of the output SVG @param height - The height of the output SVG @param callback - Called as callback( url: {string} ), where the URL will be the encoded SVG file.
addInputListener( listener : TInputListener )¶
Adds an input listener to be fired for ANY Display
removeInputListener( listener : TInputListener )¶
Removes an input listener that was previously added with Display.addInputListener.
interruptInput()¶
Interrupts all input listeners that are attached to all Displays.
Static Properties¶
INTERRUPT_OTHER_POINTERS¶
(readonly)
userGestureEmitter : TEmitter¶
Fires when we detect an input event that would be considered a "user gesture" by Chrome, so that we can trigger browser actions that are only allowed as a result. See https://github.com/phetsims/scenery/issues/802 and https://github.com/phetsims/vibe/issues/32 for more information.
inputListeners : TInputListener[]¶
Listeners that will be called for every event on ANY Display, see https://github.com/phetsims/scenery/issues/1149. Do not directly modify this!
Type DisplayOptions¶
- width?: number
Initial (or override) display width - height?: number
Initial (or override) display height - allowCSSHacks?: boolean
Applies CSS styles to the root DOM element that make it amenable to interactive content - allowSafariRedrawWorkaround?: boolean
Whether we allow the display to put a rectangle in front of everything that subtly shifts every frame, in order to force repaints for https://github.com/phetsims/geometric-optics-basics/issues/31. - allowSceneOverflow?: boolean
Usually anything displayed outside our dom element is hidden with CSS overflow. - allowLayerFitting?: boolean
If false, this will disable layer fitting (like putting preventFit: true on Nodes, but for the entire Display). Layer fitting has caused some unsightly jittering (https://github.com/phetsims/scenery/issues/1289), so this allows it to be turned on in a case-by-case manner. - defaultCursor?: string
What cursor is used when no other cursor is specified - forceSVGRefresh?: boolean
Forces SVG elements to be refreshed every frame, which can force repainting and detect (or potentially in some cases work around) SVG rendering browser bugs. See https://github.com/phetsims/scenery/issues/1507 - backgroundColor?: Color | string | null
Initial background color - preserveDrawingBuffer?: boolean
Whether WebGL will preserve the drawing buffer WARNING!: This can significantly reduce performance if set to true. - allowWebGL?: boolean
Whether WebGL is enabled at all for drawables in this Display Makes it possible to disable WebGL for ease of testing on non-WebGL platforms, see #289 - accessibility?: boolean
Enables accessibility features - supportsInteractiveHighlights?: boolean
{boolean} - Enables Interactive Highlights in the HighlightOverlay. These are highlights that surround interactive components when using mouse or touch which improves low vision access. - interactive?: boolean
Whether mouse/touch/keyboard inputs are enabled (if input has been added). - listenToOnlyElement?: boolean
If true, input event listeners will be attached to the Display's DOM element instead of the self. Normally, attaching listeners to the self is preferred (it will see mouse moves/ups outside of the browser self, allowing correct button tracking), however there may be instances where a global listener is not preferred. - batchDOMEvents?: boolean
Forwarded to Input: If true, most event types will be batched until otherwise triggered. - assumeFullWindow?: boolean
If true, the input event location (based on the top-left of the browser tab's viewport, with no scaling applied) will be used. Usually, this is not a safe assumption, so when false the location of the display's DOM element will be used to get the correct event location. There is a slight performance hit to doing so, thus this option is provided if the top-left location can be guaranteed. NOTE: Rotation of the Display's DOM element (e.g. with a CSS transform) will result in an incorrect event mapping, as getBoundingClientRect() can't work with this. getBoxQuads() should fix this when browser support is available. - aggressiveContextRecreation?: boolean
Whether Scenery will try to aggressively re-create WebGL Canvas/context instead of waiting for a context restored event. Sometimes context losses can occur without a restoration afterwards, but this can jump-start the process. See https://github.com/phetsims/scenery/issues/347. - passiveEvents?: boolean | null
Whether thepassive
flag should be set when adding and removing DOM event listeners. See https://github.com/phetsims/scenery/issues/770 for more details. If it is true or false, that is the value of the passive flag that will be used. If it is null, the default behavior of the browser will be used.
Safari doesn't support touch-action: none, so we NEED to not use passive events (which would not allow preventDefault to do anything, so drags actually can scroll the sim). Chrome also did the same "passive by default", but because we have touch-action: none
in place, it doesn't affect us, and we can potentially get performance improvements by allowing passive events. See https://github.com/phetsims/scenery/issues/770 for more information. - allowBackingScaleAntialiasing?: boolean
Whether, if no WebGL antialiasing is detected, the backing scale can be increased to provide some antialiasing benefit. See https://github.com/phetsims/scenery/issues/859. - container?: HTMLElement
An HTMLElement used to contain the contents of the Display - & Pick<PhetioObjectOptions, "tandem">
Source Code¶
See the source for Display.ts in the scenery repository.