@react-three/fiber
Version:
A React renderer for Threejs
131 lines (130 loc) • 5.21 kB
TypeScript
/// <reference types="webxr" />
import * as THREE from 'three';
import * as React from 'react';
import { type StoreApi } from 'zustand';
import { type UseBoundStoreWithEqualityFn } from 'zustand/traditional';
import type { DomEvent, EventManager, PointerCaptureTarget, ThreeEvent } from "./events.js";
import { type Camera } from "./utils.js";
export interface Intersection extends THREE.Intersection {
eventObject: THREE.Object3D;
}
export type Subscription = {
ref: React.RefObject<RenderCallback>;
priority: number;
store: RootStore;
};
export type Dpr = number | [min: number, max: number];
export interface Size {
width: number;
height: number;
top: number;
left: number;
}
export type Frameloop = 'always' | 'demand' | 'never';
export interface Viewport extends Size {
/** The initial pixel ratio */
initialDpr: number;
/** Current pixel ratio */
dpr: number;
/** size.width / viewport.width */
factor: number;
/** Camera distance */
distance: number;
/** Camera aspect ratio: width / height */
aspect: number;
}
export type RenderCallback = (state: RootState, delta: number, frame?: XRFrame) => void;
export interface Performance {
/** Current performance normal, between min and max */
current: number;
/** How low the performance can go, between 0 and max */
min: number;
/** How high the performance can go, between min and max */
max: number;
/** Time until current returns to max in ms */
debounce: number;
/** Sets current to min, puts the system in regression */
regress: () => void;
}
export interface Renderer {
render: (scene: THREE.Scene, camera: THREE.Camera) => any;
}
export declare const isRenderer: (def: any) => boolean;
export interface InternalState {
interaction: THREE.Object3D[];
hovered: Map<string, ThreeEvent<DomEvent>>;
subscribers: Subscription[];
capturedMap: Map<number, Map<THREE.Object3D, PointerCaptureTarget>>;
initialClick: [x: number, y: number];
initialHits: THREE.Object3D[];
lastEvent: React.RefObject<DomEvent | null>;
active: boolean;
priority: number;
frames: number;
subscribe: (callback: React.RefObject<RenderCallback>, priority: number, store: RootStore) => () => void;
}
export interface XRManager {
connect: () => void;
disconnect: () => void;
}
export interface RootState {
/** Set current state */
set: StoreApi<RootState>['setState'];
/** Get current state */
get: StoreApi<RootState>['getState'];
/** The instance of the renderer */
gl: THREE.WebGLRenderer;
/** Default camera */
camera: Camera;
/** Default scene */
scene: THREE.Scene;
/** Default raycaster */
raycaster: THREE.Raycaster;
/** Default clock */
clock: THREE.Clock;
/** Event layer interface, contains the event handler and the node they're connected to */
events: EventManager<any>;
/** XR interface */
xr: XRManager;
/** Currently used controls */
controls: THREE.EventDispatcher | null;
/** Normalized event coordinates */
pointer: THREE.Vector2;
/** @deprecated Normalized event coordinates, use "pointer" instead! */
mouse: THREE.Vector2;
legacy: boolean;
/** Shortcut to gl.outputColorSpace = THREE.LinearSRGBColorSpace */
linear: boolean;
/** Shortcut to gl.toneMapping = NoTonemapping */
flat: boolean;
/** Render loop flags */
frameloop: Frameloop;
performance: Performance;
/** Reactive pixel-size of the canvas */
size: Size;
/** Reactive size of the viewport in threejs units */
viewport: Viewport & {
getCurrentViewport: (camera?: Camera, target?: THREE.Vector3 | Parameters<THREE.Vector3['set']>, size?: Size) => Omit<Viewport, 'dpr' | 'initialDpr'>;
};
/** Flags the canvas for render, but doesn't render in itself */
invalidate: (frames?: number) => void;
/** Advance (render) one step */
advance: (timestamp: number, runGlobalEffects?: boolean) => void;
/** Shortcut to setting the event layer */
setEvents: (events: Partial<EventManager<any>>) => void;
/** Shortcut to manual sizing */
setSize: (width: number, height: number, top?: number, left?: number) => void;
/** Shortcut to manual setting the pixel ratio */
setDpr: (dpr: Dpr) => void;
/** Shortcut to setting frameloop flags */
setFrameloop: (frameloop: Frameloop) => void;
/** When the canvas was clicked but nothing was hit */
onPointerMissed?: (event: MouseEvent) => void;
/** If this state model is layered (via createPortal) then this contains the previous layer */
previousRoot?: RootStore;
/** Internals */
internal: InternalState;
}
export type RootStore = UseBoundStoreWithEqualityFn<StoreApi<RootState>>;
export declare const context: React.Context<RootStore>;
export declare const createStore: (invalidate: (state?: RootState, frames?: number) => void, advance: (timestamp: number, runGlobalEffects?: boolean, state?: RootState, frame?: XRFrame) => void) => RootStore;