@lightningjs/renderer
Version:
Lightning 3 Renderer
737 lines (736 loc) • 23.2 kB
TypeScript
import type { ShaderMap } from './CoreShaderManager.js';
import type { ExtractProps, TextureOptions } from './CoreTextureManager.js';
import type { CoreRenderer } from './renderers/CoreRenderer.js';
import type { CoreShader } from './renderers/CoreShader.js';
import type { Stage } from './Stage.js';
import type { Texture } from './textures/Texture.js';
import type { Dimensions } from '../common/CommonTypes.js';
import { EventEmitter } from '../common/EventEmitter.js';
import { type Bound, type RectWithValid } from './lib/utils.js';
import { Matrix3d } from './lib/Matrix3d.js';
import { RenderCoords } from './lib/RenderCoords.js';
import type { AnimationSettings } from './animations/CoreAnimation.js';
import type { IAnimationController } from '../common/IAnimationController.js';
import type { ShaderRef } from '../main-api/Renderer.js';
export declare enum LngNodeRenderState {
Init = 0,
OutOfBounds = 2,
InBounds = 4,
InViewport = 8
}
export declare enum UpdateType {
/**
* Child updates
*/
Children = 1,
/**
* Scale/Rotate transform update
*
* @remarks
* LngNode Properties Updated:
* - `scaleRotateTransform`
*/
ScaleRotate = 2,
/**
* Translate transform update (x/y/width/height/pivot/mount)
*
* @remarks
* LngNode Properties Updated:
* - `localTransform`
*/
Local = 4,
/**
* Global Transform update
*
* @remarks
* LngNode Properties Updated:
* - `globalTransform`
* - `renderCoords`
* - `renderBound`
*/
Global = 8,
/**
* Clipping rect update
*
* @remarks
* LngNode Properties Updated:
* - `clippingRect`
*/
Clipping = 16,
/**
* Calculated ZIndex update
*
* @remarks
* LngNode Properties Updated:
* - `calcZIndex`
*/
CalculatedZIndex = 32,
/**
* Z-Index Sorted Children update
*
* @remarks
* LngNode Properties Updated:
* - `children` (sorts children by their `calcZIndex`)
*/
ZIndexSortedChildren = 64,
/**
* Premultiplied Colors update
*
* @remarks
* LngNode Properties Updated:
* - `premultipliedColorTl`
* - `premultipliedColorTr`
* - `premultipliedColorBl`
* - `premultipliedColorBr`
*/
PremultipliedColors = 128,
/**
* World Alpha update
*
* @remarks
* LngNode Properties Updated:
* - `worldAlpha` = `parent.worldAlpha` * `alpha`
*/
WorldAlpha = 256,
/**
* Render State update
*
* @remarks
* LngNode Properties Updated:
* - `renderState`
*/
RenderState = 512,
/**
* Is Renderable update
*
* @remarks
* LngNode Properties Updated:
* - `isRenderable`
*/
IsRenderable = 1024,
/**
* Render Texture update
*/
RenderTexture = 2048,
/**
* Track if parent has render texture
*/
ParentRenderTexture = 4096,
/**
* None
*/
None = 0,
/**
* All
*/
All = 8191
}
/**
* A custom data map which can be stored on an LngNode
*
* @remarks
* This is a map of key-value pairs that can be stored on an INode. It is used
* to store custom data that can be used by the application.
* The data stored can only be of type string, number or boolean.
*/
export type CustomDataMap = {
[key: string]: string | number | boolean | undefined;
};
/**
* Writable properties of a Node.
*/
export interface LngNodeWritableProps {
/**
* The x coordinate of the Node's Mount Point.
*
* @remarks
* See {@link mountX} and {@link mountY} for more information about setting
* the Mount Point.
*
* @default `0`
*/
x: number;
/**
* The y coordinate of the Node's Mount Point.
*
* @remarks
* See {@link mountX} and {@link mountY} for more information about setting
* the Mount Point.
*
* @default `0`
*/
y: number;
/**
* The width of the Node.
*
* @default `0`
*/
width: number;
/**
* The height of the Node.
*
* @default `0`
*/
height: number;
/**
* The alpha opacity of the Node.
*
* @remarks
* The alpha value is a number between 0 and 1, where 0 is fully transparent
* and 1 is fully opaque.
*
* @default `1`
*/
alpha: number;
/**
* Autosize mode
*
* @remarks
* When enabled, when a texture is loaded into the Node, the Node will
* automatically resize to the dimensions of the texture.
*
* Text Nodes are always autosized based on their text content regardless
* of this mode setting.
*
* @default `false`
*/
autosize: boolean;
/**
* Clipping Mode
*
* @remarks
* Enable Clipping Mode when you want to prevent the drawing of a Node and
* its descendants from overflowing outside of the Node's x/y/width/height
* bounds.
*
* For WebGL, clipping is implemented using the high-performance WebGL
* operation scissor. As a consequence, clipping does not work for
* non-rectangular areas. So, if the element is rotated
* (by itself or by any of its ancestors), clipping will not work as intended.
*
* TODO: Add support for non-rectangular clipping either automatically or
* via Render-To-Texture.
*
* @default `false`
*/
clipping: boolean;
/**
* The color of the Node.
*
* @remarks
* The color value is a number in the format 0xRRGGBBAA, where RR is the red
* component, GG is the green component, BB is the blue component, and AA is
* the alpha component.
*
* Gradient colors may be set by setting the different color sub-properties:
* {@link colorTop}, {@link colorBottom}, {@link colorLeft}, {@link colorRight},
* {@link colorTl}, {@link colorTr}, {@link colorBr}, {@link colorBl} accordingly.
*
* @default `0xffffffff` (opaque white)
*/
color: number;
/**
* The color of the top edge of the Node for gradient rendering.
*
* @remarks
* See {@link color} for more information about color values and gradient
* rendering.
*/
colorTop: number;
/**
* The color of the bottom edge of the Node for gradient rendering.
*
* @remarks
* See {@link color} for more information about color values and gradient
* rendering.
*/
colorBottom: number;
/**
* The color of the left edge of the Node for gradient rendering.
*
* @remarks
* See {@link color} for more information about color values and gradient
* rendering.
*/
colorLeft: number;
/**
* The color of the right edge of the Node for gradient rendering.
*
* @remarks
* See {@link color} for more information about color values and gradient
* rendering.
*/
colorRight: number;
/**
* The color of the top-left corner of the Node for gradient rendering.
*
* @remarks
* See {@link color} for more information about color values and gradient
* rendering.
*/
colorTl: number;
/**
* The color of the top-right corner of the Node for gradient rendering.
*
* @remarks
* See {@link color} for more information about color values and gradient
* rendering.
*/
colorTr: number;
/**
* The color of the bottom-right corner of the Node for gradient rendering.
*
* @remarks
* See {@link color} for more information about color values and gradient
* rendering.
*/
colorBr: number;
/**
* The color of the bottom-left corner of the Node for gradient rendering.
*
* @remarks
* See {@link color} for more information about color values and gradient
* rendering.
*/
colorBl: number;
/**
* The Node's parent Node.
*
* @remarks
* The value `null` indicates that the Node has no parent. This may either be
* because the Node is the root Node of the scene graph, or because the Node
* has been removed from the scene graph.
*
* In order to make sure that a Node can be rendered on the screen, it must
* be added to the scene graph by setting it's parent property to a Node that
* is already in the scene graph such as the root Node.
*
* @default `null`
*/
parent: LngNode | null;
/**
* The Node's z-index.
*
* @remarks
* TBD
*/
zIndex: number;
/**
* The Node's Texture.
*
* @remarks
* The `texture` defines a rasterized image that is contained within the
* {@link width} and {@link height} dimensions of the Node. If null, the
* Node will use an opaque white {@link ColorTexture} when being drawn, which
* essentially enables colors (including gradients) to be drawn.
*
* If set, by default, the texture will be drawn, as is, stretched to the
* dimensions of the Node. This behavior can be modified by setting the TBD
* and TBD properties.
*
* To create a Texture in order to set it on this property, call
* {@link RendererMain.createTexture}.
*
* If the {@link src} is set on a Node, the Node will use the
* {@link ImageTexture} by default and the Node will simply load the image at
* the specified URL.
*
* Note: If this is a Text Node, the Texture will be managed by the Node's
* {@link TextRenderer} and should not be set explicitly.
*/
texture: Texture | null;
/**
* Options to associate with the Node's Texture
*/
textureOptions: TextureOptions;
/**
* The Node's shader
*
* @remarks
* The `shader` defines a {@link Shader} used to draw the Node. By default,
* the Default Shader is used which simply draws the defined {@link texture}
* or {@link color}(s) within the Node without any special effects.
*
* To create a Shader in order to set it on this property, call
* {@link RendererMain.createShader}.
*
* Note: If this is a Text Node, the Shader will be managed by the Node's
* {@link TextRenderer} and should not be set explicitly.
*/
shader: ShaderRef | null;
/**
* Shader properties
*/
shaderProps: Record<string, unknown> | null;
/**
* Image URL
*
* @remarks
* When set, the Node's {@link texture} is automatically set to an
* {@link ImageTexture} using the source image URL provided (with all other
* settings being defaults)
*/
src: string | null;
zIndexLocked: number;
/**
* Scale to render the Node at
*
* @remarks
* The scale value multiplies the provided {@link width} and {@link height}
* of the Node around the Node's Pivot Point (defined by the {@link pivot}
* props).
*
* Behind the scenes, setting this property sets both the {@link scaleX} and
* {@link scaleY} props to the same value.
*
* NOTE: When the scaleX and scaleY props are explicitly set to different values,
* this property returns `null`. Setting `null` on this property will have no
* effect.
*
* @default 1.0
*/
scale: number | null;
/**
* Scale to render the Node at (X-Axis)
*
* @remarks
* The scaleX value multiplies the provided {@link width} of the Node around
* the Node's Pivot Point (defined by the {@link pivot} props).
*
* @default 1.0
*/
scaleX: number;
/**
* Scale to render the Node at (Y-Axis)
*
* @remarks
* The scaleY value multiplies the provided {@link height} of the Node around
* the Node's Pivot Point (defined by the {@link pivot} props).
*
* @default 1.0
*/
scaleY: number;
/**
* Combined position of the Node's Mount Point
*
* @remarks
* The value can be any number between `0.0` and `1.0`:
* - `0.0` defines the Mount Point at the top-left corner of the Node.
* - `0.5` defines it at the center of the Node.
* - `1.0` defines it at the bottom-right corner of the node.
*
* Use the {@link mountX} and {@link mountY} props seperately for more control
* of the Mount Point.
*
* When assigned, the same value is also passed to both the {@link mountX} and
* {@link mountY} props.
*
* @default 0 (top-left)
*/
mount: number;
/**
* X position of the Node's Mount Point
*
* @remarks
* The value can be any number between `0.0` and `1.0`:
* - `0.0` defines the Mount Point's X position as the left-most edge of the
* Node
* - `0.5` defines it as the horizontal center of the Node
* - `1.0` defines it as the right-most edge of the Node.
*
* The combination of {@link mountX} and {@link mountY} define the Mount Point
*
* @default 0 (left-most edge)
*/
mountX: number;
/**
* Y position of the Node's Mount Point
*
* @remarks
* The value can be any number between `0.0` and `1.0`:
* - `0.0` defines the Mount Point's Y position as the top-most edge of the
* Node
* - `0.5` defines it as the vertical center of the Node
* - `1.0` defines it as the bottom-most edge of the Node.
*
* The combination of {@link mountX} and {@link mountY} define the Mount Point
*
* @default 0 (top-most edge)
*/
mountY: number;
/**
* Combined position of the Node's Pivot Point
*
* @remarks
* The value can be any number between `0.0` and `1.0`:
* - `0.0` defines the Pivot Point at the top-left corner of the Node.
* - `0.5` defines it at the center of the Node.
* - `1.0` defines it at the bottom-right corner of the node.
*
* Use the {@link pivotX} and {@link pivotY} props seperately for more control
* of the Pivot Point.
*
* When assigned, the same value is also passed to both the {@link pivotX} and
* {@link pivotY} props.
*
* @default 0.5 (center)
*/
pivot: number;
/**
* X position of the Node's Pivot Point
*
* @remarks
* The value can be any number between `0.0` and `1.0`:
* - `0.0` defines the Pivot Point's X position as the left-most edge of the
* Node
* - `0.5` defines it as the horizontal center of the Node
* - `1.0` defines it as the right-most edge of the Node.
*
* The combination of {@link pivotX} and {@link pivotY} define the Pivot Point
*
* @default 0.5 (centered on x-axis)
*/
pivotX: number;
/**
* Y position of the Node's Pivot Point
*
* @remarks
* The value can be any number between `0.0` and `1.0`:
* - `0.0` defines the Pivot Point's Y position as the top-most edge of the
* Node
* - `0.5` defines it as the vertical center of the Node
* - `1.0` defines it as the bottom-most edge of the Node.
*
* The combination of {@link pivotX} and {@link pivotY} define the Pivot Point
*
* @default 0.5 (centered on y-axis)
*/
pivotY: number;
/**
* Rotation of the Node (in Radians)
*
* @remarks
* Sets the amount to rotate the Node by around it's Pivot Point (defined by
* the {@link pivot} props). Positive values rotate the Node clockwise, while
* negative values rotate it counter-clockwise.
*
* Example values:
* - `-Math.PI / 2`: 90 degree rotation counter-clockwise
* - `0`: No rotation
* - `Math.PI / 2`: 90 degree rotation clockwise
* - `Math.PI`: 180 degree rotation clockwise
* - `3 * Math.PI / 2`: 270 degree rotation clockwise
* - `2 * Math.PI`: 360 rotation clockwise
*/
rotation: number;
/**
* Whether the Node is rendered to a texture
*
* @remarks
* TBD
*
* @default false
*/
rtt: boolean;
/**
* Node data element for custom data storage (optional)
*
* @remarks
* This property is used to store custom data on the Node as a key/value data store.
* Data values are limited to string, numbers, booleans. Strings will be truncated
* to a 2048 character limit for performance reasons.
*
* This is not a data storage mechanism for large amounts of data please use a
* dedicated data storage mechanism for that.
*
* The custom data will be reflected in the inspector as part of `data-*` attributes
*
* @default `undefined`
*/
data?: CustomDataMap;
}
/**
* Animatable properties of a Node
*/
export type LngNodeAnimatableProps = {
[Key in keyof LngNodeWritableProps as NonNullable<LngNodeWritableProps[Key]> extends number ? Key : never]: number;
};
/**
* A visual Node in the Renderer scene graph.
*
* @remarks
* A Node is a basic building block of the Renderer scene graph. It can be a
* container for other Nodes, or it can be a leaf Node that renders a solid
* color, gradient, image, or specific texture, using a specific shader.
*
* For text rendering, see {@link TextNode}.
*
* This is named `LngNode` because the browser already defines a `Node` class.
*/
export declare class LngNode extends EventEmitter {
protected stage: Stage;
readonly children: LngNode[];
protected _id: number;
protected props: Required<LngNodeWritableProps>;
updateType: UpdateType;
globalTransform?: Matrix3d;
scaleRotateTransform?: Matrix3d;
localTransform?: Matrix3d;
renderCoords?: RenderCoords;
renderBound?: Bound;
strictBound?: Bound;
preloadBound?: Bound;
clippingRect: RectWithValid;
isRenderable: boolean;
renderState: LngNodeRenderState;
worldAlpha: number;
premultipliedColorTl: number;
premultipliedColorTr: number;
premultipliedColorBl: number;
premultipliedColorBr: number;
calcZIndex: number;
hasRTTupdates: boolean;
parentHasRenderTexture: boolean;
_shader: CoreShader | null;
_src: string;
constructor(stage: Stage, props: LngNodeWritableProps);
loadTexture(): void;
unloadTexture(): void;
autosizeNode(dimensions: Dimensions): void;
private onTextureLoaded;
private onTextureFailed;
private onTextureFreed;
loadShader<Type extends keyof ShaderMap>(shaderType: Type, props: ExtractProps<ShaderMap[Type]>): void;
/**
* Change types types is used to determine the scope of the changes being applied
*
* @remarks
* See {@link UpdateType} for more information on each type
*
* @param type
*/
setUpdateType(type: UpdateType): void;
sortChildren(): void;
updateScaleRotateTransform(): void;
updateLocalTransform(): void;
/**
* @todo: test for correct calculation flag
* @param delta
*/
update(delta: number, parentClippingRect: RectWithValid): void;
checkRenderProps(): boolean;
checkRenderBounds(parentClippingRect: RectWithValid): LngNodeRenderState;
updateRenderState(parentClippingRect: RectWithValid): void;
setRenderState(state: LngNodeRenderState): void;
/**
* This function updates the `isRenderable` property based on certain conditions.
*
* @returns
*/
updateIsRenderable(): void;
onChangeIsRenderable(isRenderable: boolean): void;
calculateRenderCoords(): void;
updateBoundingRect(): void;
/**
* This function calculates the clipping rectangle for a node.
*
* The function then checks if the node is rotated. If the node requires clipping and is not rotated, a new clipping rectangle is created based on the node's global transform and dimensions.
* If a parent clipping rectangle exists, it is intersected with the node's clipping rectangle (if it exists), or replaces the node's clipping rectangle.
*
* Finally, the node's parentClippingRect and clippingRect properties are updated.
*/
calculateClippingRect(parentClippingRect: RectWithValid): void;
calculateZIndex(): void;
/**
* Destroy the node and cleanup all resources
*/
destroy(): void;
renderQuads(renderer: CoreRenderer): void;
get id(): number;
get x(): number;
set x(value: number);
get absX(): number;
get absY(): number;
get y(): number;
set y(value: number);
get width(): number;
set width(value: number);
get height(): number;
set height(value: number);
get scale(): number;
set scale(value: number);
get scaleX(): number;
set scaleX(value: number);
get scaleY(): number;
set scaleY(value: number);
get mount(): number;
set mount(value: number);
get mountX(): number;
set mountX(value: number);
get mountY(): number;
set mountY(value: number);
get pivot(): number;
set pivot(value: number);
get pivotX(): number;
set pivotX(value: number);
get pivotY(): number;
set pivotY(value: number);
get rotation(): number;
set rotation(value: number);
get alpha(): number;
set alpha(value: number);
get autosize(): boolean;
set autosize(value: boolean);
get clipping(): boolean;
set clipping(value: boolean);
get color(): number;
set color(value: number);
get colorTop(): number;
set colorTop(value: number);
get colorBottom(): number;
set colorBottom(value: number);
get colorLeft(): number;
set colorLeft(value: number);
get colorRight(): number;
set colorRight(value: number);
get colorTl(): number;
set colorTl(value: number);
get colorTr(): number;
set colorTr(value: number);
get colorBl(): number;
set colorBl(value: number);
get colorBr(): number;
set colorBr(value: number);
get zIndexLocked(): number;
set zIndexLocked(value: number);
get zIndex(): number;
set zIndex(value: number);
get parent(): LngNode | null;
set parent(newParent: LngNode | null);
get rtt(): boolean;
set rtt(value: boolean);
get shader(): ShaderRef | null;
set shader(value: ShaderRef | null);
get shaderProps(): Record<string, unknown> | null;
set shaderProps(value: Record<string, unknown> | null);
get src(): string;
set src(imageUrl: string);
/**
* Returns the framebuffer dimensions of the node.
* If the node has a render texture, the dimensions are the same as the node's dimensions.
* If the node does not have a render texture, the dimensions are inherited from the parent.
* If the node parent has a render texture and the node is a render texture, the nodes dimensions are used.
*/
get framebufferDimensions(): Dimensions;
/**
* Returns the parent render texture node if it exists.
*/
get parentRenderTexture(): LngNode | null;
get texture(): Texture | null;
set texture(value: Texture | null);
set textureOptions(value: TextureOptions);
get textureOptions(): TextureOptions;
setRTTUpdates(type: number): void;
animate(props: Partial<LngNodeAnimatableProps>, settings: Partial<AnimationSettings>): IAnimationController;
flush(): void;
}