three-viewport-gizmo
Version:
Three Viewport Gizmo is a highly customizable standalone interactive three.js view helper controls, allowing effortless integration with popular camera libraries.
569 lines (562 loc) • 23.4 kB
TypeScript
import { ColorRepresentation } from 'three';
import { DeepRequired } from 'utility-types';
import { Object3D } from 'three';
import { Object3DEventMap } from 'three';
import { OrbitControls } from 'three/examples/jsm/Addons.js';
import { OrthographicCamera } from 'three';
import { PerspectiveCamera } from 'three';
import { Vector3 } from 'three';
import { WebGLRenderer } from 'three';
import { WebGPURenderer } from 'three/webgpu';
/**
* Configuration options for individual gizmo axes.
* Each axis can be customized with its own appearance and behavior.
*/
export declare type GizmoAxisOptions = {
/** Whether to draw the axis. Default `true` */
enabled?: boolean;
/** Custom text label for the axis. If not specified, defaults to the axis name */
label?: string;
/** The axis opacity. Default `1` */
opacity?: number;
/** The scale multiplayer for the indicator size. Default `1` */
scale?: number;
/** Whether to draw the the axis line. */
line?: boolean;
/** The axis indicator background color. */
color?: ColorRepresentation;
/** Color for the axis text label */
labelColor?: ColorRepresentation;
/** The border around the axis indicator. */
border?: {
/** The border size around the axis indicator. */
size: number;
/** The border color around the axis indicator. */
color: ColorRepresentation;
};
/** The axis indicator hover options. */
hover?: {
/** The fill color on hover */
color?: ColorRepresentation;
/** The label text color when the axis is hovered. */
labelColor?: ColorRepresentation;
/** The opacity when the axis is hovered. Default `1` */
opacity?: number;
/** The indicator scale multiplayer when the axis is hovered Default `1` */
scale?: number;
/** The border around the axis indicator. */
border?: {
/** The border size around the axis indicator. */
size: number;
/** The border color around the axis indicator. */
color: ColorRepresentation;
};
};
};
/**
* Configuration options for the ViewportGizmo.
* All properties are optional and will fall back to default values if not specified.
*/
export declare type GizmoOptions = {
/** Parent element for the gizmo. Can be an HTMLElement or a CSS selector string */
container?: HTMLElement | string;
/** The Gizmo support two types a `sphere` and a `cube` configuration. Default `sphere` */
type?: "sphere" | "cube";
/** Size of the gizmo widget in pixels. Default `128`*/
size?: number;
/**
* Represents the possible placement positions of the gizmo widget in the viewport.
* The position is determined by combining vertical alignment (top, center, bottom)
* with horizontal alignment (left, center, right).
*/
placement?: "top-left" | "top-center" | "top-right" | "center-left" | "center-center" | "center-right" | "bottom-left" | "bottom-center" | "bottom-right";
/** Offset of the gizmo from the container edges in pixels. */
offset?: {
/** Offset from the left edge in pixel. Default `10` */
left?: number;
/** Offset from the top edge in pixel. Default `10` */
top?: number;
/** Offset from the right edge in pixel. Default `10` */
right?: number;
/** Offset from the bottom edge in pixel. Default `10` */
bottom?: number;
};
/** Whether view changes should be animated. Default `true` */
animated?: boolean;
/** Animation speed multiplier. Higher values result in faster animations. Default `1` */
speed?: number;
/**
* The texture resolution. Higher values improve quality at the cost of performance.
* Default `64` for a `sphere` type, and `128` for the cube.
**/
resolution?: number;
/** The width of the axes lines material in pixels. LineMaterial2 */
lineWidth?: number;
/** HTML `id` attribute for the gizmo container */
id?: string;
/** HTML `class` attribute for the gizmo container */
className?: string;
/**
* Font configuration for axis labels.
* Follows standard CSS font properties.
*/
font?: {
/** Font family for axis labels */
family?: string;
/** Font weight for axis labels */
weight?: string | number;
};
/**
* The gizmo background configuration.
* The sphere provides visual context for the current orientation.
*/
background?: {
/** Whether to display the background sphere */
enabled?: boolean;
/** Color of the background sphere in normal state */
color?: ColorRepresentation;
/** Opacity of the background sphere in normal state (0-1) */
opacity?: number;
hover?: {
/** Color of the background sphere when hovered */
color?: ColorRepresentation;
/** Opacity of the background sphere when hovered (0-1) */
opacity?: number;
};
};
/**
* Configuration for the corner axes indicators of the gizmo.
* Corners provide additional visual cues for orientation, particularly useful in cube mode.
*/
corners?: {
/** Whether to display corner indicators. Default `true` */
enabled?: boolean;
/** Base color of the corner indicators in normal state */
color?: ColorRepresentation;
/** Opacity of corner indicators in normal state (0-1). Default `1` */
opacity?: number;
/** Scale multiplier for corner indicator size. Default `1` */
scale?: number;
/** Radius of the corner indicators in range [0, 1]. Controls the roundness.
* Default `1` for sphere type, `0.2` for the cube type.
*/
radius?: number;
/** Smoothness of the corner indicators. Higher values create smoother transitions. Default `18` */
smoothness?: number;
/** Corner indicator appearance when hovered */
hover?: {
/** Color of corner indicators when hovered */
color?: ColorRepresentation;
/** Opacity of corner indicators when hovered (0-1) */
opacity?: number;
/** Scale multiplier for corner indicators when hovered */
scale?: number;
};
};
/**
* Configuration for the edge indicators of the gizmo.
* Edges help define the boundaries between faces and improve spatial understanding.
*/
edges?: {
/** Whether to display edge indicators. Default `true` */
enabled?: boolean;
/** Base color of the edge indicators in normal state */
color?: ColorRepresentation;
/** Opacity of edge indicators in normal state (0-1). Default `1` */
opacity?: number;
/** Scale multiplier for edge indicator thickness. Default `1` */
scale?: number;
/** Radius of the edge indicators in pixels. Controls the roundness. Default `2` */
radius?: number;
/** Smoothness of the edge indicators (1-10). Higher values create smoother transitions. Default `8` */
smoothness?: number;
/** Edge indicator appearance when hovered */
hover?: {
/** Color of edge indicators when hovered */
color?: ColorRepresentation;
/** Opacity of edge indicators when hovered (0-1) */
opacity?: number;
/** Scale multiplier for edge indicators when hovered */
scale?: number;
};
};
/** The axes edge radius, applied to all axes */
radius?: number;
/** The axes edge smoothness, applied to all axes */
smoothness?: number;
/**
* Configuration for positive `X` axis or the `Right` face.
* @see {@link GizmoAxisOptions}
*/
x?: GizmoAxisOptions;
/**
* Configuration for positive `Y` axis or the `Top` face.
* @see {@link GizmoAxisOptions}
*/
y?: GizmoAxisOptions;
/**
* Configuration for positive `Z` axis or the `Front` face.
* @see {@link GizmoAxisOptions}
*/
z?: GizmoAxisOptions;
/**
* Configuration for negative X axis or the `Left` face.
* @see {@link GizmoAxisOptions}
*/
nx?: GizmoAxisOptions;
/**
* Configuration for negative Y axis or the `Bottom` face.
* @see {@link GizmoAxisOptions}
*/
ny?: GizmoAxisOptions;
/**
* Configuration for negative Z axis or the `Back` face.
* @see {@link GizmoAxisOptions}
*/
nz?: GizmoAxisOptions;
/**
* @alias An alias for the negative `x` axis configuration `options.nx`,
* can be used with a cube configuration for more clarity.
*
* @see {@link GizmoAxisOptions}
*/
right?: GizmoAxisOptions;
/**
* @alias An alias for the `y` axis configuration `options.y`,
* can be used with a cube configuration for more clarity.
*
* @see {@link GizmoAxisOptions}
*/
top?: GizmoAxisOptions;
/**
* @alias An alias for the `z` axis configuration `options.z`,
* can be used with a cube configuration for more clarity.
*
* @see {@link GizmoAxisOptions}
*/
front?: GizmoAxisOptions;
/**
* @alias An alias for the `x` axis configuration `options.x`,
* can be used with a cube configuration for more clarity.
*
* @see {@link GizmoAxisOptions}
*/
left?: GizmoAxisOptions;
/**
* @alias An alias for the negative `y` axis configuration `options.ny`,
* can be used with a cube configuration for more clarity.
*
* @see {@link GizmoAxisOptions}
*/
bottom?: GizmoAxisOptions;
/**
* @alias An alias for the negative `z` axis configuration `options.nz`,
* can be used with a cube configuration for more clarity.
*
* @see {@link GizmoAxisOptions}
*/
back?: GizmoAxisOptions;
};
/** The {@link GizmoOptions } with all options set with their respective default and fallback */
declare type GizmoOptionsFallback = DeepRequired<GizmoOptions> & {
isSphere: boolean;
};
/**
* ViewportGizmo is a 3D camera orientation controller that provides a visual interface
* for changing the camera's viewing angle. It creates a widget that shows the current
* camera orientation and allows direct manipulation of the view through clicking or dragging.
*
* @fires ViewportGizmo#start - Fired when a view change interaction begins
* @fires ViewportGizmo#change - Fired during view changes
* @fires ViewportGizmo#end - Fired when a view change interaction ends
*
* @extends Object3D
*/
export declare class ViewportGizmo extends Object3D<ViewportGizmoEventMap> {
/** Whether the gizmo is currently active and responding to user input */
enabled: boolean;
/** The camera being controlled by this gizmo */
camera: OrthographicCamera | PerspectiveCamera;
/** The WebGLRenderer rendering the gizmo */
renderer: WebGLRenderer | WebGPURenderer;
/** The configuration options */
options: GizmoOptions;
/** The point around which the camera rotates */
target: Vector3;
/** Whether view changes should be animated */
animated: boolean;
/** The speed of view change animations. Higher values result in faster animations */
speed: number;
/**
* Indicates whether the gizmo is currently being animated or not,
* Useful when interacting with other camera controllers
*
* @readonly This value is set internally.
**/
animating: boolean;
private _options;
private _intersections;
private _background;
private _viewport;
private _originalViewport;
private _originalScissor;
private _scene;
private _camera;
private _container;
private _domElement;
private _domRect;
private _dragging;
private _distance;
private _clock;
private _targetQuaternion;
private _quaternionStart;
private _quaternionEnd;
private _pointerStart;
private _focus;
private _placement;
private _controls?;
private _controlsListeners?;
/**
* Creates a new ViewportGizmo instance.
*
* @param camera - The camera to be controlled by this gizmo
* @param renderer - The WebGL renderer used to render the scene
* @param options - {@link GizmoOptions}, Configuration options for the gizmo.
* @param options.container - Parent element for the gizmo. Can be an HTMLElement or a CSS selector string
* @param options.type - The gizmo configuration type. Either 'sphere' or 'cube', defaults to 'sphere'
* @param options.size - Size of the gizmo widget in pixels. Defaults to 128
* @param options.placement - Position of the gizmo in the viewport
* Options include:
* - `"top-left"`
* - `"top-center"`
* - `"top-right"`
* - `"center-left"`
* - `"center-center"`
* - `"center-right"`
* - `"bottom-left"`
* - `"bottom-center"`
* - `"bottom-right"`
* @param options.offset - Offset of the gizmo from container edges in pixels
* @param options.offset.left - Offset from the left edge
* @param options.offset.top - Offset from the top edge
* @param options.offset.right - Offset from the right edge
* @param options.offset.bottom - Offset from the bottom edge
* @param options.animated - Whether view changes should be animated. Defaults to true
* @param options.speed - Animation speed multiplier. Defaults to 1
* @param options.resolution - Texture resolution. Defaults to 64 for sphere, 128 for cube
* @param options.lineWidth - Width of the axes lines in pixels
* @param options.id - HTML `id` attribute for the gizmo container
* @param options.className - HTML `class` attribute for the gizmo container
* @param options.font - Font configuration for axis labels
* @param options.font.family - Font family for axis labels
* @param options.font.weight - Font weight for axis labels
* @param options.background - Configuration for the background sphere/cube
* @param options.background.enabled - Whether to display the background
* @param options.background.color - Color of the background in normal state
* @param options.background.opacity - Opacity of the background in normal state
* @param options.background.hover.color - Color of the background when hovered
* @param options.background.hover.opacity - Opacity of the background when hovered
* @param options.corners - Configuration for corner indicators
* @param options.corners.enabled - Whether to display corner indicators
* @param options.corners.color - Base color of corner indicators
* @param options.corners.opacity - Opacity of corner indicators
* @param options.corners.scale - Scale multiplier for corner indicators
* @param options.corners.radius - Radius of corner indicators
* @param options.corners.smoothness - Smoothness of corner indicators
* @param options.corners.hover.color - Color of corner indicators when hovered
* @param options.corners.hover.opacity - Opacity of corner indicators when hovered
* @param options.corners.hover.scale - Scale of corner indicators when hovered
* @param options.edges - Configuration for edge indicators
* @param options.edges.enabled - Whether to display edge indicators
* @param options.edges.color - Base color of edge indicators
* @param options.edges.opacity - Opacity of edge indicators
* @param options.edges.scale - Scale multiplier for edge indicators
* @param options.edges.radius - Radius of edge indicators
* @param options.edges.smoothness - Smoothness of edge indicators
* @param options.edges.hover.color - Color of edge indicators when hovered
* @param options.edges.hover.opacity - Opacity of edge indicators when hovered
* @param options.edges.hover.scale - Scale of edge indicators when hovered
* @param options.x - Configuration for positive X axis/face
* @param options.y - Configuration for positive Y axis/face
* @param options.z - Configuration for positive Z axis/face
* @param options.nx - Configuration for negative X axis/face
* @param options.ny - Configuration for negative Y axis/face
* @param options.nz - Configuration for negative Z axis/face
*
* @remarks Axis-specific configuration can also use alias names for cube mode:
* - `right` (same as `x`)
* - `left` (same as `nx`)
* - `top` (same as `y`)
* - `bottom` (same as `ny`)
* - `front` (same as `z`)
* - `back` (same as `nz`)
*
* For each axis/face configuration, the following options are available:
* @param options.AXIS.enabled - Whether to draw the axis
* @param options.AXIS.label - Custom text label for the axis
* @param options.AXIS.opacity - Axis opacity
* @param options.AXIS.scale - Scale multiplier for indicator size
* @param options.AXIS.line - Whether to draw the axis line
* @param options.AXIS.color - Axis indicator background color
* @param options.AXIS.labelColor - Axis label color
* @param options.AXIS.border.size - Border size around the axis indicator
* @param options.AXIS.border.color - Border color around the axis indicator
* @param options.AXIS.hover.color - Fill color on hover
* @param options.AXIS.hover.labelColor - Label text color on hover
* @param options.AXIS.hover.opacity - Opacity when hovered
* @param options.AXIS.hover.scale - Indicator scale when hovered
* @param options.AXIS.hover.border.size - Hover border size
* @param options.AXIS.hover.border.color - Hover border color
*/
constructor(camera: PerspectiveCamera | OrthographicCamera, renderer: WebGLRenderer | WebGPURenderer, options?: GizmoOptions);
/** Gets the current placement of the gizmo relative to its container. */
get placement(): GizmoOptionsFallback["placement"];
/**
* Sets and update the placement of the gizmo relative to its container.
*
* @param placement - The new placement position
*/
set placement(placement: GizmoOptionsFallback["placement"]);
/**
* Regenerates the gizmo with the new options.
*
* @remarks
* - Not recommended for use in real-time rendering or animation loops
* - Provides a way to completely rebuild the gizmo with new options
* - Can be computationally expensive, so use sparingly
*/
set(options?: GizmoOptions): this;
/**
* Renders the gizmo to the screen.
* This method handles viewport and scissor management to ensure the gizmo
* renders correctly without affecting the main scene rendering.
*
* @returns The gizmo instance for method chaining
*/
render(): this;
/**
* Updates the gizmo's DOM-related properties based on its current position
* and size in the document.
*
* @returns The gizmo instance for method chaining
*/
domUpdate(): this;
/**
* Updates the gizmo's orientation to match the current camera orientation.
*
* @returns The gizmo instance for method chaining
*/
cameraUpdate(): this;
/**
* Performs a complete update of the gizmo, including both DOM and camera-related updates.
*
* @param controls - Internal. Set to `false` if the update event comes from the attached controls.
*
* @returns The gizmo instance for method chaining
*/
update(controls?: boolean): this;
/**
* Connects OrbitControls with the gizmo, handling interaction states and updates.
* Automatically detaches any previously attached controls.
*
* @param controls - The scene's {@link https://threejs.org/docs/#examples/en/controls/OrbitControls OrbitControls}
*/
attachControls(controls: OrbitControls): this;
/** Removes all control event listeners and references. Safe to call multiple times. */
detachControls(): this | undefined;
/** Cleans up all resources including geometries, materials, textures, and event listeners. */
dispose(): void;
/**
* Updates the gizmo's orientation either based on the camera or internal state.
*
* @private
* @param fromCamera - Whether to update based on camera orientation (true) or internal state (false)
*/
private _updateOrientation;
/**
* Handles the animation of camera position and orientation changes.
*
* @private
*/
private _animate;
/**
* Sets the camera orientation to look at the target from a specific axis.
*
* @private
* @param position - The axis point position
*/
private _setOrientation;
/**
* Handles the pointer down event for starting drag operations.
*
* @private
* @param e - The pointer event
*/
private _onPointerDown;
/**
* Converts the input-coordinates from the standard Y-axis up to what is set in Object3D.DEFAULT_UP.
*
* @private
* @param target - The target Vector3 to be converted
* @param isSpherical - Whether or not the coordinates are for a sphere
* @returns The converted coordinates
*/
private coordinateConversion;
/**
* Handles pointer move events for hover effects and drag operations.
*
* @private
* @param e - The pointer event
*/
private _onPointerMove;
/**
* Handles pointer leave events to reset hover states.
*
* @private
*/
private _onPointerLeave;
/**
* Handles click events for axis selection.
*
* @private
* @param e - The pointer event
*/
private _handleClick;
/**
* Handles hover effects for interactive elements.
*
* @private
* @param e - The pointer event
*/
private _handleHover;
}
/**
* Map of custom events emitted by the ViewportGizmo.
* Extends Three.js Object3D events with gizmo-specific interaction events.
* @extends Object3DEventMap
*/
export declare interface ViewportGizmoEventMap extends Object3DEventMap {
/**
* Fired when a view change interaction begins.
* This can be triggered by:
* - Starting a drag operation
* - Clicking an axis to start a view transition
*/
start: {};
/**
* Fired when a view change interaction completes.
* This can be triggered by:
* - Releasing a drag operation
* - Completing a view transition animation
*/
end: {};
/**
* Fired during view changes.
* This can be triggered by:
* - Active drag operations updating the view
* - View transition animations in progress
* - Any other camera orientation updates
*/
change: {};
}
export { }