# HandleGizmo

Class · extends [`DragGizmo`](https://api.playcanvas.com/engine/classes/DragGizmo.md) · category: Gizmo

Source: https://github.com/playcanvas/engine/blob/64089771243fe28a9b9d2b4de538b99b07c75097/src/extras/gizmo/handle/handle-gizmo.js#L133

The base class of gizmos that draw world-sized overlay shapes, such as a camera frustum or a
light shape, with handles that drag to edit them once large enough on screen.

Use a layer that keeps the scene depth, so occluded parts use the `occluded` color, and sorts
transparent mesh instances manually, as [Gizmo.createLayer](https://api.playcanvas.com/engine/classes/Gizmo.md#createlayer) makes with `depth` set.

```javascript
const layer = Gizmo.createLayer(app, 'Overlays', undefined, true);
```

## Constructors

### constructor

```ts
new HandleGizmo(camera: CameraComponent, layer: Layer, name?: string)
```

Creates a new HandleGizmo object.

**Parameters**

- `camera` ([`CameraComponent`](https://api.playcanvas.com/engine/classes/CameraComponent.md)): The camera component.
- `layer` ([`Layer`](https://api.playcanvas.com/engine/classes/Layer.md)): The render layer.
- `name` (`string`, optional, default `'gizmo:handle'`): The name of the gizmo.

## Properties

### _drag

```ts
protected _drag: GizmoHandle
```

The dragged handle, as it was at the start of the drag.

### _dragging

```ts
protected _dragging: boolean = false
```

Whether a handle is being dragged.

### _renderer

```ts
protected _renderer: OverlayRenderer
```

The overlay renderer.

### _theme

```ts
protected _theme: HandleGizmoTheme
```

Internal theme.

### handles

```ts
handles: boolean = true
```

Whether to show handles that edit the shapes. Defaults to true.

### icon

```ts
icon: boolean = true
```

Whether to show an icon at each node. Defaults to true.

### readout

```ts
readout: boolean = true
```

Whether to show the value of a hovered or dragged handle. Defaults to true.

## Accessors

### handleSize

```ts
get handleSize(): number
set handleSize(value: number)
```

Gets the handle size in CSS pixels.

### iconSize

```ts
get iconSize(): number
set iconSize(value: number)
```

Gets the icon size in CSS pixels.

### lineThickness

```ts
get lineThickness(): number
set lineThickness(value: number)
```

Gets the line thickness in CSS pixels.

### theme

```ts
get theme(): HandleGizmoTheme
```

Gets the current theme for the gizmo.

## Methods

### _active

```ts
protected _active(node: GraphNode | null, name: string, index: number): boolean
```

Gets whether the handle editing a value is hovered or dragged.

**Parameters**

- `node` ([`GraphNode`](https://api.playcanvas.com/engine/classes/GraphNode.md) `| null`): The node the handle edits, or null for a shape gizmo.
- `name` (`string`): The value the handle edits.
- `index` (`number`): The index of the handle among those editing the value.

**Returns** `boolean`: Whether the handle is active.

### _boxCorners

```ts
protected _boxCorners(center: Vec3, rotation: Quat, halfExtents: Vec3): Vec3[]
```

Gets the corners of a box, indexed by their x, y and z bits.

**Parameters**

- `center` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): The center of the box.
- `rotation` ([`Quat`](https://api.playcanvas.com/engine/classes/Quat.md)): The rotation of the box.
- `halfExtents` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): The half extents along the axes of the rotation.

**Returns** [`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)`[]`: The world corners, valid until the next call.

### _boxHandles

```ts
protected _boxHandles(center: Vec3, halfExtents: Vec3, options: BoxHandleOptions, pad?: number): void
```

Places the face and corner handles of the box last passed to
[HandleGizmo#_boxCorners](https://api.playcanvas.com/engine/classes/HandleGizmo.md#_boxcorners), once large enough on screen.

**Parameters**

- `center` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): The center of the box.
- `halfExtents` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): The half extents.
- `options` (`BoxHandleOptions`): The handles to show.
- `pad` (`number`, optional, default `0`): The padding on each side, left out of the readout extents.

### _detailed

```ts
protected _detailed(center: Vec3, radius: number): boolean
```

Gets whether a shape is large enough on screen to show its handles.

**Parameters**

- `center` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): The center of the shape.
- `radius` (`number`): The radius of the shape.

**Returns** `boolean`: Whether to show the details.

### _drawShapes

```ts
protected _drawShapes(): void
```

Places the shapes of the attached nodes. Implemented by the subclass.

### _handle

```ts
protected _handle(position: Vec3, color: Color, node: GraphNode | null, name: string, index: number, origin: Vec3, dir: Vec3, inPlane?: boolean, guide?: boolean): boolean
```

Places a handle that drags along a line or in a plane, with a dashed guide from the origin
while hovered or dragged.

**Parameters**

- `position` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): The world position.
- `color` ([`Color`](https://api.playcanvas.com/engine/classes/Color.md)): The color of the handle when hovered or dragged, and of its guide.
- `node` ([`GraphNode`](https://api.playcanvas.com/engine/classes/GraphNode.md) `| null`): The node the handle edits, or null for a shape gizmo.
- `name` (`string`): The value the handle edits.
- `index` (`number`): The index of the handle among those editing the value.
- `origin` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): A point the edit is measured from, on the line or plane.
- `dir` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): The unit direction of the line, or the normal of the plane.
- `inPlane` (`boolean`, optional, default `false`): Whether the handle moves in a plane.
- `guide` (`boolean`, optional, default `!inPlane`): Whether to show the dashed line. Defaults to true for a line.

**Returns** `boolean`: Whether the handle is hovered or dragged.

### _icon

```ts
protected _icon(kind: OverlayIcon, position: Vec3, node: GraphNode): void
```

Places the icon of a node, which fires [HandleGizmo.EVENT_ICONSELECT](https://api.playcanvas.com/engine/classes/HandleGizmo.md#event_iconselect) when clicked.

**Parameters**

- `kind` ([`OverlayIcon`](https://api.playcanvas.com/engine/types/OverlayIcon.md)): The icon.
- `position` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): The world position.
- `node` ([`GraphNode`](https://api.playcanvas.com/engine/classes/GraphNode.md)): The node the icon marks.

### _moveHandle

```ts
protected _moveHandle(handle: GizmoHandle, point: Vec3): void
```

Edits the value of the dragged handle. Implemented by the subclass.

**Parameters**

- `handle` (`GizmoHandle`): The dragged handle.
- `point` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): Where the handle is dragged to, on its line.

### _readoutAt

```ts
protected _readoutAt(position: Vec3, label: string, color: Color, value: number, unit?: string): void
```

Shows the value of a hovered or dragged handle below it.

**Parameters**

- `position` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): The handle position.
- `label` (`string`): The value label.
- `color` ([`Color`](https://api.playcanvas.com/engine/classes/Color.md)): The label color.
- `value` (`number`): The value.
- `unit` (`string`, optional, default `''`): The unit after the value.

### _readoutHtmlAt

```ts
protected _readoutHtmlAt(position: Vec3, html: string): void
```

Shows readout markup below a hovered or dragged handle.

**Parameters**

- `position` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): The handle position.
- `html` (`string`): The markup, as [HandleGizmo#_readoutValue](https://api.playcanvas.com/engine/classes/HandleGizmo.md#_readoutvalue) formats it.

### _readoutValue

```ts
protected _readoutValue(label: string, color: Color, value: number, unit?: string): string
```

Formats a value with two decimals after a colored label.

**Parameters**

- `label` (`string`): The label.
- `color` ([`Color`](https://api.playcanvas.com/engine/classes/Color.md)): The label color.
- `value` (`number`): The value.
- `unit` (`string`, optional, default `''`): The unit after the value.

**Returns** `string`: The markup.

### _resizeBox

```ts
protected _resizeBox(handle: GizmoHandle, point: Vec3, rotation: Quat, startPosition: Vec3, startHalfExtents: Vec3, options: BoxHandleOptions, pad: number, position: Vec3, halfExtents: Vec3): void
```

Resizes a box to a dragged [HandleGizmo#_boxHandles](https://api.playcanvas.com/engine/classes/HandleGizmo.md#_boxhandles) handle, keeping the opposite face
or corner in place, or the center for a centered box.

**Parameters**

- `handle` (`GizmoHandle`): The dragged handle.
- `point` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): Where the handle is dragged to.
- `rotation` ([`Quat`](https://api.playcanvas.com/engine/classes/Quat.md)): The rotation of the box.
- `startPosition` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): The center at the start of the resize.
- `startHalfExtents` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): The half extents at the start of the resize.
- `options` (`BoxHandleOptions`): How the handles resize the box.
- `pad` (`number`): The padding on each side, left out of the snapped extents.
- `position` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): Receives the center.
- `halfExtents` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): Receives the half extents.

### _sphereHandles

```ts
protected _sphereHandles(center: Vec3, rotation: Quat, radius: number, node: GraphNode | null, name: string): void
```

Places handles at the ends of a sphere's axes, which drag its radius.

**Parameters**

- `center` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): The center of the sphere.
- `rotation` ([`Quat`](https://api.playcanvas.com/engine/classes/Quat.md)): The rotation of the axes.
- `radius` (`number`): The radius of the sphere.
- `node` ([`GraphNode`](https://api.playcanvas.com/engine/classes/GraphNode.md) `| null`): The node the handles edit, or null for a shape gizmo.
- `name` (`string`): The value the handles edit.

### _sphereOutline

```ts
protected _sphereOutline(center: Vec3, rotation: Quat, radius: number): void
```

Places the outline of a sphere, over faint great circles once large enough on screen, or
solid rings when the camera is inside it.

**Parameters**

- `center` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): The center of the sphere.
- `rotation` ([`Quat`](https://api.playcanvas.com/engine/classes/Quat.md)): The rotation of the great circles.
- `radius` (`number`): The radius of the sphere.

### _sphereRings

```ts
protected _sphereRings(center: Vec3, rotation: Quat, radius: number, weight?: number, alpha?: number): void
```

Places three great circles of a sphere.

**Parameters**

- `center` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): The center of the sphere.
- `rotation` ([`Quat`](https://api.playcanvas.com/engine/classes/Quat.md)): The rotation of the sphere.
- `radius` (`number`): The radius of the sphere.
- `weight` (`number`, optional, default `1`): The thickness as a factor of the line thickness.
- `alpha` (`number`, optional, default `1`): The alpha factor.

### _sphereSilhouette

```ts
protected _sphereSilhouette(center: Vec3, radius: number, out: Vec3): number
```

Gets the outline of a sphere as the camera sees it.

**Parameters**

- `center` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): The center of the sphere.
- `radius` (`number`): The radius of the sphere.
- `out` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): Receives the center of the outline.

**Returns** `number`: The radius of the outline.

### _startHandle

```ts
protected _startHandle(handle: GizmoHandle): void
```

Stores the values a handle edits at the start of a drag. Implemented by the subclass.

**Parameters**

- `handle` (`GizmoHandle`): The dragged handle.

### _updateRotation

```ts
_updateRotation(): void
```

The shapes are drawn in world space.

### _updateScale

```ts
_updateScale(): void
```

The shapes are sized in world units.

### destroy

```ts
destroy(): void
```

Destroys the gizmo and its shapes.

### prerender

```ts
prerender(): void
```

Places the shapes of the attached nodes.

### setTheme

```ts
setTheme(partial: Partial<HandleGizmoTheme>): void
```

Sets the theme or partial theme for the gizmo.

**Parameters**

- `partial` (`Partial<`[`HandleGizmoTheme`](https://api.playcanvas.com/engine/interfaces/HandleGizmoTheme.md)`>`): The partial theme to set.

**Example**

```ts
gizmo.setTheme({ occluded: new Color(1, 1, 1, 0.5) });
```

**Example**

```ts
// accents told apart without red and green
gizmo.setTheme({
    primary: new Color(0.9, 0.6, 0),
    secondary: new Color(0.35, 0.7, 0.9),
    tertiary: new Color(0.8, 0.6, 0.7)
});
```

## Events

### EVENT_HANDLEEND

```ts
static EVENT_HANDLEEND: string = 'handle:end'
```

Fired when a handle stops being dragged.

**Example**

```ts
const gizmo = new pc.LightGizmo(camera, layer);
gizmo.on('handle:end', (node, name) => {
    console.log(`Finished editing ${name} of ${node.name}`);
});
```

### EVENT_HANDLEMOVE

```ts
static EVENT_HANDLEMOVE: string = 'handle:move'
```

Fired when a dragged handle edits its value.

**Example**

```ts
const gizmo = new pc.LightGizmo(camera, layer);
gizmo.on('handle:move', (node, name) => {
    console.log(`Edited ${name} of ${node.name}`);
});
```

### EVENT_HANDLESTART

```ts
static EVENT_HANDLESTART: string = 'handle:start'
```

Fired when a handle starts being dragged.

**Example**

```ts
const gizmo = new pc.LightGizmo(camera, layer);
gizmo.on('handle:start', (node, name) => {
    console.log(`Started editing ${name} of ${node.name}`);
});
```

### EVENT_ICONSELECT

```ts
static EVENT_ICONSELECT: string = 'icon:select'
```

Fired when the icon of a node is clicked.

**Example**

```ts
const gizmo = new pc.LightGizmo(camera, layer);
gizmo.on('icon:select', (node) => {
    console.log(`Clicked the icon of ${node.name}`);
});
```

## Inherited from [DragGizmo](https://api.playcanvas.com/engine/classes/DragGizmo.md)

- `protected _app: AppBase`
- `protected _camera: CameraComponent`
- `protected _coordSpace: GizmoSpace = 'world'`
- `protected _device: GraphicsDevice`
- `protected _handles: EventHandle[] = []`
- `protected _layer: Layer`
- `protected _mouseButtons: [boolean, boolean, boolean]`
- `protected _scale: number = 1`
- `intersectShapes: Shape[] = []`
- `nodes: GraphNode[] = []`
- `preventDefault: boolean = true`
- `root: Entity`
- `snap: boolean = false`
- `snapAngleIncrement: number = 5`
- `protected get _requiresNodes(): boolean`
- `get camera(): CameraComponent` · `set camera(camera: CameraComponent)`
- `protected get cameraDir(): Vec3`
- `get coordSpace(): GizmoSpace` · `set coordSpace(value: GizmoSpace)`
- `get enabled(): boolean` · `set enabled(state: boolean)`
- `protected get facingDir(): Vec3`
- `get layer(): Layer` · `set layer(layer: Layer)`
- `get mouseButtons(): [boolean, boolean, boolean]`
- `get size(): number` · `set size(value: number)`
- `get snapIncrement(): number` · `set snapIncrement(value: number)`
- `protected _createRay(mouseWPos: Vec3): Ray`
- `protected _getScreenScale(pos: Vec3): number`
- `protected _labelMarkup(text: string, color: Color): string`
- `protected _lineNormal(dir: Vec3, facing: Vec3, out: Vec3): boolean`
- `protected _snapAngle(value: number): number`
- `protected _snapLength(value: number): number`
- `protected _snapValue(value: number, increment: number): number`
- `protected _snapVector(vec: Vec3, increment: number): Vec3`
- `protected _updatePosition(): void`
- `attach(nodes?: GraphNode | GraphNode[]): void`
- `detach(): void`
- `fire(name: string, arg1?: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any, arg6?: any, arg7?: any, arg8?: any): EventHandler`
- `hasEvent(name: string): boolean`
- `off(name?: string, callback?: HandleEventCallback, scope?: any): EventHandler`
- `on(name: string, callback: HandleEventCallback, scope?: any): EventHandle`
- `once(name: string, callback: HandleEventCallback, scope?: any): EventHandle`
- `update(): void`
- `static createLayer(app: AppBase, layerName?: string, layerIndex?: number, depth?: boolean): Layer`
- `static EVENT_NODESATTACH: string = 'nodes:attach'`
- `static EVENT_NODESDETACH: string = 'nodes:detach'`
- `static EVENT_POINTERDOWN: string = 'pointer:down'`
- `static EVENT_POINTERMOVE: string = 'pointer:move'`
- `static EVENT_POINTERUP: string = 'pointer:up'`
- `static EVENT_POSITIONUPDATE: string = 'position:update'`
- `static EVENT_RENDERUPDATE: string = 'render:update'`
- `static EVENT_ROTATIONUPDATE: string = 'rotation:update'`
- `static EVENT_SCALEUPDATE: string = 'scale:update'`
