import { Observable, ReplaySubject } from 'rxjs'; import { GLclampf2, GLsizei2 } from './tuples'; import { Color } from './color'; import { Context } from './context'; import { Controller } from './controller'; import { EyeGazeDataStreams } from './eyegazedatastream'; import { EyeGazeEventProvider } from './eyegazeeventprovider'; import { MouseEventProvider } from './mouseeventprovider'; import { PointerEventProvider } from './pointereventprovider'; import { Renderer } from './renderer'; import { Resizable } from './resizable'; import { TouchEventProvider } from './toucheventprovider'; import { KeyboardEventProvider } from './keyboardeventprovider'; import { Wizard } from './wizard'; /** * A canvas is associated to a single canvas element (DOM) and integrates or delegates event handling as well as * control over the rendering loop and the attached renderer respectively. Furthermore, the canvas can bind a single * renderer (non owning) and sets up communication between controller, renderer, and navigation. The controller invokes * the renderer's update, frame, and swap methods. The navigation manipulates the renderer's camera. The renderer can * invalidate itself which causes a controller update. * * Note: Since only the multi-frame number is used by the renderer and the controller, the canvas provides getter, * setter, and change callback setter. Debug-frame and frame number are managed exclusively by the controller. * * Note: the canvas should hold any properties that are required to be passed onto a newly bound renderer (in the case * multiple renderer are used with a canvas). The clear color is one example of such a property. */ export declare class Canvas extends Resizable { /** * Default color that is used if none is set via data attributes. */ protected static readonly DEFAULT_CLEAR_COLOR: Color; /** * Default frame precision, e.g., accumulation format when multi-frame rendering is used. */ protected static readonly DEFAULT_FRAME_PRECISION: Wizard.Precision; /** * Default multi-frame number used if none is set via data attributes. */ protected static readonly DEFAULT_MULTI_FRAME_NUMBER = 0; /** @see {@link context} */ protected _context: Context; /** @see {@link controller} */ protected _controller: Controller; /** @see {@link renderer} */ protected _renderer: Renderer | undefined; /** @see {@link clearColor} */ protected _clearColor: Color; /** * @see {@link framePrecision} * This property can be observed, e.g., `aCanvas.framePrecisionObservable.subscribe()`. */ protected _framePrecision: Wizard.Precision; protected _framePrecisionSubject: ReplaySubject; /** * @see {@link size} * This property can be observed, e.g., `aCanvas.sizeObservable.subscribe()`. * Zero-initialization prevents drawing on an invalid canvas size, i.e., a canvas size [1, 1] is technically valid * for rendering, which might lead to rendering on an [1, 1] canvas before the first 'real' size is set (e.g., via * resize event), resulting in visually unpleasant initial frames in some (slow) applications. */ protected _size: GLsizei2; protected _sizeSubject: ReplaySubject; /** * @see {@link frameScale} * This property can be observed, `aCanvas.frameScaleObservable.subscribe()`. */ protected _frameScale: GLclampf2; protected _frameScaleSubject: ReplaySubject; /** * @see {@link frameSize} * This property can be observed, `aCanvas.frameSizeObservable.subscribe()`. */ protected _frameSize: GLsizei2; protected _frameSizeSubject: ReplaySubject; /** * Flag used to determine whether frame size or frame scale is the dominant configuration. */ protected _favorSizeOverScale: boolean; /** @see {@link element} */ protected _element: HTMLCanvasElement; /** @see {@link mouseEventProvider} */ protected _mouseEventProvider: MouseEventProvider; /** @see {@link touchEventProvider} */ protected _touchEventProvider: TouchEventProvider; /** @see {@link pointerEventProvider} */ protected _pointerEventProvider: PointerEventProvider; /** @see {@link eyeGazeEventProvider} */ protected _eyeGazeEventProvider: EyeGazeEventProvider; /** @see {@link keyboardEventProvider} */ protected _keyboardEventProvider: KeyboardEventProvider; protected _lostContextExtension: WEBGL_lose_context | undefined; /** * Create and initialize a multi-frame controller, setup a default multi-frame number and get the canvas's webgl * context as well as the canvas resolution. The context and resolution will be passed on to the set renderer and * its stages/passes appropriately. The canvas does not provide lazy initialization and is strictly bound to a * single canvas element (DOM) that cannot be changed. * * Note: the multi-frame number can be set using a data attribute in the canvas element called * 'data-multi-frame-number'. * * The canvas supports the following data attributes: * - data-multi-frame-number {number} - integer greater than 0 * - data-clear-color {Color} - rgba color for clearing * - data-frame-scale {GLclampf2} - width and height frame scale in [0.0,1.0] * - data-frame-size {GLizei2} - width and height frame size in pixel * - data-frame-precision {RenderPrecision} - precision for, e.g., frame accumulation * , either 'float', 'half', 'byte', or 'auto'. * * Note: data-frame-size takes precedence if both frame-scale and frame-size data attributes are provided. * @param element - Canvas element or element id {string} to be used for querying the canvas element. * @param attributes - Overrides the internal default attributes @see{Context.DEFAULT_ATTRIBUTES}. */ constructor(element: HTMLCanvasElement | string, attributes?: WebGLContextAttributes); /** * Creates and initializes a new controller that is used for this canvas. If provided via data attributes * multi-frame number and debug-frame number are set. * @param dataset - The attributes data-multi-frame-number and data-debug-frame-number are supported. */ protected configureController(dataset: DOMStringMap): void; /** * Initializes the frame size and scale. By default, the scale is 1.0 for width and height and the size reflects * the native canvas size. * @param dataset - The attributes data-frame-size and data-frame-scale are supported. */ protected configureSizeAndScale(dataset: DOMStringMap): void; /** * Register 'webglcontextlost' and 'webglcontextrestored' to handle lost and restoration * of WebGL contexts. */ protected configureContextLostAndRestore(): void; /** * Obtain the WEBGL_lose_context extension, store it with this canvas instance and use it * for emulation of the context lost and restore feature. */ protected configureContextLostAndRestoreEmulation(): void; /** * Handle a WebGL context lost event. * This is for both natural and emulated lost contexts. */ protected onContextLost(): void; /** * Handle a WebGL context restore event. * This is for both natural and emulated restored contexts. */ protected onContextRestore(): void; /** * Convenience function that triggers the canvas size retrieval. The native width and height of the canvas dom * element is cached (in pixel). */ protected retrieveSize(): void; /** * Resize is invoked by the resizable mixin. It retrieves the canvas size and promotes it to the renderer. */ protected onResize(): void; /** * Utility for communicating this._framePrecision changes to its associated subject. */ protected framePrecisionNext(): void; /** * Utility for communicating this._size changes to its associated subject. */ protected sizeNext(): void; /** * Utility for communicating this._frameScale changes to its associated subject. */ protected frameScaleNext(): void; /** * Utility for communicating this._frameSize changes to its associated subject. */ protected frameSizeNext(): void; /** * The renderer (if not undefined) will be connected to the controller and navigation. The controller will * immediately trigger a multi-frame, thereby causing the renderer to render frames. * * Note that no renderer should be bound to multiple canvases * simultaneously. The reference is non owning. * * @param renderer - Either undefined or an uninitialized renderer. */ protected bind(renderer: Renderer | undefined): void; /** * Unbinds the current renderer from the canvas as well as the controller and navigation, and uninitializes the * renderer. */ protected unbind(): void; /** * Uninitializes and deletes the controller as well as all other properties. */ dispose(): void; /** * Allows for explicit trigger of onResize, e.g., in case resize event-handling is managed explicitly ... */ resize(): void; /** * Single controller that is managing the rendering control flow of a bound renderer. * @returns - The controller used by the canvas. */ get controller(): Controller; /** * The currently bound renderer. If no renderer is bound, undefined is returned. If a renderer is bound, it should * always be initialized (renderer initialization handled by the canvas). * @returns - The currently bound renderer. */ get renderer(): Renderer | undefined; /** * Binds a renderer to the canvas. A previously bound renderer will be unbound (see bind and unbind). * @param renderer - A renderer object or undefined. */ set renderer(renderer: Renderer | undefined); /** * Targeted scale for rendering with respect to the canvas size. This property can be observed, e.g., * `canvas.frameScaleObservable.subscribe()`. * @returns - The frame scale in [0.0, 1.0]. */ get frameScale(): GLclampf2; /** * Set the targeted scale for rendering with respect to the canvas size. The scale will be clamped to [0.0,1.0]. A * scale of 0.0 results in 1px frame resolution for the respective component. * The frame scale allows to detach the rendering resolution from the native canvas resolution, e.g., in order to * decrease rendering cost. The frame resolution can also be specified explicitly by width and height. Non-finite * values will be ignored. * @param frameScale - Scale of rendering. * @returns - The frame scale in [0.0,1.0]. */ set frameScale(frameScale: GLclampf2); /** * Observable that can be used to subscribe to frame scale changes. */ get frameScale$(): Observable; /** * Targeted resolution (width and height) for rendering in pixel. This property can be observed, e.g., * `canvas.frameSizeObservable.subscribe()`. * @returns - The frame size in pixel (must not be physical/native pixels). */ get frameSize(): GLsizei2; /** * Set the targeted size for rendering in pixels. The size will be clamped to [1, canvas-size]. The frame size * allows to detach the rendering resolution from the native canvas resolution, e.g., in order to decrease * rendering cost. Non-finite values will be ignored. * The render resolution can also be specified implicitly by width and height in scale (@see frameScale). * @param frameSize - Size for rendering in pixel (must not be physical/native pixels). * @returns - The frame size in [1, canvas-size]. */ set frameSize(frameSize: GLsizei2); /** * Observable that can be used to subscribe to frame size changes. */ get frameSize$(): Observable; /** * Getter for the canvas's clear color. The clear color is provided to the renderer (on bind). Since this is a * canvas specific setting it is stored here, not in a renderer or controller. * @returns - Color object passed to any renderer bound to this canvas. */ get clearColor(): Color; /** * Sets the clear color that is then passed to the currently bound renderer as well as to any pipelines bound in * the future. The provided color will be clamped to [0.0;1.0] for every component. * @param clearColor - Color object that will be referenced. */ set clearColor(clearColor: Color); /** * Getter for the targeted frame precision. This property can be observed, e.g., * `canvas.framePrecisionObservable.subscribe()`. * @returns - Accumulation format as string passed to any renderer bound. */ get framePrecision(): Wizard.Precision; /** * Sets the targeted frame precision that is then passed to the currently bound renderer as well as to any renderers * bound in the future. This might be used for frame accumulation in multi-frame based rendering. * @param precision - Frame precision, 'float', 'half', 'byte' or 'auto' are supported. */ set framePrecision(precision: Wizard.Precision); /** * Observable that can be used to subscribe to frame precision changes. */ get framePrecision$(): Observable; /** * Provides access to the WebGL context (leaky abstraction). */ get context(): Context; /** * Getter for the created rendering backend (webgl context type). * @returns - Backend that was created on construction, either 'webgl' or 'webgl2' based on which one was created * successfully. If no context could be created undefined is returned. */ get backend(): string; /** * Size of the canvas measured in physical/native screen pixels. This is the 'managed' canvas width and height. The * unmanaged canvas width and height are available via context.gl.canvas.width and context.gl.canvas.height (which * should always be the same). * This property can be observed, e.g., `allocationRegister.bytesObservable.subscribe()`. * @returns - The canvas width and height in physical/native screen pixels as 2-tuple. */ get size(): GLsizei2; /** * Observable that can be used to subscribe to canvas size changes. */ get size$(): Observable; /** * Width of the canvas measured in physical/native screen pixels. This is the 'managed' canvas width. The * unmanaged canvas width is available via context.gl.canvas_width (which should always be the same). * @returns - The canvas width in physical/native screen pixels. */ get width(): GLsizei; /** * Height of the canvas measured in physical/native screen pixels. This is the 'managed' canvas height. The * unmanaged canvas height is available via context.gl.canvas_height (which should always be the same). * @returns - The canvas height in physical/native screen pixels. */ get height(): GLsizei; /** * Canvas element within the HTML5 document. */ get element(): HTMLElement; /** * Canvas mouse event provider referring to the canvas element. */ get mouseEventProvider(): MouseEventProvider; /** * Canvas touch event provider referring to the canvas element. */ get touchEventProvider(): TouchEventProvider; get keyboardEventProvider(): KeyboardEventProvider; /** * Emulate a WebGL context loss. * This functionality requires to have configureContextLostAndRestoreEmulation() called before. * This function is usually called within the constructor of this canvas. */ testLoseContext(): void; /** * Emulate a WebGL context restore. * This functionality requires to have configureContextLostAndRestoreEmulation() called before. * This function is usually called within the constructor of this canvas. */ testRestoreContext(): void; /** * Eye gaze event provider referring to the canvas element. */ get eyeGazeEventProvider(): EyeGazeEventProvider; /** * Activates the eye gaze event provider referring to the canvas element. */ activateEyeGazeEventProvider(eyeGazeDataStreams: EyeGazeDataStreams, serverAddress: string): void; }