Skip to content

Trail

Overview

Represents a trail (path in the graph) from a 'root' node down to a descendant node. In a DAG, or with different views, there can be more than one trail up from a node, even to the same root node!

It has an array of nodes, in order from the 'root' down to the last node, a length, and an array of indices such that node_i.children[index_i] === node_{i+1}.

The indices can sometimes become stale when nodes are added and removed, so Trails can have their indices updated with reindex(). It's designed to be as fast as possible on Trails that are already indexed accurately.

@author Jonathan Olson <jonathan.olson@colorado.edu>

Class Trail

import { Trail } from 'scenerystack/scenery';

Constructor

new Trail( nodes? : Trail | Node[] | Node )

Instance Methods

copy() : Trail

Returns a copy of this Trail that can be modified independently

isValid() : boolean

Whether all nodes in the trail are still connected from the trail's root to its leaf.

isVisible() : boolean

This trail is visible only if all nodes on it are marked as visible

isPDOMVisible() : boolean

This trail is pdomVisible only if all nodes on it are marked as pdomVisible

getOpacity() : number

isPickable() : boolean

Essentially whether this node is visited in the hit-testing operation

get( index : number ) : Node

slice( startIndex : number, endIndex? : number ) : Trail

subtrailTo( node : Node, excludeNode ) : Trail

TODO: consider renaming to subtrailToExcluding and subtrailToIncluding? https://github.com/phetsims/scenery/issues/1581

isEmpty() : boolean

getMatrixConcatenation( startingIndex : number, endingIndex : number ) : Matrix3

Returns the matrix multiplication of our selected nodes transformation matrices.

@param startingIndex - Include nodes matrices starting from this index (inclusive) @param endingIndex - Include nodes matrices up to this index (exclusive)

getMatrix() : Matrix3

From local to global

e.g. local coordinate frame of the leaf node to the parent coordinate frame of the root node

getAncestorMatrix() : Matrix3

From local to next-to-global (ignores root node matrix)

e.g. local coordinate frame of the leaf node to the local coordinate frame of the root node

getParentMatrix() : Matrix3

From parent to global

e.g. parent coordinate frame of the leaf node to the parent coordinate frame of the root node

getAncestorParentMatrix() : Matrix3

From parent to next-to-global (ignores root node matrix)

e.g. parent coordinate frame of the leaf node to the local coordinate frame of the root node

getTransform() : Transform3

From local to global

e.g. local coordinate frame of the leaf node to the parent coordinate frame of the root node

getParentTransform() : Transform3

From parent to global

e.g. parent coordinate frame of the leaf node to the parent coordinate frame of the root node

addAncestor( node : Node, index? : number ) : this

removeAncestor() : this

addDescendant( node : Node, index? : number ) : this

removeDescendant() : this

addDescendantTrail( trail : Trail )

removeDescendantTrail( trail : Trail )

reindex()

Refreshes the internal index references (important if any children arrays were modified!)

setImmutable() : this

setMutable() : this

areIndicesValid() : boolean

equals( other : Trail ) : boolean

upToNode( node : Node ) : Trail

Returns a new Trail from the root up to the parameter node.

isExtensionOf( other : Trail, allowSameTrail? : boolean ) : boolean

Whether this trail contains the complete 'other' trail, but with added descendants afterwards.

@param other - is other a subset of this trail? @param allowSameTrail

containsNode( node : Node ) : boolean

Returns whether a given node is contained in the trail.

getTransformTo( otherTrail : Trail ) : Transform3

A transform from our local coordinate frame to the other trail's local coordinate frame

getMatrixTo( otherTrail : Trail ) : Matrix3

Returns a matrix that transforms a point in our last node's local coordinate frame to the other trail's last node's local coordinate frame

getBranchIndexTo( otherTrail : Trail ) : number

Returns the first index that is different between this trail and the other trail.

If the trails are identical, the index should be equal to the trail's length.

getLastInputEnabledIndex() : number

Returns the last (largest) index into the trail's nodes that has inputEnabled=true.

getCursorCheckIndex() : number

Returns the leaf-most index, unless there is a Node with inputEnabled=false (in which case, the lowest index for those matching Nodes are returned).

nodeFromTop( offset : number ) : Node

TODO: phase out in favor of get() https://github.com/phetsims/scenery/issues/1581

lastNode() : Node

rootNode() : Node

previous() : Trail | null

Returns the previous graph trail in the order of self-rendering

previousPainted() : Trail | null

Like previous(), but keeps moving back until the trail goes to a node with isPainted() === true

next() : Trail | null

In the order of self-rendering

nextPainted() : Trail | null

Like next(), but keeps moving back until the trail goes to a node with isPainted() === true

eachTrailUnder( callback : TrailCallback )

Calls callback( trail ) for this trail, and each descendant trail. If callback returns true, subtree will be skipped

compare( other : Trail ) : number

Standard Java-style compare. -1 means this trail is before (under) the other trail, 0 means equal, and 1 means this trail is after (on top of) the other trail. A shorter subtrail will compare as -1.

Assumes that the Trails are properly indexed. If not, please reindex them!

Comparison is for the rendering order, so an ancestor is 'before' a descendant

isBefore( other : Trail ) : boolean

isAfter( other : Trail ) : boolean

localToGlobalPoint( point : Vector2 ) : Vector2

localToGlobalBounds( bounds : Bounds2 ) : Bounds2

globalToLocalPoint( point : Vector2 ) : Vector2

globalToLocalBounds( bounds : Bounds2 ) : Bounds2

parentToGlobalPoint( point : Vector2 ) : Vector2

parentToGlobalBounds( bounds : Bounds2 ) : Bounds2

globalToParentPoint( point : Vector2 ) : Vector2

globalToParentBounds( bounds : Bounds2 ) : Bounds2

getUniqueId() : string

Concatenates the unique IDs of nodes in the trail, so that we can do id-based lookups

toString() : string

Returns a string form of this object

toPathString() : string

Cleaner string form which will show class names. Not optimized by any means, meant for debugging.

toDebugString() : string

Returns a debugging string ideal for logged output.

Instance Properties

nodes : Node[]

The main nodes of the trail, in order from root to leaf

length : number

Shortcut for the length of nodes.

uniqueId : string

A unique identifier that should only be shared by other trails that are identical to this one.

indices : number[]

indices[x] stores the index of nodes[x] in nodes[x-1]'s children, e.g. nodes[i].children[ indices[i] ] === nodes[i+1]

Static Methods

eachPaintedTrailBetween( a : Trail, b : Trail, callback : ( trail: Trail ) => void, excludeEndTrails : boolean, rootNode : Node )

Like eachTrailBetween, but only fires for painted trails. If callback returns true, subtree will be skipped

eachTrailBetween( a : Trail, b : Trail, callback : ( trail: Trail ) => void, excludeEndTrails : boolean, rootNode : Node )

Global way of iterating across trails. when callback returns true, subtree will be skipped

branchIndex( a : Trail, b : Trail ) : number

The index at which the two trails diverge. If a.length === b.length === branchIndex, the trails are identical

sharedTrail( a : Trail, b : Trail ) : Trail

The subtrail from the root that both trails share

appendAncestorTrailsWithPredicate( trailResults : Trail[], trail : Trail, predicate : ( node: Node ) => boolean )

@param trailResults - Will be muted by appending matching trails @param trail @param predicate

appendDescendantTrailsWithPredicate( trailResults : Trail[], trail : Trail, predicate : ( node: Node ) => boolean )

@param trailResults - Will be muted by appending matching trails @param trail @param predicate

spannedSubtrees( a : Trail, b : Trail )

Fires subtree(trail) or self(trail) on the callbacks to create disjoint subtrees (trails) that cover exactly the nodes inclusively between a and b in rendering order. We try to consolidate these as much as possible.

"a" and "b" are treated like self painted trails in the rendering order

Example tree: a - b --- c --- d - e --- f ----- g ----- h ----- i --- j ----- k - l - m --- n

spannedSubtrees( a, a ) -> self( a ); spannedSubtrees( c, n ) -> subtree( a ); NOTE: if b is painted, that wouldn't work! spannedSubtrees( h, l ) -> subtree( h ); subtree( i ); subtree( j ); self( l ); spannedSubtrees( c, i ) -> [b,f] --- wait, include e self?

fromUniqueId( rootNode : Node, uniqueId : string ) : Trail

Re-create a trail to a root node from an existing Trail id. The rootNode must have the same Id as the first Node id of uniqueId.

@param rootNode - the root of the trail being created @param uniqueId - integers separated by ID_SEPARATOR, see getUniqueId

Source Code

See the source for Trail.ts in the scenery repository.