API reference
Every public class, method, and event in @codexo/exojs. Generated from source.
classRetainedContainer
A Container that declares its subtree "mostly static and/or moves as a whole". While the subtree is unchanged, its whole previously-collected command range is spliced into the render plan - no walk, no per-child culling, no material keys - and moving the container (or the camera) changes only one per-group GPU matrix instead of touching every descendant. Opt-in at construction; there is no runtime toggle. The existing revision contract (RenderNode.invalidateContent and the automatic bumps on built-in mutation paths) is the entire authoring surface: any mutation inside the subtree drops the retained fragment for one frame. Trade-offs of the group-local space convention: descendants resolve group-relative transforms, so hit-testing/`getBounds()` inside the group are group-local; per-child view culling is disabled inside the group (the group is culled as a whole); particle-extension drawables bake their own transforms and are not group-transform-aware. `PixelSnapMode.Position` IS group-aware - the shader applies the group matrix before rounding the composed device origin, so a position-snapped node inside a translated/scaled group still lands on the device-pixel grid (and stays recordable). Group-wide fades are done per-drawable tint (the engine has no inherited alpha) or via RenderNode.cacheAsTexture. Nodes with filters/mask/clip/ cacheAsTexture are supported as DIRECT children (they stay world-space and re-collect every frame); nesting one deeper pushes ONLY the direct child branch containing it out of the group - that sub-branch renders world-space and re-collects every frame like a direct barrier child, while retention and the group transform stay active for the rest of the group - and warns once in dev builds. Note that any escaped branch keeps the group's fragment off the recorded-instruction tier (barrier entries are not batch-recordable); the group stays on entry replay. World-space queries against nodes inside the group (picking, spatial audio, physics, cross-group math) go through SceneNode.getWorldTransform, which composes through the boundary and returns the true world matrix.
import { RetainedContainer } from '@codexo/exojs'A Container that declares its subtree "mostly static and/or moves as a whole". While the subtree is unchanged, its whole previously-collected command range is spliced into the render plan - no walk, no per-child culling, no material keys - and moving the container (or the camera) changes only one per-group GPU matrix instead of touching every descendant.
Opt-in at construction; there is no runtime toggle. The existing revision contract (RenderNode.invalidateContent and the automatic bumps on built-in mutation paths) is the entire authoring surface: any mutation inside the subtree drops the retained fragment for one frame.
Trade-offs of the group-local space convention: descendants resolve group-relative transforms, so hit-testing/`getBounds()` inside the group are group-local; per-child view culling is disabled inside the group (the group is culled as a whole); particle-extension drawables bake their own transforms and are not group-transform-aware. `PixelSnapMode.Position` IS group-aware - the shader applies the group matrix before rounding the composed device origin, so a position-snapped node inside a translated/scaled group still lands on the device-pixel grid (and stays recordable). Group-wide fades are done per-drawable tint (the engine has no inherited alpha) or via RenderNode.cacheAsTexture. Nodes with filters/mask/clip/ cacheAsTexture are supported as DIRECT children (they stay world-space and re-collect every frame); nesting one deeper pushes ONLY the direct child branch containing it out of the group - that sub-branch renders world-space and re-collects every frame like a direct barrier child, while retention and the group transform stay active for the rest of the group - and warns once in dev builds. Note that any escaped branch keeps the group's fragment off the recorded-instruction tier (barrier entries are not batch-recordable); the group stays on entry replay.
World-space queries against nodes inside the group (picking, spatial audio, physics, cross-group math) go through SceneNode.getWorldTransform, which composes through the boundary and returns the true world matrix.
new(): RetainedContainer_markOwnTransformDirty(): void_onChildListChanged(): voidblur(): thisclearFilters(): thiscollidesWith(target: CollidableContract for objects that participate in collision detection. Implemented by all concrete shape classes as well as `SceneNode`.): CollisionResponseResult of a successful Collidable.collidesWith call. Contains the two participating shapes, the penetration depth, containment flags, and the minimum-translati… | nullcontains(x: number, y: number): booleandestroy(): voidfocus(): thisgetBounds(out?: RectangleMutable axis-aligned rectangle defined by a top-left origin `(x, y)` and dimensions `(width, height)`. Implements Collidable with full SAT collision response f…): RectangleMutable axis-aligned rectangle defined by a top-left origin `(x, y)` and dimensions `(width, height)`. Implements Collidable with full SAT collision response f…invalidateCache(): thisinvalidateContent(): thismove(x: number, y: number): thisproject(axis: VectorConcrete mutable 2D vector with full AbstractVector arithmetic and Collidable collision support (treated as a point collider). `Vector.temp` provides a shared…, result: IntervalA closed scalar interval `[min, max]` used by the SAT collision solver to represent the projection of a shape onto a separating axis. `Interval.temp` provides…): IntervalA closed scalar interval `[min, max]` used by the SAT collision solver to represent the projection of a shape onto a separating axis. `Interval.temp` provides…removeChildAt(index: number): thisremoveChildren(begin: number, end: number): thisrender(backend: RenderBackend): thisrotate(degrees: number): thissetChildIndex(child: RenderNodeSceneNode that can produce visual output. Adds the rendering pipeline features on top of the structural transform/bounds carried by SceneNode: post-process `fi…, index: number): thissetLocalBounds(x: number, y: number, width: number, height: number): thissetOrigin(x: number, y: number): thissetPosition(x: number, y: number): thissetRotation(degrees: number): thissetScale(x: number, y: number): thissetSkew(x: number, y: number): thisswapChildren(firstChild: RenderNodeSceneNode that can produce visual output. Adds the rendering pipeline features on top of the structural transform/bounds carried by SceneNode: post-process `fi…, secondChild: RenderNodeSceneNode that can produce visual output. Adds the rendering pipeline features on top of the structural transform/bounds carried by SceneNode: post-process `fi…): thisupdateBounds(): thisupdateParentTransform(): thisupdateTransform(): thiscursor: null | stringdraggable: booleanfocusable: booleanname: null | stringtabIndex: numberbottom: numbercacheAsTexture: booleancacheResolution: TargetResolutionclip: booleanclipShape: GeometryNon-renderable geometry data object used by advanced rendering paths. Geometry owns only vertex/index data and its layout metadata; it is not a scene node, has… | RectangleMutable axis-aligned rectangle defined by a top-left origin `(x, y)` and dimensions `(width, height)`. Implements Collidable with full SAT collision response f… | nullcullable: booleandestroyed: booleanheight: numberinteractive: booleanisAlignedBox: booleanleft: numberpreserveDrawOrder: booleanright: numberrotation: numberskewX: numberskewY: numbertop: numbervisible: booleanwidth: numberx: numbery: numberzIndex: numberonBlur: SignalLightweight typed event emitter. Each `Signal` represents one named notification channel (e.g. `onResize`, `onFrame`). Listeners are added with Signal.add or S…<[RenderNodeSceneNode that can produce visual output. Adds the rendering pipeline features on top of the structural transform/bounds carried by SceneNode: post-process `fi…]>onContextMenu: SignalLightweight typed event emitter. Each `Signal` represents one named notification channel (e.g. `onResize`, `onFrame`). Listeners are added with Signal.add or S…<[InteractionEventDOM-Event-shaped envelope dispatched by InteractionSystem to interactive scene nodes. Bubbles up the *entire* parent chain - `target` stays pinned to the hit-d…]>onDrag: SignalLightweight typed event emitter. Each `Signal` represents one named notification channel (e.g. `onResize`, `onFrame`). Listeners are added with Signal.add or S…<[InteractionEventDOM-Event-shaped envelope dispatched by InteractionSystem to interactive scene nodes. Bubbles up the *entire* parent chain - `target` stays pinned to the hit-d…]>onDragEnd: SignalLightweight typed event emitter. Each `Signal` represents one named notification channel (e.g. `onResize`, `onFrame`). Listeners are added with Signal.add or S…<[InteractionEventDOM-Event-shaped envelope dispatched by InteractionSystem to interactive scene nodes. Bubbles up the *entire* parent chain - `target` stays pinned to the hit-d…]>onDragStart: SignalLightweight typed event emitter. Each `Signal` represents one named notification channel (e.g. `onResize`, `onFrame`). Listeners are added with Signal.add or S…<[InteractionEventDOM-Event-shaped envelope dispatched by InteractionSystem to interactive scene nodes. Bubbles up the *entire* parent chain - `target` stays pinned to the hit-d…]>onFocus: SignalLightweight typed event emitter. Each `Signal` represents one named notification channel (e.g. `onResize`, `onFrame`). Listeners are added with Signal.add or S…<[RenderNodeSceneNode that can produce visual output. Adds the rendering pipeline features on top of the structural transform/bounds carried by SceneNode: post-process `fi…]>onKeyDown: SignalLightweight typed event emitter. Each `Signal` represents one named notification channel (e.g. `onResize`, `onFrame`). Listeners are added with Signal.add or S…<[KeyEventEnvelope dispatched by `app.interaction` to the focused RenderNode for keyboard input, then bubbled up its entire parent chain - same DOM-style shape as Intera…]>onKeyUp: SignalLightweight typed event emitter. Each `Signal` represents one named notification channel (e.g. `onResize`, `onFrame`). Listeners are added with Signal.add or S…<[KeyEventEnvelope dispatched by `app.interaction` to the focused RenderNode for keyboard input, then bubbled up its entire parent chain - same DOM-style shape as Intera…]>onPointerDown: SignalLightweight typed event emitter. Each `Signal` represents one named notification channel (e.g. `onResize`, `onFrame`). Listeners are added with Signal.add or S…<[InteractionEventDOM-Event-shaped envelope dispatched by InteractionSystem to interactive scene nodes. Bubbles up the *entire* parent chain - `target` stays pinned to the hit-d…]>onPointerMove: SignalLightweight typed event emitter. Each `Signal` represents one named notification channel (e.g. `onResize`, `onFrame`). Listeners are added with Signal.add or S…<[InteractionEventDOM-Event-shaped envelope dispatched by InteractionSystem to interactive scene nodes. Bubbles up the *entire* parent chain - `target` stays pinned to the hit-d…]>onPointerOut: SignalLightweight typed event emitter. Each `Signal` represents one named notification channel (e.g. `onResize`, `onFrame`). Listeners are added with Signal.add or S…<[InteractionEventDOM-Event-shaped envelope dispatched by InteractionSystem to interactive scene nodes. Bubbles up the *entire* parent chain - `target` stays pinned to the hit-d…]>onPointerOver: SignalLightweight typed event emitter. Each `Signal` represents one named notification channel (e.g. `onResize`, `onFrame`). Listeners are added with Signal.add or S…<[InteractionEventDOM-Event-shaped envelope dispatched by InteractionSystem to interactive scene nodes. Bubbles up the *entire* parent chain - `target` stays pinned to the hit-d…]>onPointerTap: SignalLightweight typed event emitter. Each `Signal` represents one named notification channel (e.g. `onResize`, `onFrame`). Listeners are added with Signal.add or S…<[InteractionEventDOM-Event-shaped envelope dispatched by InteractionSystem to interactive scene nodes. Bubbles up the *entire* parent chain - `target` stays pinned to the hit-d…]>onPointerUp: SignalLightweight typed event emitter. Each `Signal` represents one named notification channel (e.g. `onResize`, `onFrame`). Listeners are added with Signal.add or S…<[InteractionEventDOM-Event-shaped envelope dispatched by InteractionSystem to interactive scene nodes. Bubbles up the *entire* parent chain - `target` stays pinned to the hit-d…]>