UNPKG

@lightningjs/renderer

Version:
737 lines (736 loc) 23.2 kB
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; }