import * as gl_matrix from 'gl-matrix'; import { vec2, mat4, vec3, quat, vec4 } from 'gl-matrix'; import * as zarr from 'zarrita'; import { Location, Readable } from 'zarrita'; import { z } from 'zod'; declare abstract class Node { readonly id: string; abstract get type(): string; } type TextureFilter = "nearest" | "linear"; type TextureWrapMode = "repeat" | "clamp_to_edge"; type TextureDataFormat = "scalar" | "rgb" | "rgba"; type TextureDataType = "byte" | "short" | "int" | "unsigned_byte" | "unsigned_short" | "unsigned_int" | "float"; type TextureUnpackRowAlignment = 1 | 2 | 4 | 8; type DataTextureTypedArray = Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Float32Array; declare abstract class Texture extends Node { dataFormat: TextureDataFormat; dataType: TextureDataType; maxFilter: TextureFilter; minFilter: TextureFilter; mipmapLevels: number; unpackAlignment: TextureUnpackRowAlignment; wrapR: TextureWrapMode; wrapS: TextureWrapMode; wrapT: TextureWrapMode; needsUpdate: boolean; readTexel?: (x: number, y: number, z: number) => Promise; protected data_: DataTextureTypedArray | null; get data(): DataTextureTypedArray | null; set data(data: DataTextureTypedArray); releaseCpuData(): void; abstract get width(): number; abstract get height(): number; get depth(): number; get type(): string; } type SpatialAxis = "x" | "y" | "z"; type SliceAxes = { u: SpatialAxis; v: SpatialAxis; w: SpatialAxis; }; /** * The plane a 2D slice lies on, named by its in-plane axes. */ type SliceOrientation = "XY" | "XZ" | "YZ"; declare const chunkDataTypes: readonly [Int8ArrayConstructor, Int16ArrayConstructor, Int32ArrayConstructor, Uint8ArrayConstructor, Uint16ArrayConstructor, Uint32ArrayConstructor, Float32ArrayConstructor]; type ChunkDataConstructor = (typeof chunkDataTypes)[number]; type ChunkData = InstanceType; type ChunkViewState = { visible: boolean; prefetch: boolean; priority: number | null; orderKey: number | null; }; type Chunk = { data?: ChunkData; texture?: Texture; releasedAt?: DOMHighResTimeStamp; state: "unloaded" | "queued" | "loading" | "loaded"; lod: number; shape: { x: number; y: number; z: number; c: number; }; rowAlignmentBytes: TextureUnpackRowAlignment; chunkIndex: { x: number; y: number; z: number; c: number; t: number; }; scale: { x: number; y: number; z: number; }; offset: { x: number; y: number; z: number; }; } & ChunkViewState; /** * Per-axis dimension metadata for a multiscale image source. * * Maps the spatial axes `x`, `y`, `z` and the non-spatial axes `c` and * `t` onto the source's stored dimensions. */ type SourceDimensionMap = { /** The `x` spatial dimension. */ x: SourceDimension; /** The `y` spatial dimension. */ y: SourceDimension; /** The `z` spatial dimension if present. */ z?: SourceDimension; /** The channel dimension if present. */ c?: SourceDimension; /** The time dimension if present. */ t?: SourceDimension; /** Number of levels of detail in the pyramid. */ numLods: number; }; /** * One dimension of a multiscale image source. */ type SourceDimension = { /** Axis name from the source metadata. */ name: string; /** Position of the axis in the stored arrays. */ index: number; /** Physical unit if declared in the metadata. */ unit?: string; /** Per-LOD metadata ordered finest first. */ lods: SourceDimensionLod[]; }; /** * Metadata for one dimension at one level of detail. * * Combines array metadata with the OME-Zarr coordinate transform. */ type SourceDimensionLod = { /** Extent of the dimension in array elements. */ size: number; /** Chunk extent along the dimension in elements. */ chunkSize: number; /** World units per array element. */ scale: number; /** World coordinate of the first element. */ translation: number; }; /** * World-space coordinates selecting the data to display. */ type SliceCoordinates = { /** Position on the `x` axis in world units. */ x?: number; /** Position on the `y` axis in world units. */ y?: number; /** Position on the `z` axis in world units. */ z?: number; /** Channel indices to load. Defaults to all channels. */ c?: number[]; /** The time point to display. */ t?: number; }; type ChunkSource = { get loader(): ChunkLoader; }; type ChunkLoader = { getSourceDimensionMap(): SourceDimensionMap; getBytesPerElement(): number; loadChunkData(chunk: Chunk, signal: AbortSignal): Promise; }; /** * A category of chunk request ordered by a loading policy. */ type PriorityCategory = "fallbackVisible" | "prefetchTime" | "visibleCurrent" | "fallbackBackground" | "prefetchSpace"; /** * @hidden */ type ImageSourcePolicyProps = { profile?: string; prefetch: { x: number; y: number; z?: number; t?: number; }; priorityOrder: PriorityCategory[]; lod?: { min?: number; max?: number; bias?: number; }; }; /** * A resolved and frozen loading policy consumed by layers. * * Create instances with {@link createExplorationPolicy}, * {@link createPlaybackPolicy}, {@link createNoPrefetchPolicy}, or * {@link createImageSourcePolicy} rather than by hand. */ type ImageSourcePolicy = Readonly<{ profile: string; prefetch: { x: number; y: number; z: number; t: number; }; priorityOrder: readonly PriorityCategory[]; priorityMap: Readonly>; lod: { min: number; max: number; bias: number; }; }>; /** * Creates a loading policy tuned for interactively browsing a scene. * * Prefetches one chunk beyond the view along each spatial axis and * fills the visible region before prefetching. This is the default * policy for layers constructed without one. * * @param overrides - Properties merged over. */ declare function createExplorationPolicy(overrides?: Partial): ImageSourcePolicy; /** * Creates a loading policy tuned for playing through timepoints. * * Prefetches twenty timepoints ahead, buffering at the current LOD * for smooth playback without reduced quality. * * @param overrides - Properties merged over. */ declare function createPlaybackPolicy(overrides?: Partial): ImageSourcePolicy; /** * Creates a loading policy with spatial and temporal prefetching disabled. * * No spatial or temporal prefetching happens, which minimizes memory * use and network traffic for static scenes. * * @param overrides - Properties merged over. */ declare function createNoPrefetchPolicy(overrides?: Partial): ImageSourcePolicy; /** * Creates a loading policy from explicit properties, validating and * freezing them. Prefer the profile factories for common cases and use * this to build a policy from scratch. * * @param config - Initialization properties. */ declare function createImageSourcePolicy(config: ImageSourcePolicyProps): ImageSourcePolicy; declare class ChunkStore { private readonly chunks_; private readonly lowestResLOD_; private readonly dimensions_; private readonly views_; private hasHadViews_; constructor(dimensions: SourceDimensionMap); getChunkGrid(lod: number, t: number, c: number): Chunk[][][] | undefined; hasChunksAtTime(timeIndex: number): boolean; get lodCount(): number; get channelCount(): number; get dimensions(): SourceDimensionMap; getLowestResLOD(): number; addView(policy: ImageSourcePolicy, axes?: SliceAxes): ChunkStoreView; get views(): ReadonlyArray; canDispose(): boolean; updateAndCollectChunkChanges(): Set; private removeDisposedViews; private aggregateChunkViewStates; private validateXYScaleRatios; private getAndValidateTimeDimension; private getAndValidateChannelDimension; } /** * Axis-aligned bounding box defined by minimum and maximum corners. * * Box2 represents a 2D region bounded by two corners: `min` and `max`. It * is used for view rectangles, viewport regions, and intersection checks. * A default-constructed box is empty and intersection treats boxes * as half-open intervals. * * @group Math */ declare class Box2 { /** Minimum corner of the box. */ min: vec2; /** Maximum corner of the box. */ max: vec2; /** * Creates a box from optional corner points. The corners are cloned. * When a corner is omitted the box starts empty. * * @param min - The minimum corner. * @param max - The maximum corner. */ constructor(min?: vec2, max?: vec2); /** Returns a deep copy of the box. */ clone(): Box2; /** Returns `true` when the box encloses no area. */ isEmpty(): boolean; /** * Tests whether two boxes overlap. Boxes are treated as half-open * intervals so touching edges do not count as overlap. * * @param a - The first box. * @param b - The second box. */ static intersects(a: Box2, b: Box2): boolean; /** * Tests whether two boxes have exactly equal corners. * * @param a - The first box. * @param b - The second box. */ static equals(a: Box2, b: Box2): boolean; /** Returns a copy with both corners floored componentwise. */ floor(): Box2; /** Converts the box to an `x, y, width, height` rectangle. */ toRect(): { x: number; y: number; width: number; height: number; }; } declare class ChunkStoreView { private readonly store_; private policy_; private policyChanged_; private currentLOD_; private readonly axes_; private readonly scale0_; private lastViewBounds2D_; private lastViewProjection_; private lastSliceBounds_?; private lastTCoord_?; private lastCCoords_?; private readonly sourceMaxSquareDistance2D_; private readonly chunkViewStates_; private isDisposed_; constructor(store: ChunkStore, policy: ImageSourcePolicy, axes?: SliceAxes); get chunkViewStates(): ReadonlyMap; get isDisposed(): boolean; get lodCount(): number; get channelCount(): number; getWholePlaneRect(): Box2; getChunksToRender(): Chunk[]; updateChunksForImage(sliceCoords: SliceCoordinates, view: { worldViewRect: Box2; bufferWidthPx: number; }): void; updateChunksForVolume(sliceCoords: SliceCoordinates, viewProjection: mat4): void; allVisibleFallbackLODLoaded(): boolean; get currentLOD(): number; maybeForgetChunk(chunk: Chunk): void; dispose(): void; setImageSourcePolicy(newPolicy: ImageSourcePolicy, key: symbol): void; private setLOD; private markTimeChunksForPrefetchImage; private markTimeChunksForPrefetchVolume; private computePriority; private channelsOfInterest; private chunkIndexRange; private iterateChunksInBox; private iterateAllChunksAtLod; private getChunkAabb; private fallbackLOD; private timeIndex; private getSliceAxisBounds; private makeViewBounds3D; private viewBounds2DChanged; private hasViewProjectionChanged; private sliceBoundsChanged; private cCoordsChanged; private getPaddedBounds; private squareDistance2D; } /** * A snapshot of the chunk request queue. */ type QueueStats = { /** Number of requests waiting to start. */ pending: number; /** Number of requests currently in flight. */ running: number; }; declare class ChunkManager { private readonly stores_; private readonly queue_; private readonly uploadTexture_?; private readonly disposeTexture_?; private readonly getGpuResidentBytes_; private memoryLimitBytes_; private readonly maxGpuUploadsPerUpdate_; private readonly resident_; constructor(uploadTexture?: (texture: Texture) => void, disposeTexture?: (texture: Texture) => void, getGpuResidentBytes?: () => number, memoryLimitBytes?: number, maxConcurrentRequests?: number, maxGpuUploadsPerUpdate?: number); get memoryLimitBytes(): number; set memoryLimitBytes(value: number); get queueStats(): QueueStats; get memoryStats(): { cpuChunkBytes: number; cpuChunkCount: number; }; addView(source: ChunkSource, policy: ImageSourcePolicy, axes?: SliceAxes): ChunkStoreView; update(): void; private releaseChunk; private enqueueWithinBudget; private evictionCandidates; private evictWorseChunks; private chunkBytes; private uploadLoadedChunks; private disposeChunkTexture; } /** * Axis-aligned bounding box defined by minimum and maximum corners. * * Box3 represents a 3D region bounded by two corners: `min` and `max`. It * is used for spatial queries, culling tests, intersection checks, and * computing bounding volumes. A default-constructed box is empty and * intersection treats boxes as half-open intervals. * * @group Math */ declare class Box3 { /** Minimum corner of the box. */ min: vec3; /** Maximum corner of the box. */ max: vec3; /** * Creates a box from optional corner points. The corners are cloned. * When a corner is omitted the box starts empty. * * @param min - The minimum corner. * @param max - The maximum corner. */ constructor(min?: vec3, max?: vec3); /** Returns a deep copy of the box. */ clone(): Box3; /** Returns `true` when the box encloses no volume. */ isEmpty(): boolean; /** * Tests whether two boxes overlap. Boxes are treated as half-open * intervals so touching faces do not count as overlap. * * @param a - The first box. * @param b - The second box. */ static intersects(a: Box3, b: Box3): boolean; /** * Grows the box in place to contain the given point. * * @param p - The point to include. */ expandWithPoint(p: vec3): void; /** * Transforms the box in place by the given matrix. The result is the * axis-aligned box of the eight transformed corners so the box can grow * under rotation. * * @param matrix - The transform to apply. */ applyTransform(matrix: mat4): void; } /** * Camera view frustum defined by six world-space planes. * * Frustum represents the visible region of a camera as six bounding * planes. It is used for culling tests and visibility checks against * bounding boxes. The planes are extracted from a view-projection matrix * and normalized so distances are in world units. * * @group Math */ declare class Frustum { private readonly planes_; /** * Creates a frustum from a view-projection matrix. * * @param m - The combined view-projection matrix. */ constructor(m: mat4); /** * Re-extracts the six planes from a view-projection matrix. * * @param m - The combined view-projection matrix. */ setWithViewProjection(m: mat4): void; /** * Tests whether a box is at least partly inside the frustum. The test * is conservative. A box outside the frustum but near a corner can be * reported as intersecting, which only costs a draw of an offscreen * object. * * @param box - The world-space box to test. */ intersectsWithBox3(box: Box3): boolean; } /** * Transform defined by translation, rotation, and scale components. * * TRS transform represents a placement in world space composed as * translation times rotation times scale. It is used to position cameras * and renderable objects through their `transform` property. The matrix * is computed lazily and cached. * * ```ts * const transform = camera.transform; * transform.setTranslation([0, 0, radius]); * transform.targetTo([0, 0, 0]); * ``` * * @group Math */ declare class TrsTransform { private dirty_; private matrix_; private rotation_; private translation_; private scale_; /** * Composes the given rotation onto the current rotation. * * @param q - The rotation to apply. */ addRotation(q: quat): void; /** * Replaces the rotation with the given quaternion. * * @param q - The new rotation. */ setRotation(q: quat): void; /** A copy of the rotation quaternion. */ get rotation(): gl_matrix.vec4; /** * Adds the given offset to the translation. * * @param vec - The offset to add. */ addTranslation(vec: vec3): void; /** * Replaces the translation with the given vector. * * @param vec - The new translation. */ setTranslation(vec: vec3): void; /** A copy of the translation vector. */ get translation(): vec3; /** * Multiplies the scale componentwise by the given vector. * * @param vec - The scale factors to apply. */ addScale(vec: vec3): void; /** * Replaces the scale with the given vector. * * @param vec - The new scale. */ setScale(vec: vec3): void; /** * Rotates the transform to face the given target point. Uses `+Y` as * world up. * * @param target - The world-space point to face. */ targetTo(target: vec3): void; /** A copy of the scale vector. */ get scale(): vec3; /** The composed transform matrix. Recomputed when stale. */ get matrix(): mat4; /** The inverse of the composed transform matrix. */ get inverse(): mat4; private computeMatrix; } /** Identifies a concrete camera implementation. */ type CameraType = "OrthographicCamera" | "PerspectiveCamera"; /** * Abstract base class for cameras. * * A camera pairs a world-space transform with a projection, producing the * view and projection matrices used to render a viewport. The concrete * cameras, {@link OrthographicCamera} and {@link PerspectiveCamera}, define * the projection. This class provides the shared transform, derived * matrices, and navigation helpers. * * @group Cameras */ declare abstract class Camera extends Node { private readonly transform_; /** @hidden */ protected projectionMatrix_: mat4; /** @hidden */ protected near_: number; /** @hidden */ protected far_: number; /** @hidden */ protected abstract updateProjectionMatrix(): void; /** Identifies the camera type. */ abstract get type(): CameraType; /** Recomputes the camera's projection matrix. */ update(): void; /** The camera's projection matrix. */ get projectionMatrix(): mat4; /** The camera's world-space transform. */ get transform(): TrsTransform; /** The view matrix: the inverse of the camera's world transform. */ get viewMatrix(): mat4; /** The camera's local right axis in world space. */ get right(): vec3; /** The camera's local up axis in world space. */ get up(): vec3; /** * Computes the combined view-projection matrix. * * @returns The projection matrix multiplied by the view matrix. */ getViewProjection(): mat4; /** The view frustum derived from the current view-projection. */ get frustum(): Frustum; /** * Sets the aspect ratio (width / height) of the viewport the camera * renders into. Called automatically by the owning viewport when it * resizes. * * @param aspectRatio - The viewport's width divided by its height. */ abstract setAspectRatio(aspectRatio: number): void; /** * Zooms the view by the given factor relative to the current zoom level. * Factors greater than `1` zoom in and factors between `0` and `1` zoom * out. * * @param factor - The magnification factor to apply. */ abstract zoom(factor: number): void; /** * Moves the camera by the given world-space offset. * * @param vec - The translation to add to the camera's position. */ pan(vec: vec3): void; /** The camera's world-space position. */ get position(): vec3; /** * Transforms a position from clip space to world space. * * @param position - The clip-space position to transform. * @returns The corresponding world-space position. */ clipToWorld(position: vec3): vec3; } type Primitive = "triangles" | "points" | "lines"; type GeometryAttributeType = "position" | "normal" | "uv" | "next_position" | "previous_position" | "direction" | "color" | "size" | "marker"; type GeometryAttribute = { type: GeometryAttributeType; itemSize: number; offset: number; }; declare class Geometry extends Node { private boundingBox_; protected primitive_: Primitive; protected attributes_: GeometryAttribute[]; protected vertexData_: Float32Array; protected indexData_: Uint32Array; constructor(vertexData?: number[], indexData?: number[], primitive?: Primitive); addAttribute(attr: GeometryAttribute): void; get vertexCount(): number; get stride(): number; get strideBytes(): number; get primitive(): Primitive; get vertexData(): Float32Array; get indexData(): Uint32Array; get attributes(): GeometryAttribute[]; get boundingBox(): Box3; get type(): string; private getAttribute; } declare class WireframeGeometry extends Geometry { constructor(geometry: Geometry); } type Shader = "floatScalarImage" | "floatVolume" | "intLabelImage" | "intScalarImage" | "intVolume" | "labelImage" | "points" | "projectedLine" | "uintScalarImage" | "uintVolume" | "wireframe" | "meshDepth" | "pointsDepth" | "projectedLineDepth"; /** * A value convertible to {@link Color}. */ type ColorLike = Color | vec3 | vec4 | string; /** * Immutable RGBA color with components in `[0, 1]`. * * Color represents an RGBA value with four components. It is used for channel * tints, label color maps, and wireframe overlays. Components are validated * at construction and never change. Every API that takes a color accepts a * {@link ColorLike} so hex strings and component arrays coerce automatically * through {@link from}. Common colors are available as static presets. * * @group Math */ declare class Color { /** Opaque red `#ff0000`. */ static readonly RED: Color; /** Opaque green `#00ff00`. */ static readonly GREEN: Color; /** Opaque blue `#0000ff`. */ static readonly BLUE: Color; /** Opaque yellow `#ffff00`. */ static readonly YELLOW: Color; /** Opaque magenta `#ff00ff`. */ static readonly MAGENTA: Color; /** Opaque cyan `#00ffff`. */ static readonly CYAN: Color; /** Opaque black `#000000`. */ static readonly BLACK: Color; /** Opaque white `#ffffff`. */ static readonly WHITE: Color; /** Fully transparent black. */ static readonly TRANSPARENT: Color; private readonly rgba_; /** * Creates a color from RGBA components in `[0, 1]`. * * @param r - The red component. * @param g - The green component. * @param b - The blue component. * @param a - The alpha component. Defaults to `1`. */ constructor(r: number, g: number, b: number, a?: number); /** The RGB components as a three-element array. */ get rgb(): [number, number, number]; /** The RGBA components as a four-element array. */ get rgba(): readonly [number, number, number, number]; /** The red component. */ get r(): number; /** The green component. */ get g(): number; /** The blue component. */ get b(): number; /** The alpha component. */ get a(): number; /** The color as a `#rrggbb` hex string. Alpha is dropped. */ get rgbHex(): string; /** The color packed into a 32-bit integer as RGBA bytes. */ get packed(): number; /** * Converts a {@link ColorLike} value to a `Color`. * * @param colorLike - The value to convert. */ static from(colorLike: ColorLike): Color; /** * Parses a `#rrggbb` hex string into an opaque color. * * @param hex - The hex string with or without the leading `#`. */ static fromRgbHex(hex: string): Color; private toHexComponent; } type CullingMode = "none" | "front" | "back" | "both"; /** * Abstract base class representing a {@link Layer}-renderable object. * * Renderables pair a geometry with a shader program, textures, uniform * values, and a world transform. Subclasses assign a geometry, select one * of the built-in shader programs through {@link programName} or provide * a new one, bind textures with {@link setTexture}, and override {@link getUniforms} to * feed values to the shader. * * ```ts * class MyRenderable extends RenderableObject { * constructor(texture: Texture) { * super(); * this.geometry = new PlaneGeometry(512, 512, 1, 1); * this.programName = "floatScalarImage"; * * this.setTexture(0, texture); * } * * public get type() { * return "MyRenderable"; * } * * public override getUniforms() { * return { u_imageSampler: 0 }; * } * } * ``` * * @group Renderables */ declare abstract class RenderableObject extends Node { /** * Draws the geometry's wireframe on top of the normal pass. Layers use * this as a chunk debugging aid. Defaults to `false`. */ wireframeEnabled: boolean; /** The color of the wireframe overlay. Defaults to `Color.WHITE`. */ wireframeColor: Color; /** * Whether the object is depth tested when drawn. Objects that opt out * are also left out of the depth prepass. Defaults to `true`. */ depthTest: boolean; private readonly textures_; private staleTextures_; private readonly transform_; private geometry_; private wireframeGeometry_; private programName_; private depthProgramName_; private cullFaceMode_; /** * Assigns a texture to the given texture unit. The renderer binds each * entry of {@link textures} to its matching unit before drawing. * * @param index - The texture unit to bind to. * @param texture - The texture to assign. */ setTexture(index: number, texture: Texture): void; /** * Removes all assigned textures. */ protected clearTextures(): void; /** * Queues a replaced texture for GPU disposal. Subclasses call this when * swapping out a texture they own. The renderer drains the queue * through {@link popStaleTextures} before the next draw. Passing * `undefined` is a no-op. * * @param texture - The texture that is no longer in use. */ protected markStaleTexture(texture: Texture | undefined): void; /** * Drains the queue of textures marked stale. Called automatically by * the renderer, which disposes the GPU resources of each returned * texture. * * @returns The textures queued since the last call. */ popStaleTextures(): Texture[]; /** * The geometry drawn for this object. */ get geometry(): Geometry; /** * A line-segment version of {@link geometry} used for the wireframe * overlay. Built lazily on first access and cached until the geometry * changes. */ get wireframeGeometry(): WireframeGeometry; /** The assigned textures indexed by texture unit. */ get textures(): Texture[]; /** * The object's world transform as translation, rotation, and scale. * Layers position, orient, and size renderables through it. */ get transform(): TrsTransform; /** @param geometry - The geometry to draw. */ set geometry(geometry: Geometry); /** * The name of a shader program that draws the object. The * renderer skips objects whose program name is `null`. */ get programName(): Shader | null; /** * The name of the shader program used in the depth prepass or `null` * to stay out of it. Objects without one never occlude other layers. */ get depthProgramName(): Shader | null; /** * The geometry's bounding box transformed to world space. The renderer * culls objects whose box falls outside the view frustum. */ get boundingBox(): Box3; /** * @param programName - The shader program name. */ protected set programName(programName: Shader); /** * Selects the shader program for the depth prepass. Subclasses set * this so the object writes depth and occludes content in other * layers. * * @param programName - The shader program name. */ protected set depthProgramName(programName: Shader); /** Which triangle faces are culled when drawing. Defaults to `"none"`. */ get cullFaceMode(): CullingMode; /** @param mode - The culling mode to apply. */ set cullFaceMode(mode: CullingMode); /** * Returns the uniform values to upload before drawing. Override in * subclasses that need custom uniforms. Values are matched to shader * uniforms by name and take precedence over the owning layer's * uniforms. */ getUniforms(): Record; } declare class Plane { normal: vec3; signedDistance: number; constructor(normal?: vec3, distance?: number); static fromPointAndNormal(point: vec3, normal: vec3): Plane; set(normal: vec3, distance: number): void; signedDistanceToPoint(point: vec3): number; normalize(): void; } declare class Ray { readonly origin: vec3; readonly direction: vec3; constructor(origin: vec3, direction: vec3); intersectWithPlane(plane: Plane): vec3 | null; } declare const eventTypes: readonly ["pointerdown", "pointermove", "pointerup", "pointercancel", "wheel"]; type EventType = (typeof eventTypes)[number]; declare class EventContext { private propagationStopped_; readonly type: EventType; readonly event?: Event; worldPos?: vec3; worldRay?: Ray; clipPos?: vec3; constructor(type: EventType, event?: Event); get propagationStopped(): boolean; stopPropagation(): void; } type Listener = (event: EventContext) => void; declare class EventDispatcher { private readonly listeners_; private readonly element_; private isConnected_; constructor(element: HTMLElement); addEventListener(listener: Listener): void; removeEventListener(listener: Listener): void; connect(): void; disconnect(): void; private readonly handleEvent; } /** * The loading lifecycle state of a layer. */ type LayerState = "initialized" | "loading" | "ready"; /** * How a layer's output blends with previously drawn content. */ type BlendMode = "none" | "normal" | "additive" | "subtractive" | "multiply" | "premultipliedOver"; /** * A callback invoked after a layer's state changes. */ type StateChangeCallback = (newState: LayerState, prevState?: LayerState) => void; /** * Initialization properties for constructing a layer. */ type LayerProps = { /** Layer opacity in `[0, 1]`. Defaults to `1`. */ opacity?: number; /** How the layer blends. Defaults to `"none"`. */ blendMode?: BlendMode; /** Hides content behind. Inferred from `blendMode`. */ occludes?: boolean; }; /** * Abstract base class for any layer that can be added to a viewport. * * A layer owns a set of renderable objects and contributes them to the * scene each frame. Subclasses such as {@link ImageLayer}, * {@link VolumeLayer}, and {@link LabelLayer} implement {@link update} to * build or refresh those objects for the current view. Custom layers * register objects with {@link addObject} and report readiness through * {@link setState}. * * Layers carry shared presentation state in {@link opacity}, * {@link blendMode}, and {@link occludes}, and expose a lifecycle * {@link LayerState} that observers can subscribe to. A layer instance may * be attached to only one viewport at a time. * * ```ts * class Particles extends Layer { * public readonly type = "Particles"; * * constructor(points: PointProps[]) { * super(); * this.addObject(new PointsRenderable(points)); * this.setState("ready"); * } * * public update() {} * } * * viewport.addLayer(new Particles(points)); * ``` * * @group Layers */ declare abstract class Layer { /** A string identifying the concrete layer type. */ abstract readonly type: string; /** * How the layer's output blends with previously drawn content. Also * applies to blending between objects within the layer. */ blendMode: BlendMode; /** * Whether the layer writes depth and hides content drawn behind it. * * Occluding layers render a depth pass and always draw before * non-occluding layers regardless of their order in the viewport. When * not set explicitly this value is inferred from `blendMode` at * construction only. Reassigning {@link blendMode} later does not update * it. */ occludes: boolean; /** Set to `true` by subclasses whose shaders read scene depth. */ protected requiresSceneDepth_: boolean; private readonly coverageGroups_; private state_; private attached_; private readonly callbacks_; private opacity_; /** * Creates a layer with the given presentation state. * * @param props - Initialization properties. */ constructor({ opacity, blendMode, occludes, }?: LayerProps); /** * Whether the layer's shaders read scene depth. When `true` the renderer * draws occluding layers to a depth texture the layer's shaders can * sample. A layer cannot both occlude and read scene depth. */ get requiresSceneDepth(): boolean; /** The layer's opacity in `[0, 1]`. Values outside are clamped. */ get opacity(): number; /** @param value - The new opacity in `[0, 1]`. */ set opacity(value: number); /** * Builds or refreshes the layer's renderable objects for the current * view. Called automatically once per frame for every layer in a * viewport. * * @param viewport - The viewport being rendered. */ abstract update(viewport?: Viewport): void; /** * Handles a pointer or wheel event from the owning viewport. Called * automatically for each event before the camera controls. The default * implementation does nothing. * * @param _event - The event with clip and world coordinates attached. */ onEvent(_event: EventContext): void; /** * Lifecycle hook that is called automatically when a layer is * is attached to a viewport. A layer can only be attached to one viewport * at a time. * * @param context - The shared runtime context. */ onAttached(context: IdetikContext): void; /** * Lifecycle hook that is called automatically when a layer is detached * from a viewport. * * @param context - The shared runtime context. */ onDetached(context: IdetikContext): void; /** @hidden */ protected attach(_context: IdetikContext): void; /** @hidden */ protected detach(_context: IdetikContext): void; /** * The layer's renderable objects grouped by coverage group. Objects in * a group draw each pixel at most once, letting chunks at multiple * levels of detail overlap correctly. */ get coverageGroups(): ReadonlyMap; /** The layer's current lifecycle state. */ get state(): LayerState; /** * Registers a callback invoked after every state change. * * @param callback - Receives the new and previous states. */ addStateChangeCallback(callback: StateChangeCallback): void; /** * Removes a previously registered state change callback. * * @param callback - The callback to remove. */ removeStateChangeCallback(callback: StateChangeCallback): void; /** * Sets the lifecycle state and notifies state change callbacks. * * @param newState - The state to enter. */ protected setState(newState: LayerState): void; /** * Registers a renderable object for drawing. Objects in the same * coverage group draw each pixel at most once. * * @param object - The object to add. * @param coverageGroup - The group key. */ protected addObject(object: RenderableObject, coverageGroup?: number | null): void; /** Removes all registered renderable objects. */ protected clearObjects(): void; /** * Returns uniform name-value pairs applied to every object drawn by * this layer. Override in subclasses that need custom shader uniforms. */ getUniforms(): Record; } /** * A world-space rectangle for the camera to frame. */ type OrthographicCameraFrame = { /** Left edge of the view frame in world units. */ left: number; /** Right edge of the view frame in world units. */ right: number; /** Top edge of the view frame in world units. */ top: number; /** Bottom edge of the view frame in world units. */ bottom: number; }; /** * Initialization properties for constructing an orthographic camera. */ type OrthographicCameraProps = { /** Left edge of the view frame in world units. */ left: number; /** Right edge of the view frame in world units. */ right: number; /** Top edge of the view frame in world units. */ top: number; /** Bottom edge of the view frame in world units. */ bottom: number; /** Near clipping plane distance. Defaults to `-1e6`. */ near?: number; /** Far clipping plane distance. Defaults to `1e6`. */ far?: number; /** Slice orientation. Defaults to `"XY"`. */ orientation?: SliceOrientation; }; /** * A camera using an orthographic (parallel) projection. * * Orthographic projection has no perspective foreshortening: objects render at * the same size regardless of their distance from the camera, which makes this * the camera to use for 2D image viewing. It pairs naturally with * {@link PanZoomControls}. * * The constructor frames a world-space rectangle, typically the physical * extent of the image being viewed. Zoom and pan are then applied as scale and * translation on top of that frame, and {@link setFrame} resets them. When the * viewport's aspect ratio differs from the frame's, the frame is padded rather * than stretched, so image pixels always stay square. * * ```ts * const camera = new OrthographicCamera({ * left: 0, * right: 1024, * top: 0, * bottom: 1024 * }); * * const idetik = new Idetik({ * canvas: document.querySelector('canvas')!, * viewports: [{ * camera, * layers: [imageLayer], * cameraControls: new PanZoomControls(camera), * }], * }); * ``` * @group Cameras */ declare class OrthographicCamera extends Camera { private width_; private height_; private viewportAspectRatio_; private viewportSize_; private axes_; private rotation_; private orientation_; /** * Creates an orthographic camera framing the given world-space rectangle. * * @param props - Initialization properties. */ constructor(props: OrthographicCameraProps); /** * The world-space size of the rendered view as `[width, height]`. * * This is the camera frame padded to match the viewport's aspect ratio, so * it reflects what is actually visible rather than the frame that was set. */ get viewportSize(): [number, number]; /** * Sets the aspect ratio (width / height) of the viewport the camera renders * into. Called automatically by the owning viewport when it resizes. * * @param aspectRatio - The viewport's width divided by its height. */ setAspectRatio(aspectRatio: number): void; /** * Reframes the camera to the given world-space rectangle, resetting any * accumulated zoom and pan. * * The frame may be padded horizontally or vertically at render time to * match the viewport's aspect ratio (see {@link viewportSize}). * * @param frame - The view frame edges in world units. */ setFrame({ left, right, top, bottom }: OrthographicCameraFrame): void; /** Identifies the camera type as `OrthographicCamera`. */ get type(): CameraType; /** The slice orientation the camera faces. */ get orientation(): SliceOrientation; /** * Changes the slice orientation the camera faces. The current frame and * zoom carry over numerically to the new plane axes. Call {@link setFrame} * to reframe the view for the new plane. * * @param orientation - The slice plane for the camera to face. */ setOrientation(orientation: SliceOrientation): void; /** * Zooms the view by the given factor relative to the current zoom level. * Factors greater than `1` zoom in and factors between `0` and `1` zoom * out. * * @param factor - The magnification factor to apply. */ zoom(factor: number): void; /** * Computes the world-space rectangle currently visible in the viewport, * accounting for zoom, pan, and aspect-ratio padding. * * @returns The visible rectangle on the camera's slice plane. */ getWorldViewRect(): Box2; /** @hidden */ protected updateProjectionMatrix(): void; } /** * The contract between a viewport and its camera controls. * * Implement this interface to drive a camera with custom input logic and * assign it to a viewport through its `cameraControls` property. The * viewport passes pointer and wheel events to `onEvent` unless a layer * stops propagation. * * ```ts * class ClickToZoomControls implements CameraControls { * constructor(private camera: OrthographicCamera) {} * * get isMoving() { * return false; * } * * onUpdate(dt: number) {} * * onEvent(event: EventContext) { * if (event.type === "pointerdown") this.camera.zoom(2); * } * } * * viewport.cameraControls = new ClickToZoomControls(camera); * ``` * * @group Controls */ interface CameraControls { /** * Whether the camera is in motion from user interaction. Layers may * read this to reduce rendering quality while the view changes. */ readonly isMoving: boolean; /** * Advances time-based motion such as damping. Called automatically by * the render loop. * * @param dt - Time since the last frame in seconds. */ onUpdate(dt: number): void; /** * Handles a pointer or wheel event. Called automatically by the owning * viewport unless a layer stops propagation. * * @param event - The event with clip and world coordinates attached. */ onEvent(event: EventContext): void; } type ScrollZoomMode = "always" | "modifier" | "never"; /** * Initialization properties for constructing pan and zoom controls. */ type PanZoomControlsProps = { /** When the scroll wheel zooms. Defaults to `"always"`. */ scrollZoom?: ScrollZoomMode; }; /** * Camera controls for 2D pan and zoom with an orthographic camera. * * Dragging with the left mouse button pans the view and the scroll wheel * zooms around the cursor, keeping the point under the pointer fixed. * Movement applies immediately with no inertia or damping. * * ```ts * const camera = new OrthographicCamera({ * left: 0, * right: 1024, * top: 0, * bottom: 1024, * }); * * const idetik = new Idetik({ * canvas, * viewports: [{ * camera, * layers: [imageLayer], * cameraControls: new PanZoomControls(camera), * }], * }); * ``` * * @group Controls */ declare class PanZoomControls implements CameraControls { private readonly camera_; private readonly scrollZoom_; private dragActive_; private dragStart_; /** * Creates pan and zoom controls for the given camera. * * @param camera - The orthographic camera to control. * @param params - Initialization properties. */ constructor(camera: OrthographicCamera, params?: PanZoomControlsProps); /** Whether a pan drag is in progress. */ get isMoving(): boolean; /** * Handles a pointer or wheel event. Called automatically by the owning * viewport unless a layer stops propagation. * * @param event - The event with clip and world coordinates attached. */ onEvent(event: EventContext): void; /** * Does nothing. Pan and zoom apply immediately with no inertia. * * @param _delta - Time since the last frame in seconds. Unused. */ onUpdate(_delta: number): void; private onWheel; private onPointerDown; private onPointerMove; private onPointerEnd; } /** * Initialization properties for constructing a viewport. */ type ViewportProps = { /** Unique id. Defaults to the element id or a generated id. */ id?: string; /** Host element. Defaults to the Idetik canvas. */ element?: HTMLElement; /** The camera the viewport renders with. */ camera: Camera; /** Layers to render in order. */ layers?: Layer[]; /** Input controls driving the camera. */ cameraControls?: CameraControls; }; interface ResolvedViewportProps extends ViewportProps { id: string; element: HTMLElement; context: IdetikContext; } /** * A region of the canvas that renders a stack of layers through a camera. * * Every viewport draws into the shared canvas through the area of its host * element. The element defaults to the canvas itself and must be unique * across viewports. * * Viewports also route input. Pointer and wheel events on the host element * are enriched with clip and world coordinates and a picking ray, sent to * each layer in order and passed to the camera controls unless a layer stops * propagation. * * ```ts * const idetik = new Idetik({ * canvas, * viewports: [{ id: 'main', camera, layers: [imageLayer] }], * }); * * const viewport = idetik.getViewport('main')!; * viewport.addLayer(labelLayer); * ``` * * @group Core */ declare class Viewport { /** The viewport's unique identifier. */ readonly id: string; /** The host element defining the viewport's area. */ readonly element: HTMLElement; /** The camera the viewport renders with. */ readonly camera: Camera; /** The pointer and wheel event dispatcher for the host element. */ readonly events: EventDispatcher; /** Input controls driving the camera. */ cameraControls?: CameraControls; private readonly context_; private layers_; /** @hidden */ constructor(props: ResolvedViewportProps); /** * The layers rendered by this viewport in order. Layers with `occludes` * set draw before non-occluding layers regardless of stack order. */ get layers(): readonly Layer[]; /** * Adds a layer to the top of the stack. * * @param layer - The layer to add. */ addLayer(layer: Layer): void; /** * Removes a previously added layer. * * @param layer - The layer to remove. */ removeLayer(layer: Layer): void; /** Removes all layers from the viewport. */ removeAllLayers(): void; /** * Syncs the camera's aspect ratio to the host element's size. Called * automatically when the host element resizes. */ updateSize(): void; /** * Computes the viewport's box relative to the given canvas in device pixels. * * @param canvas - The canvas to compute the box against. * @returns The viewport's box in the canvas's coordinate space. */ getBoxRelativeTo(canvas: HTMLCanvasElement): Box2; /** * The viewport's rectangle in the drawing buffer in device pixels. */ getBufferRect(): { x: number; y: number; width: number; height: number; }; /** * Converts a client-space position to clip space. The `y` axis points * down, matching the renderer's mirrored projection. * * @param position - The client-space position to convert. * @param depth - The clip-space z value. */ clientToClip(position: vec2, depth?: number): vec3; /** * Converts a client-space position such as a pointer location to world * space. * * @param position - The client-space position to convert. * @param depth - The clip-space z value. */ clientToWorld(position: vec2, depth?: number): vec3; private getBox; private updateAspectRatio; } /** * An object updated once per frame after all viewports have rendered. * * Overlays drive HUD elements that live outside the canvas such as scale * bars, time indicators, or memory readouts. * * ```ts * const chunkReadout: Overlay = { * update(idetik) { * div.textContent = `${idetik.memoryStats.cpuChunkCount} chunks`; * }, * }; * * idetik.addOverlay(chunkReadout); * ``` */ type Overlay = { /** Called once per rendered frame. */ update: (idetik: Idetik) => void; }; /** * Initialization properties for constructing an Idetik instance. */ type IdetikProps = { /** The canvas element to render into. */ canvas: HTMLCanvasElement; /** Viewport definitions to create at startup. */ viewports?: ViewportProps[]; /** Overlays to run each frame. */ overlays?: Overlay[]; /** Shows an FPS meter. Defaults to `false`. */ showStats?: boolean; /** Memory budget for chunk data. Defaults to `2048`. */ memoryLimitMB?: number; /** Max in-flight chunk requests. Defaults to `8`. */ maxConcurrentRequests?: number; /** Max GPU texture uploads per frame. Defaults to `4`. */ maxGpuUploadsPerUpdate?: number; }; type IdetikContext = { chunkManager: ChunkManager; }; /** * A snapshot of the runtime's memory usage. */ type MemoryStats = { /** Bytes of chunk data held in CPU memory. */ cpuChunkBytes: number; /** Number of chunks held in CPU memory. */ cpuChunkCount: number; /** Bytes of texture data resident on the GPU. */ gpuTextureBytes: number; /** Number of textures resident on the GPU. */ gpuTextureCount: number; /** Used JS heap in bytes. */ jsHeapUsedBytes?: number; /** JS heap size limit in bytes. */ jsHeapLimitBytes?: number; }; /** * The entry point of an Idetik application. * * An Idetik instance owns the renderer and the chunk manager and drives the * render loop for the viewports it is given. Each viewport pairs a camera * and its controls with a stack of layers and draws into a region of the * shared canvas. Layers in all viewports stream chunks through the same * manager under a single memory budget. * * ```ts * const source = await OmeZarrImageSource.fromHttp({ url }); * * const layer = new ImageLayer({ * source, * sliceCoords: { t: 0, z: 0, c: [0] }, * }); * * const camera = new OrthographicCamera({ * left: 0, * right: 1024, * top: 0, * bottom: 1024, * }); * * const idetik = new Idetik({ * canvas: document.querySelector('canvas')!, * viewports: [{ * camera, * layers: [layer], * cameraControls: new PanZoomControls(camera), * }], * }); * * idetik.start(); * ``` * * @see {@link Layer} for the data layers rendered within a viewport. * * @group Core */ declare class Idetik { /** The canvas element the renderer draws into. */ readonly canvas: HTMLCanvasElement; /** The registered overlays that update once per frame in order. */ readonly overlays: Overlay[]; private readonly chunkManager_; private readonly context_; private readonly renderer_; private readonly viewports_; private readonly stats_?; private readonly sizeObserver_; private lastAnimationId_?; private lastTimestamp_; /** * Creates an Idetik runtime for the given canvas. * * @param params - Initialization properties. */ constructor(params: IdetikProps); /** Counts of queued and in-flight chunk requests. */ get chunkQueueStats(): QueueStats; /** A snapshot of current CPU/GPU/JS heap memory usage. */ get memoryStats(): MemoryStats; /** The number of objects drawn in the last rendered frame. */ get renderedObjects(): number; /** The width of the rendering surface in pixels. */ get width(): number; /** The height of the rendering surface in pixels. */ get height(): number; /** The viewports in render order. */ get viewports(): readonly Viewport[]; /** Whether the render loop is running. */ get running(): boolean; /** * Finds a viewport by its id. * * @param id - The id given in the viewport's definition. * @returns The matching viewport or `undefined` if none matches. */ getViewport(id: string): Viewport | undefined; /** * Adds a viewport at runtime. * * @param props - The viewport definition. The `element` defaults to the * canvas and must be unique across viewports. * @returns The created viewport. */ addViewport(props: ViewportProps): Viewport; /** * Removes a previously added viewport. * * @param viewport - The viewport to remove. * @returns `true` if the viewport was found and removed. */ removeViewport(viewport: Viewport): boolean; /** * Registers an overlay that updates once per frame. * * @param overlay - The overlay to add. */ addOverlay(overlay: Overlay): void; /** * Removes a previously added overlay. * * @param overlay - The overlay to remove. * @returns `true` if the overlay was found and removed. */ removeOverlay(overlay: Overlay): boolean; /** * Sets the memory budget for chunk data at runtime. * * @param memoryLimitMB - The new budget in megabytes. */ setMemoryLimitMB(memoryLimitMB: number): void; /** * Starts the render loop and connects input handlers. * * @returns The instance, for chaining. */ start(): this; private animate; /** * Stops the render loop and disconnects input handlers. */ stop(): void; } /**The zarr.json attributes key*/ declare const Image: z.ZodObject<{ /**The versioned OME-Zarr Metadata namespace*/ ome: z.ZodObject<{ /**The multiscale datasets for this image*/ multiscales: z.ZodArray; datasets: z.ZodArray, "many">; }, "strip", z.ZodTypeAny, { path: string; coordinateTransformations: any[]; }, { path: string; coordinateTransformations: any[]; }>, "many">; axes: z.ZodArray, "many">; coordinateTransformations: z.ZodOptional, "many">>; }, "strip", z.ZodTypeAny, { datasets: { path: string; coordinateTransformations: any[]; }[]; axes: any[]; name?: string | undefined; coordinateTransformations?: any[] | undefined; }, { datasets: { path: string; coordinateTransformations: any[]; }[]; axes: any[]; name?: string | undefined; coordinateTransformations?: any[] | undefined; }>, "many">; omero: z.ZodOptional>; label: z.ZodOptional; family: z.ZodOptional; color: z.ZodOptional; active: z.ZodOptional; }, "strip", z.ZodTypeAny, { color?: string | undefined; window?: { min: number; max: number; end: number; start: number; } | undefined; label?: string | undefined; family?: string | undefined; active?: boolean | undefined; }, { color?: string | undefined; window?: { min: number; max: number; end: number; start: number; } | undefined; label?: string | undefined; family?: string | undefined; active?: boolean | undefined; }>, "many">; rdefs: z.ZodOptional; defaultZ: z.ZodOptional; color: z.ZodOptional>; projection: z.ZodOptional; }, "strip", z.ZodTypeAny, { color?: "color" | "greyscale" | undefined; defaultT?: number | undefined; defaultZ?: number | undefined; projection?: string | undefined; }, { color?: "color" | "greyscale" | undefined; defaultT?: number | undefined; defaultZ?: number | undefined; projection?: string | undefined; }>>; }, "strip", z.ZodTypeAny, { channels: { color?: string | undefined; window?: { min: number; max: number; end: number; start: number; } | undefined; label?: string | undefined; family?: string | undefined; active?: boolean | undefined; }[]; rdefs?: { color?: "color" | "greyscale" | undefined; defaultT?: number | undefined; defaultZ?: number | undefined; projection?: string | undefined; } | undefined; }, { channels: { color?: string | undefined; window?: { min: number; max: number; end: number; start: number; } | undefined; label?: string | undefined; family?: string | undefined; active?: boolean | undefined; }[]; rdefs?: { color?: "color" | "greyscale" | undefined; defaultT?: number | undefined; defaultZ?: number | undefined; projection?: string | undefined; } | undefined; }>>; /**The version of the OME-Zarr Metadata*/ version: z.ZodLiteral<"0.5">; }, "strip", z.ZodTypeAny, { multiscales: { datasets: { path: string; coordinateTransformations: any[]; }[]; axes: any[]; name?: string | undefined; coordinateTransformations?: any[] | undefined; }[]; version: "0.5"; omero?: { channels: { color?: string | undefined; window?: { min: number; max: number; end: number; start: number; } | undefined; label?: string | undefined; family?: string | undefined; active?: boolean | undefined; }[]; rdefs?: { color?: "color" | "greyscale" | undefined; defaultT?: number | undefined; defaultZ?: number | undefined; projection?: string | undefined; } | undefined; } | undefined; }, { multiscales: { datasets: { path: string; coordinateTransformations: any[]; }[]; axes: any[]; name?: string | undefined; coordinateTransformations?: any[] | undefined; }[]; version: "0.5"; omero?: { channels: { color?: string | undefined; window?: { min: number; max: number; end: number; start: number; } | undefined; label?: string | undefined; family?: string | undefined; active?: boolean | undefined; }[]; rdefs?: { color?: "color" | "greyscale" | undefined; defaultT?: number | undefined; defaultZ?: number | undefined; projection?: string | undefined; } | undefined; } | undefined; }>; }, "strip", z.ZodTypeAny, { ome: { multiscales: { datasets: { path: string; coordinateTransformations: any[]; }[]; axes: any[]; name?: string | undefined; coordinateTransformations?: any[] | undefined; }[]; version: "0.5"; omero?: { channels: { color?: string | undefined; window?: { min: number; max: number; end: number; start: number; } | undefined; label?: string | undefined; family?: string | undefined; active?: boolean | undefined; }[]; rdefs?: { color?: "color" | "greyscale" | undefined; defaultT?: number | undefined; defaultZ?: number | undefined; projection?: string | undefined; } | undefined; } | undefined; }; }, { ome: { multiscales: { datasets: { path: string; coordinateTransformations: any[]; }[]; axes: any[]; name?: string | undefined; coordinateTransformations?: any[] | undefined; }[]; version: "0.5"; omero?: { channels: { color?: string | undefined; window?: { min: number; max: number; end: number; start: number; } | undefined; label?: string | undefined; family?: string | undefined; active?: boolean | undefined; }[]; rdefs?: { color?: "color" | "greyscale" | undefined; defaultT?: number | undefined; defaultZ?: number | undefined; projection?: string | undefined; } | undefined; } | undefined; }; }>; type Image = z.infer; type Version$1 = "v2" | "v3"; type ZarrArrayParams = { arrayPath: string; zarrVersion: Version$1 | undefined; } & ({ type: "fetch"; url: string; } | { type: "filesystem"; directoryHandle: FileSystemDirectoryHandle; path: string; }); type OmeZarrImageLoaderProps = { metadata: Image["ome"]["multiscales"][number]; arrays: zarr.Array[]; arrayParams: ZarrArrayParams[]; }; declare class OmeZarrImageLoader { private readonly metadata_; private readonly arrays_; private readonly arrayParams_; private readonly dimensions_; private readonly bytesPerElement_; constructor(props: OmeZarrImageLoaderProps); getSourceDimensionMap(): SourceDimensionMap; getBytesPerElement(): number; loadChunkData(chunk: Chunk, signal: AbortSignal): Promise; } /**The zarr.json attributes key*/ declare const Plate: z.ZodObject<{ /**The versioned OME-Zarr Metadata namespace*/ ome: z.ZodObject<{ plate: z.ZodObject<{ /**The acquisitions for this plate*/ acquisitions: z.ZodOptional; /**The name of the acquisition*/ name: z.ZodOptional; /**The description of the acquisition*/ description: z.ZodOptional; /**The start timestamp of the acquisition, expressed as epoch time i.e. the number seconds since the Epoch*/ starttime: z.ZodOptional; /**The end timestamp of the acquisition, expressed as epoch time i.e. the number seconds since the Epoch*/ endtime: z.ZodOptional; }, "strip", z.ZodTypeAny, { id: number; name?: string | undefined; maximumfieldcount?: number | undefined; description?: string | undefined; starttime?: number | undefined; endtime?: number | undefined; }, { id: number; name?: string | undefined; maximumfieldcount?: number | undefined; description?: string | undefined; starttime?: number | undefined; endtime?: number | undefined; }>, "many">>; /**The maximum number of fields per view across all wells*/ field_count: z.ZodOptional; /**The name of the plate*/ name: z.ZodOptional; /**The columns of the plate*/ columns: z.ZodArray, "many">; /**The rows of the plate*/ rows: z.ZodArray, "many">; /**The wells of the plate*/ wells: z.ZodArray, "many">; }, "strip", z.ZodTypeAny, { columns: { name: string; }[]; rows: { name: string; }[]; wells: { path: string; rowIndex: number; columnIndex: number; }[]; name?: string | undefined; acquisitions?: { id: number; name?: string | undefined; maximumfieldcount?: number | undefined; description?: string | undefined; starttime?: number | undefined; endtime?: number | undefined; }[] | undefined; field_count?: number | undefined; }, { columns: { name: string; }[]; rows: { name: string; }[]; wells: { path: string; rowIndex: number; columnIndex: number; }[]; name?: string | undefined; acquisitions?: { id: number; name?: string | undefined; maximumfieldcount?: number | undefined; description?: string | undefined; starttime?: number | undefined; endtime?: number | undefined; }[] | undefined; field_count?: number | undefined; }>; /**The version of the OME-Zarr Metadata*/ version: z.ZodLiteral<"0.5">; }, "strip", z.ZodTypeAny, { version: "0.5"; plate: { columns: { name: string; }[]; rows: { name: string; }[]; wells: { path: string; rowIndex: number; columnIndex: number; }[]; name?: string | undefined; acquisitions?: { id: number; name?: string | undefined; maximumfieldcount?: number | undefined; description?: string | undefined; starttime?: number | undefined; endtime?: number | undefined; }[] | undefined; field_count?: number | undefined; }; }, { version: "0.5"; plate: { columns: { name: string; }[]; rows: { name: string; }[]; wells: { path: string; rowIndex: number; columnIndex: number; }[]; name?: string | undefined; acquisitions?: { id: number; name?: string | undefined; maximumfieldcount?: number | undefined; description?: string | undefined; starttime?: number | undefined; endtime?: number | undefined; }[] | undefined; field_count?: number | undefined; }; }>; }, "strip", z.ZodTypeAny, { ome: { version: "0.5"; plate: { columns: { name: string; }[]; rows: { name: string; }[]; wells: { path: string; rowIndex: number; columnIndex: number; }[]; name?: string | undefined; acquisitions?: { id: number; name?: string | undefined; maximumfieldcount?: number | undefined; description?: string | undefined; starttime?: number | undefined; endtime?: number | undefined; }[] | undefined; field_count?: number | undefined; }; }; }, { ome: { version: "0.5"; plate: { columns: { name: string; }[]; rows: { name: string; }[]; wells: { path: string; rowIndex: number; columnIndex: number; }[]; name?: string | undefined; acquisitions?: { id: number; name?: string | undefined; maximumfieldcount?: number | undefined; description?: string | undefined; starttime?: number | undefined; endtime?: number | undefined; }[] | undefined; field_count?: number | undefined; }; }; }>; type Plate = z.infer; /**JSON from OME-Zarr zarr.json*/ declare const Well: z.ZodObject<{ /**The versioned OME-Zarr Metadata namespace*/ ome: z.ZodObject<{ well: z.ZodObject<{ /**The fields of view for this well*/ images: z.ZodArray; /**The path for this field of view subgroup*/ path: z.ZodString; }, "strip", z.ZodTypeAny, { path: string; acquisition?: number | undefined; }, { path: string; acquisition?: number | undefined; }>, "many">; }, "strip", z.ZodTypeAny, { images: { path: string; acquisition?: number | undefined; }[]; }, { images: { path: string; acquisition?: number | undefined; }[]; }>; /**The version of the OME-Zarr Metadata*/ version: z.ZodLiteral<"0.5">; }, "strip", z.ZodTypeAny, { version: "0.5"; well: { images: { path: string; acquisition?: number | undefined; }[]; }; }, { version: "0.5"; well: { images: { path: string; acquisition?: number | undefined; }[]; }; }>; }, "strip", z.ZodTypeAny, { ome: { version: "0.5"; well: { images: { path: string; acquisition?: number | undefined; }[]; }; }; }, { ome: { version: "0.5"; well: { images: { path: string; acquisition?: number | undefined; }[]; }; }; }>; type Well = z.infer; declare const versions: readonly ["0.4", "0.5"]; type Version = (typeof versions)[number]; type AdaptedOme = T & { originalVersion: Version; }; /** @hidden */ declare function loadOmeZarrPlate(url: string, version?: Version): Promise>; /** @hidden */ declare function loadOmeZarrWell(url: string, path: string, version?: Version): Promise>; type OmeroMetadata = NonNullable; type OmeroChannel = OmeroMetadata["channels"][number]; /** @hidden */ declare function loadOmeroChannels(source: OmeZarrImageSource): Promise; /** @hidden */ declare function loadOmeroDefaults(source: OmeZarrImageSource): Promise; /** * Input to {@link OmeZarrImageSource.fromHttp}. */ type HttpOmeZarrImageSourceProps = { /** URL of the OME-Zarr root group. */ url: string; /** OME-Zarr version. Detected from metadata when omitted. */ version?: Version; }; /** * Input to {@link OmeZarrImageSource.fromFileSystem}. */ type FileSystemOmeZarrImageSourceProps = { /** Directory handle with read permission. */ directory: FileSystemDirectoryHandle; /** OME-Zarr version. Detected from metadata when omitted. */ version?: Version; /** Image path within the directory. Defaults to the root. */ path?: `/${string}`; }; /** * A multiscale image opened from an OME-Zarr store. * * Instances are created with {@link fromHttp} or {@link fromFileSystem} * rather than the constructor. Both factories read the store's metadata up * front so the returned source already knows its axes, resolution levels, * and channel count. OME-Zarr versions `0.4` and `0.5` are supported and * the version is detected from metadata when not given. * * A source is handed to a layer which streams chunks from it on demand. * * ```ts * const source = await OmeZarrImageSource.fromHttp({ * url: "https://example.com/image.ome.zarr", * }); * * const layer = new ImageLayer({ * source, * sliceCoords: { t: 0, z: 0, c: [0] }, * }); * ``` * * @group Data Loading */ declare class OmeZarrImageSource { /** The zarr store location the image was opened from. */ readonly location: Location; /** The OME-Zarr version passed at creation if any. */ readonly version?: Version; private readonly loader_; private constructor(); private static openLoader; /** * Returns per-axis dimension metadata for the image. * * Each axis entry lists one record per level of detail with its size, * chunk size, scale, and translation. Use these to convert between * array indices and world coordinates, pick slice coordinates, and * frame cameras around the image extent. */ getDimensions(): SourceDimensionMap; /** * Returns the number of channels in the image. */ getChannelCount(): number; /** The chunk loader that streams this image's data. */ get loader(): OmeZarrImageLoader; /** * Opens an OME-Zarr image over HTTP(S). * * @param props - The store url and optional version. */ static fromHttp(props: HttpOmeZarrImageSourceProps): Promise; /** * Opens an OME-Zarr image from a local directory. * * Uses the File System Access API so it only works in Chromium-based * browsers. Pass the handle returned by `window.showDirectoryPicker()`. * The optional path lets an application ask once for root permission * and open many images. * * @param props - The directory handle, optional version, and path. */ static fromFileSystem(props: FileSystemOmeZarrImageSourceProps): Promise; } /** * The result of picking a value from a layer with a click. */ type PointPickingResult = { /** The picked position in world units. */ world: vec3; /** The data value sampled at the position. */ value: number; }; /** * Initialization properties for constructing an axes layer. */ type AxesLayerProps = { /** Axis length in world units. */ length: number; /** Line width in pixels. */ width: number; }; /** * A layer that draws the world coordinate axes as colored lines. * * Three lines start at the world origin: `x` in red, `y` in green, and * `z` in blue, each with the given length and width. The layer is static * and ready as soon as it is constructed. * * ```ts * viewport.addLayer(new AxesLayer({ length: 100, width: 2 })); * ``` * * @group Layers */ declare class AxesLayer extends Layer { /** Identifies the layer type as `AxesLayer`. */ readonly type = "AxesLayer"; /** * Creates an axes layer with the given dimensions. * * @param props - Initialization properties. */ constructor(props: AxesLayerProps); /** Performs no per-frame work. The axes are built at construction. */ update(): void; } /** * Appearance settings for a single image channel. */ type ChannelProps = { /** Whether the channel is drawn. Defaults to `true`. */ visible?: boolean; /** The channel's tint color. Defaults to white. */ color?: ColorLike; /** Intensity range shown. Defaults to the data range. */ contrastLimits?: [number, number]; /** Channel opacity in `[0, 1]`. Defaults to `1`. */ opacity?: number; }; /** Layer that exposes channel controls. */ interface ChannelsEnabled { channelProps: ChannelProps[] | undefined; setChannelProps(channelProps: ChannelProps[]): void; resetChannelProps(): void; addChannelChangeCallback(callback: () => void): void; removeChannelChangeCallback(callback: () => void): void; } /** * Initialization properties for constructing an image layer. */ type ImageLayerProps = { /** The chunked image source to stream from. */ source: ChunkSource; /** The slice to display in world units. */ sliceCoords: SliceCoordinates; /** Streaming policy. Defaults to the exploration policy. */ policy?: ImageSourcePolicy; /** Slice plane orientation. Defaults to `"XY"`. */ orientation?: SliceOrientation; /** Per-channel appearance. Length must match the source. */ channelProps?: ChannelProps[]; /** Called with the picked value when the layer is clicked. */ onPickValue?: (info: PointPickingResult) => void; /** Layer opacity in `[0, 1]`. Defaults to `1`. */ opacity?: number; /** How the layer blends. Defaults to `"additive"`. */ blendMode?: BlendMode; /** Hides content behind. Defaults to `true`. */ occludes?: boolean; }; /** * A layer that renders a 2D slice of a chunked multi-channel image source. * * Image layer streams chunks from a source such as * {@link OmeZarrImageSource} according to its streaming policy, which * decides which resolution levels and chunks to load for the current view. * Per-channel appearance is controlled with {@link ChannelProps} and the * visible slice is selected with {@link SliceCoordinates}. The layer holds * `sliceCoords` by reference, so mutating the object it was constructed * with moves through the data. * * ```ts * const source = await OmeZarrImageSource.fromHttp({ url }); * * const layer = new ImageLayer({ * source, * sliceCoords: { t: 0, z: 0, c: [0, 1] }, * channelProps: [ * { color: Color.GREEN, contrastLimits: [0, 1024] }, * { color: Color.MAGENTA, contrastLimits: [0, 1024] }, * ], * }); * * viewport.addLayer(layer); * ``` * * @see {@link VolumeLayer} for 3D volume rendering of the same data. * * @group Layers */ declare class ImageLayer extends Layer implements ChannelsEnabled { /** Identifies the layer type as `ImageLayer`. */ readonly type = "ImageLayer"; private readonly source_; private readonly sliceCoords_; private axes_; private planeRotation_; private orientation_; private readonly onPickValue_?; private readonly visibleChunks_; private orderedChunks_; private readonly pool_; private readonly initialChannelProps_?; private readonly channelChangeCallbacks_; private policy_; private channelProps_?; private chunkStoreView_?; private context_?; private pointerDownPos_; private debugMode_; private static readonly STALE_PRESENTATION_MS_; private lastPresentationTimeStamp_?; private lastPresentationTimeCoord_?; private readonly wireframeColors_; /** * Creates an image layer for the given source and slice. * * @param props - Initialization properties. */ constructor({ source, sliceCoords, policy, orientation, channelProps, onPickValue, ...layerOptions }: ImageLayerProps); /** @hidden */ protected attach(context: IdetikContext): void; /** @hidden */ protected detach(_context: IdetikContext): void; /** * Streams chunks for the current view and refreshes the visible slice. * * @param viewport - The viewport being rendered. */ update(viewport?: Viewport): void; /** The slice plane the layer displays. */ get orientation(): SliceOrientation; /** * Changes the slice orientation at runtime. Visible renderables are * rebuilt for the new plane and chunks already resident in the shared * cache are reused. * * @param orientation - The new slice plane. */ setOrientation(orientation: SliceOrientation): void; private updateChunks; private rebuildRenderGroups; /** The `t` coordinate of the most recently presented slice. */ get lastPresentationTimeCoord(): number | undefined; private isPresentationStale; /** * Handles click picking for `onPickValue`. Called automatically for * each pointer event. * * @param event - The event with clip and world coordinates attached. */ onEvent(event: EventContext): void; private pickAtRay; /** The layer's chunk store view for diagnostic overlays. */ get chunkStoreView(): ChunkStoreView | undefined; /** * The slice coordinates the layer displays. This is the object passed * at construction and may be mutated to move through the data. */ get sliceCoords(): SliceCoordinates; /** The chunked image source the layer streams from. */ get source(): ChunkSource; /** * The streaming policy in effect. Assign a new policy to reschedule * loading at runtime, for example when switching between exploration * and playback. */ get imageSourcePolicy(): Readonly; /** @param newPolicy - The policy to apply. */ set imageSourcePolicy(newPolicy: ImageSourcePolicy); private getImageForChunk; private getChannelPropsForChunk; private createImage; private updateSlicePosition; private sliceIndexForChunk; private updateImageChunk; /** * Reads the data value at a world position from the resident chunks. * Prefers the current level of detail and falls back to other resident * levels. * * @param world - The world-space position to sample. * @returns The sampled value or `null` if no resident chunk covers it. */ getValueAtWorld(world: vec3): Promise; private readValueFromChunk; /** Whether chunk wireframes are drawn colored by level of detail. */ get debugMode(): boolean; /** @param debug - Whether to draw chunk wireframes. */ set debugMode(debug: boolean); /** The current per-channel appearance settings. */ get channelProps(): ChannelProps[] | undefined; /** * Applies new per-channel appearance settings to all visible chunks * and notifies channel change callbacks. * * @param channelProps - One entry per source channel. */ setChannelProps(channelProps: ChannelProps[]): void; /** Restores the channel settings passed at construction. */ resetChannelProps(): void; /** * Registers a callback invoked after every channel settings change. * * @param callback - The callback to add. */ addChannelChangeCallback(callback: () => void): void; /** * Removes a previously registered channel change callback. * * @param callback - The callback to remove. */ removeChannelChangeCallback(callback: () => void): void; private releaseAndRemoveChunks; } /** * Initialization properties for constructing a volume layer. */ type VolumeLayerProps = { /** The chunked image source to stream from. */ source: ChunkSource; /** Selects `t` and `c`. Spatial axes are ignored. */ sliceCoords: SliceCoordinates; /** Streaming policy. Defaults to the exploration policy. */ policy?: ImageSourcePolicy; /** Per-channel appearance. Length must match the source. */ channelProps?: ChannelProps[]; }; /** * A layer that renders a chunked multi-channel image source as a 3D * volume. * * Volume layer ray marches the loaded chunks with premultiplied blending * and composites all visible channels in a single pass. The volume renders * at a single level of detail taken from the policy's `lod.min`, so pin * one with the policy when constructing the layer. While the camera moves * the ray march step size is doubled to keep interaction responsive. * * ```ts * const source = await OmeZarrImageSource.fromHttp({ url }); * * const layer = new VolumeLayer({ * source, * sliceCoords: { t: 0, c: undefined }, * policy: createExplorationPolicy({ lod: { min: 2, max: 2 } }), * channelProps: [ * { color: "#00ffff", contrastLimits: [300, 1500] }, * { color: "#ff00ff", contrastLimits: [75, 500] }, * ], * }); * * viewport.addLayer(layer); * ``` * * @see {@link ImageLayer} for 2D slicing of the same data. * * @group Layers */ declare class VolumeLayer extends Layer implements ChannelsEnabled { /** Identifies the layer type as `VolumeLayer`. */ readonly type = "VolumeLayer"; /** Highlights rays of zero length for debugging. Defaults to `false`. */ debugShowDegenerateRays: boolean; /** Ray march step size relative to voxel size. Defaults to `1`. */ relativeStepSize: number; /** Scales sample opacity during compositing. Defaults to `1`. */ opacityMultiplier: number; /** Alpha where a ray stops early. Defaults to `0.99`. */ earlyTerminationAlpha: number; /** Volume ray marching reads scene depth to composite with occluding layers. */ protected requiresSceneDepth_: boolean; private readonly source_; private readonly sliceCoords_; private readonly currentVolumes_; private readonly volumeToPoolKey_; private readonly pool_; private readonly initialChannelProps_?; private readonly channelChangeCallbacks_; private policy_; private chunkStoreView_?; private channelProps_?; private lastLoadedTime_; private lastNumRenderedChannelChunks_; private interactiveStepSizeScale_; private debugShowWireframes_; /** Whether chunk bounding wireframes are drawn for debugging. */ get debugShowWireframes(): boolean; /** @param value - Whether to draw chunk wireframes. */ set debugShowWireframes(value: boolean); /** * Sets the streaming policy at runtime and reschedules loading. The * volume renders the level of detail given by the policy's `lod.min`. * * @param newPolicy - The policy to apply. */ set imageSourcePolicy(newPolicy: ImageSourcePolicy); /** * Applies new per-channel appearance settings to all visible volumes * and notifies channel change callbacks. * * @param channelProps - One entry per source channel. */ setChannelProps(channelProps: ChannelProps[]): void; /** The current per-channel appearance settings. */ get channelProps(): ChannelProps[] | undefined; /** Restores the channel settings passed at construction. */ resetChannelProps(): void; /** * Registers a callback invoked after every channel settings change. * * @param callback - The callback to add. */ addChannelChangeCallback(callback: () => void): void; /** * Removes a previously registered channel change callback. * * @param callback - The callback to remove. */ removeChannelChangeCallback(callback: () => void): void; /** * Creates a volume layer for the given source. * * @param props - Initialization properties. */ constructor({ source, sliceCoords, policy, channelProps }: VolumeLayerProps); private getOrCreateVolume; /** @hidden */ protected attach(context: IdetikContext): void; /** @hidden */ protected detach(_context: IdetikContext): void; private updateChunks; private updateVolumeTransform; private releaseAndRemoveVolume; /** * Streams chunks for the current view and rebuilds the volume set * sorted front to back. Called automatically once per frame. * * @param viewport - The viewport being rendered. */ update(viewport?: Viewport): void; private rebuildObjects; /** Returns the ray marching uniforms for this layer. */ getUniforms(): Record; } /** * Color assignments for label values. * * Values present in `lookupTable` use its color. Any other value takes a * color from `cycle` by index. Value `0` renders transparent unless the * lookup table assigns it a color. */ type LabelColorMapProps = { /** Exact colors for specific label values. */ lookupTable?: ReadonlyMap; /** Colors cycled by value. Defaults to 6 built-ins. */ cycle?: ReadonlyArray; }; /** * A validated color map with every entry resolved to a {@link Color}. * Returned by {@link LabelLayer.colorMap}. */ type LabelColorMap = { /** Exact colors for specific label values. */ readonly lookupTable: ReadonlyMap; /** Colors cycled by value. */ readonly cycle: ReadonlyArray; }; /** * Initialization properties for constructing a label image renderable. */ type LabelImageRenderableProps = { /** Width of the label image in texels. */ width: number; /** Height of the label image in texels. */ height: number; /** Scalar integer texture of label values. */ imageData: Texture; /** Colors to apply to label values. */ colorMap: LabelColorMapProps; /** Outlines the selected value. Defaults to `false`. */ outlineSelected?: boolean; /** The selected label value. Defaults to `null`. */ selectedValue?: number | null; }; /** * A textured plane that draws one 2D slice of integer label data. * * Each label value is colored through a {@link LabelColorMap}. Values in * the lookup table use its color, other values take a color from the * cycle, and value `0` renders transparent unless the lookup table covers * it. The image texture must hold scalar integer data. {@link LabelLayer} * constructs and pools one instance per visible chunk, so most * applications configure labels through the layer instead. * * @group Renderables */ declare class LabelImageRenderable extends RenderableObject { /** * A matrix mapping world space to the texture's normalized coordinate * space. Layers derive it from the chunk's offset, scale, and shape. */ worldToTexCoord: mat4; private outlineSelected_; private selectedValue_; /** * Creates a label renderable drawing the given label texture. The * texture's data type selects the matching label shader. * * @param props - Initialization properties. */ constructor(props: LabelImageRenderableProps); /** Identifies the renderable type as `LabelImageRenderable`. */ get type(): string; /** * Returns the sampler, color map, and selection uniforms for the label * image shaders. */ getUniforms(): { u_imageSampler: number; u_colorCycleSampler: number; u_colorLookupTableSampler: number; u_outlineSelected: number; u_selectedValue: number; u_worldToTexCoord: mat4; }; /** * Replaces the label color map. The previous color map textures are * marked stale for GPU disposal. * * @param colorMap - The new color map. */ setColorMap(colorMap: LabelColorMapProps): void; /** * Sets the label value drawn as selected or `null` to clear the * selection. The selected region is outlined when the renderable was * constructed with `outlineSelected`. * * @param value - The label value to select. */ setSelectedValue(value: number | null): void; private makeColorCycleTexture; private makeColorLookupTableTexture; } /** * Initialization properties for constructing a label layer. */ type LabelLayerProps = { /** The single-channel label source to stream from. */ source: ChunkSource; /** The slice to display in world units. */ sliceCoords: SliceCoordinates; /** Streaming policy. Defaults to the exploration policy. */ policy?: ImageSourcePolicy; /** Slice plane orientation. Defaults to `"XY"`. */ orientation?: SliceOrientation; /** Colors for label values. Defaults to a built-in cycle. */ colorMap?: LabelColorMapProps; /** Called with the picked label when the layer is clicked. */ onPickValue?: (info: PointPickingResult) => void; /** Outlines the picked label. Defaults to `false`. */ outlineSelected?: boolean; /** Layer opacity in `[0, 1]`. Defaults to `1`. */ opacity?: number; /** How the layer blends. Defaults to `"none"`. */ blendMode?: BlendMode; /** Hides content behind. Inferred from `blendMode`. */ occludes?: boolean; }; /** * A layer that renders a 2D slice of a single-channel label image. * * Label layer displays segmentation data where each pixel holds an * integer label. Labels are colored by cycling through the color map's * `cycle` with exact-value overrides in its `lookupTable`. Chunks stream * through the same policy machinery as {@link ImageLayer} and the source * must be single channel. * * Clicking the layer picks the label under the pointer. With * `outlineSelected` the picked label is outlined, and `onPickValue` * receives the world position and label value for custom handling such as * highlighting through {@link setColorMap}. * * ```ts * const labels = new LabelLayer({ * source: labelSource, * sliceCoords: { z: 12, c: [0] }, * opacity: 0.55, * blendMode: "normal", * onPickValue: ({ value }) => console.log(`label ${value}`), * }); * * viewport.addLayer(labels); * ``` * * @group Layers */ declare class LabelLayer extends Layer { /** Identifies the layer type as `LabelLayer`. */ readonly type = "LabelLayer"; private readonly source_; private readonly sliceCoords_; private axes_; private planeRotation_; private orientation_; private readonly onPickValue_?; private readonly outlineSelected_; private readonly visibleChunks_; private readonly pool_; private colorMap_; private selectedValue_; private policy_; private chunkStoreView_?; private context_?; private pointerDownPos_; private static readonly STALE_PRESENTATION_MS_; private lastPresentationTimeStamp_?; private lastPresentationTimeCoord_?; /** * Creates a label layer for the given source and slice. * * @param props - Initialization properties. */ constructor({ source, sliceCoords, policy, orientation, colorMap, onPickValue, outlineSelected, ...layerOptions }: LabelLayerProps); /** @hidden */ protected attach(context: IdetikContext): void; /** @hidden */ protected detach(_context: IdetikContext): void; /** * Streams chunks for the current view and refreshes the visible slice. * Called automatically once per frame. * * @param viewport - The viewport being rendered. */ update(viewport?: Viewport): void; /** The slice plane the layer displays. */ get orientation(): SliceOrientation; /** * Changes the slice orientation at runtime. Visible renderables are * rebuilt for the new plane and chunks already resident in the shared * cache are reused. * * @param orientation - The new slice plane. */ setOrientation(orientation: SliceOrientation): void; private updateChunks; private isPresentationStale; /** * Handles click picking and selection outlining. Called automatically * for each pointer event on the owning viewport. * * @param event - The event with clip and world coordinates attached. */ onEvent(event: EventContext): void; private pickAtRay; /** The validated color map currently in effect. */ get colorMap(): LabelColorMap; /** * Replaces the color map and recolors all visible chunks. * * @param colorMap - Colors for label values. Omitted fields fall back * to defaults. */ setColorMap(colorMap: LabelColorMapProps): void; /** * Sets the label value drawn as selected or `null` to clear the * selection. * * @param value - The label value to select. */ setSelectedValue(value: number | null): void; /** * The slice coordinates the layer displays. This is the object passed * at construction and may be mutated to move through the data. */ get sliceCoords(): SliceCoordinates; /** The chunked label source the layer streams from. */ get source(): ChunkSource; /** * The streaming policy in effect. Assign a new policy to reschedule * loading at runtime, for example when switching between exploration * and playback. */ get imageSourcePolicy(): Readonly; /** @param newPolicy - The policy to apply. */ set imageSourcePolicy(newPolicy: ImageSourcePolicy); /** The layer's chunk store view for diagnostic overlays. */ get chunkStoreView(): ChunkStoreView | undefined; /** The `t` coordinate of the most recently presented slice. */ get lastPresentationTimeCoord(): number | undefined; /** * Reads the label value at a world position from the resident chunks. * Prefers the current level of detail and falls back to other resident * levels. * * @param world - The world-space position to sample. * @returns The label value or `null` if no resident chunk covers it. */ getValueAtWorld(world: vec3): Promise; private readValueFromChunk; private getLabelForChunk; private createLabel; private updateSlicePosition; private sliceIndexForChunk; private updateLabelChunk; private releaseAndRemoveChunks; } /** * Initialization properties for constructing an image renderable. */ type ImageRenderableProps = { /** Width of the image in texels. */ width: number; /** Height of the image in texels. */ height: number; /** The scalar image texture to draw. */ texture: Texture; /** Channel appearance settings. Defaults to `[]`. */ channelProps?: ChannelProps[]; }; type UniformValues = { u_color: vec3; u_imageSampler: number; Opacity: number; u_valueOffset: number; u_valueScale: number; u_worldToTexCoord: mat4; }; /** * A textured plane that draws one 2D slice of scalar image data. * * Image renderable maps a scalar texture through a single channel's * color, contrast limits, and opacity. {@link ImageLayer} constructs and * pools one instance per visible chunk, so most applications never create * these directly. * * @group Renderables */ declare class ImageRenderable extends RenderableObject { /** * A matrix mapping world space to the texture's normalized coordinate * space. Layers derive it from the chunk's offset, scale, and shape. */ worldToTexCoord: mat4; private channels_; /** * Creates an image renderable drawing the given texture. The texture's * data type selects the matching scalar image shader. * * @param props - Initialization properties. */ constructor({ width, height, texture, channelProps, }: ImageRenderableProps); /** Identifies the renderable type as `ImageRenderable`. */ get type(): string; /** * Replaces the channel appearance settings and revalidates them * against the current texture. Only the first entry affects rendering. * * @param channels - The new channel settings. */ setChannelProps(channels: ChannelProps[]): void; /** * Updates one property of the channel at the given index and * revalidates the channel against the current texture. * * @param channelIndex - The channel to update. * @param property - The property name to set. * @param value - The new value. */ setChannelProperty(channelIndex: number, property: K, value: Required[K]): void; /** * Returns the sampler, contrast, color, opacity, and world-to-texture * uniforms for the scalar image shaders. */ getUniforms(): UniformValues; } type Marker = "circle" | "square" | "triangle"; /** * Initialization properties for a point in {@link PointsRenderable}. */ type PointProps = { /** World-space position of the point. */ position: vec3; /** Fill color of the marker. */ color: ColorLike; /** Marker size in pixels. */ size: number; /** Marker shape. */ marker: Marker; }; /** * A set of point markers drawn as screen-space sprites. * * Each point has a world-space position, a color, a size in pixels, and a * marker shape. All instances share a single marker sprite atlas. The * point set is fixed at construction, so build a new instance to change * it. Construct these directly inside a custom {@link Layer}. * * ```ts * class Particles extends Layer { * public readonly type = "Particles"; * * constructor(positions: vec3[]) { * super(); * this.addObject( * new PointsRenderable( * positions.map((position) => ({ * position, * color: Color.RED, * size: 20, * marker: "circle" as const, * })) * ) * ); * this.setState("ready"); * } * * public update() {} * } * ``` * * @group Renderables */ declare class PointsRenderable extends RenderableObject { /** * Creates a renderable drawing one marker per entry. * * @param points - The points to draw. */ constructor(points: PointProps[]); /** Identifies the renderable type as `PointsRenderable`. */ get type(): string; } declare class ProjectedLineGeometry extends Geometry { constructor(path: vec3[]); private createVertices; private createIndex; } /** * Initialization properties for constructing a projected line renderable. */ type ProjectedLineRenderableProps = { /** The line path geometry to draw. */ geometry: ProjectedLineGeometry; /** The line color. */ color: ColorLike; /** Line width in pixels. */ width: number; }; /** * A polyline drawn with a constant screen-space width. * * The line is extruded in the vertex shader so its width stays fixed in * pixels at any zoom level. Custom layers can construct it directly for * paths and outlines. * * @group Renderables */ declare class ProjectedLineRenderable extends RenderableObject { private color_; private width_; /** * Creates a projected line renderable for the given path geometry. * * @param props - Initialization properties. */ constructor({ geometry, color, width }: ProjectedLineRenderableProps); /** Identifies the renderable type as `ProjectedLineRenderable`. */ get type(): string; /** The line color. Assignable from any {@link ColorLike} value. */ get color(): Color; /** @param value - The new line color. */ set color(value: ColorLike); /** The line width in pixels. */ get width(): number; /** @param value - The new width in pixels. */ set width(value: number); /** Returns the color and width uniforms for the line shader. */ getUniforms(): { u_lineColor: [number, number, number]; u_lineWidth: number; }; } /** * Initialization properties for constructing a volume renderable. */ type VolumeRenderableProps = { /** Channel appearance settings. Defaults to `[]`. */ channelProps?: ChannelProps[]; }; /** * A ray-marched box that draws multi-channel volumetric data. * * The renderable draws a unit box and ray marches through 3D chunk * textures in the fragment shader. Up to 4 channels blend in a single * pass and all loaded channels must share one texture data type. Front * faces are culled and depth testing is off by default. * {@link VolumeLayer} constructs and pools one instance per spatial chunk * group, streams chunk textures in with {@link updateVolumeWithChunk}, * and sizes the box through the transform. * * @group Renderables */ declare class VolumeRenderable extends RenderableObject { /** * World size of a voxel along each axis. Layers set it from the chunk * scale so ray march steps account for anisotropic voxels. Defaults to * `[1, 1, 1]`. */ voxelScale: vec3; private channels_; private loadedChannels_; private readonly channelToTextureIndex_; /** * Creates an empty volume renderable. * * @param props - Initialization properties. */ constructor({ channelProps }?: VolumeRenderableProps); /** Identifies the renderable type as `VolumeRenderable`. */ get type(): string; /** * Loads or refreshes the texture for the chunk's channel. The channel * index comes from the chunk and the texture's data type selects the * volume shader, so every channel must share one data type. Chunks * without a texture are ignored. * * @param chunk - The chunk holding the channel texture. */ updateVolumeWithChunk(chunk: Chunk): void; private addChannelTexture; private updateChannelTexture; /** * Marks all channels as not loaded so they stop rendering until the * next chunk update. The textures themselves are kept. */ clearLoadedChannels(): void; /** * Clears all textures and channel state so the renderable can be * pooled and reused for another chunk. */ reset(): void; /** * Returns per-channel sampler, color, contrast, opacity, and * visibility uniforms for up to 4 loaded channels plus the voxel * scale. */ getUniforms(): Record; /** * Get an available texture for a channel. If desiredChannelIndex is provided, it will try to return the texture for that channel index. If that texture is not available, or no desiredChannelIndex is passed, return the first available channel texture. This is used to determine which texture to use when updating channel properties, since channel properties can be updated even if the channel's texture hasn't been loaded yet. If no textures are available, it returns null, which signals that default contrast limits should be used when validating the channel properties. */ private getAvailableChannelTexture; /** * Replaces the appearance settings for all channels. * * @param channels - The new channel settings. */ setChannelProps(channels: ChannelProps[]): void; /** * Updates one property of the channel at the given index and * revalidates it against the channel's texture when available. * * @param channelIndex - The channel to update. * @param property - The property name to set. * @param value - The new value. */ setChannelProperty(channelIndex: number, property: K, value: Required[K]): void; } /** * Initialization properties for constructing a perspective camera. */ type PerspectiveCameraProps = { /** Vertical field of view in degrees. Defaults to `60`. */ fov?: number; /** Aspect ratio (width / height). Defaults to `1.77`. */ aspectRatio?: number; /** Near clipping plane distance. Defaults to `0.1`. */ near?: number; /** Far clipping plane distance. Defaults to `10000`. */ far?: number; /** World-space camera position. Defaults to the origin. */ position?: vec3; }; /** * A camera using a perspective projection. * * Perspective projection applies foreshortening: objects appear smaller the * farther they are from the camera, which makes this the camera to use for * 3D scenes such as volume rendering. It pairs naturally with * {@link OrbitControls}. * * The projection is defined by a vertical field of view, an aspect ratio, * and near/far clipping planes. Zooming narrows or widens the field of view * rather than moving the camera. * * ```ts * const camera = new PerspectiveCamera({ fov: 45 }); * * const controls = new OrbitControls(camera, { * radius: 1200, * target: [0, 0, 0], * }); * * const idetik = new Idetik({ * canvas: document.querySelector('canvas')!, * viewports: [{ camera, layers: [volumeLayer], cameraControls: controls }], * }); * ``` * * @see {@link OrthographicCamera} for 2D image viewing with parallel * projection. * * @group Cameras */ declare class PerspectiveCamera extends Camera { private fov_; private aspectRatio_; /** * Creates a perspective camera from the given projection settings. * * @param props - Initialization properties. */ constructor(props?: PerspectiveCameraProps); /** * Sets the aspect ratio (width / height) of the viewport the camera * renders into. Called automatically by the owning viewport when it * resizes. * * @param aspectRatio - The viewport's width divided by its height. */ setAspectRatio(aspectRatio: number): void; /** Identifies the camera type as `PerspectiveCamera`. */ get type(): CameraType; /** The vertical field of view in degrees. */ get fov(): number; /** * Zooms the view by the given factor relative to the current zoom level. * Factors greater than `1` zoom in and factors between `0` and `1` zoom * out. * * Zooming narrows or widens the field of view rather than moving the * camera, and the result is clamped to valid angles. * * @param factor - The magnification factor to apply. */ zoom(factor: number): void; /** @hidden */ protected updateProjectionMatrix(): void; } /** * Initialization properties for constructing orbit controls. */ type OrbitControlsProps = { /** Distance from the target in world units. Defaults to `1`. */ radius?: number; /** Initial azimuth angle in radians. Defaults to `0`. */ yaw?: number; /** Initial elevation angle in radians. Defaults to `0`. */ pitch?: number; /** The point the camera orbits. Defaults to the origin. */ target?: vec3; /** Velocity decay rate between `0` and `1`. Defaults to `0.5`. */ dampingFactor?: number; /** When the scroll wheel zooms. Defaults to `"always"`. */ scrollZoom?: ScrollZoomMode; }; /** * Camera controls for orbiting a perspective camera around a target. * * Dragging with the left mouse button orbits, dragging with `Shift` held * or with the middle button pans the target, and the scroll wheel zooms by * changing the orbit radius. Input adds velocity that damping decays over time. * * ```ts * const camera = new PerspectiveCamera({ near: 1.0 }); * * const idetik = new Idetik({ * canvas, * viewports: [{ * camera, * layers: [volumeLayer], * cameraControls: new OrbitControls(camera, { * radius: 100, * target: [40, 40, 10], * }), * }], * }); * ``` * * @group Controls */ declare class OrbitControls implements CameraControls { private readonly camera_; private readonly orbitVelocity_; private readonly panVelocity_; private readonly currPos_; private readonly currCenter_; private readonly dampingFactor_; private readonly scrollZoom_; private currMouseButton_; /** * Creates orbit controls and moves the camera to the initial pose. * * @param camera - The perspective camera to control. * @param params - Initialization properties. */ constructor(camera: PerspectiveCamera, params?: OrbitControlsProps); /** The current distance from the target in world units. */ get radius(): number; /** The current azimuth angle in radians. */ get yaw(): number; /** The current elevation angle in radians. */ get pitch(): number; /** A copy of the point the camera orbits. */ get target(): vec3; /** Whether any orbit, pan, or zoom velocity remains. */ get isMoving(): boolean; /** * Handles a pointer or wheel event. Called automatically by the owning * viewport unless a layer stops propagation. * * @param event - The event with clip and world coordinates attached. */ onEvent(event: EventContext): void; /** * Applies pending velocities to the camera and decays them toward zero. * Called automatically by the render loop once per frame. * * @param dt - Time since the last frame in seconds. */ onUpdate(dt: number): void; private onPointerDown; private onPointerMove; private onWheel; private onPointerEnd; private orbit; private pan; private zoom; private updateCamera; private cutoffLowVelocity; } export { AxesLayer, Box2, Box3, Camera, Color, Frustum, Idetik, ImageLayer, ImageRenderable, LabelImageRenderable, LabelLayer, Layer, OmeZarrImageSource, OrbitControls, OrthographicCamera, PanZoomControls, PerspectiveCamera, PointsRenderable, ProjectedLineRenderable, RenderableObject, TrsTransform, Viewport, VolumeLayer, VolumeRenderable, createExplorationPolicy, createImageSourcePolicy, createNoPrefetchPolicy, createPlaybackPolicy, loadOmeZarrPlate, loadOmeZarrWell, loadOmeroChannels, loadOmeroDefaults }; export type { AxesLayerProps, BlendMode, CameraControls, CameraType, ChannelProps, ColorLike, FileSystemOmeZarrImageSourceProps, HttpOmeZarrImageSourceProps, IdetikProps, ImageLayerProps, ImageRenderableProps, ImageSourcePolicy, ImageSourcePolicyProps, LabelColorMap, LabelColorMapProps, LabelImageRenderableProps, LabelLayerProps, LayerProps, LayerState, MemoryStats, OrbitControlsProps, OrthographicCameraFrame, OrthographicCameraProps, Overlay, PanZoomControlsProps, PerspectiveCameraProps, PointPickingResult, PointProps, PriorityCategory, ProjectedLineRenderableProps, QueueStats, SliceCoordinates, SliceOrientation, SourceDimension, SourceDimensionLod, SourceDimensionMap, StateChangeCallback, ViewportProps, VolumeLayerProps, VolumeRenderableProps };