# Gizmo

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

Source: https://github.com/playcanvas/engine/blob/970d89f6d3bc6667f4e1f88153abd6e7e82ed52c/src/extras/gizmo/gizmo.js#L56

The base class for all gizmos.

A gizmo is an interactive widget drawn over the scene in its own [Layer](https://api.playcanvas.com/engine/classes/Layer.md);
[createLayer](https://api.playcanvas.com/engine/classes/Gizmo.md#createlayer) makes such a layer and adds it to the scene and the camera. Construct a gizmo
for a [CameraComponent](https://api.playcanvas.com/engine/classes/CameraComponent.md), then [attach](https://api.playcanvas.com/engine/classes/Gizmo.md#attach) the [GraphNode](https://api.playcanvas.com/engine/classes/GraphNode.md)s it should act on, which
are then listed in [nodes](https://api.playcanvas.com/engine/classes/Gizmo.md#nodes); [detach](https://api.playcanvas.com/engine/classes/Gizmo.md#detach) releases them. A gizmo updates and renders
itself from the application's update and prerender hooks, so it needs no per-frame call and is
torn down with [destroy](https://api.playcanvas.com/engine/classes/Gizmo.md#destroy). [size](https://api.playcanvas.com/engine/classes/Gizmo.md#size) scales the widget, which otherwise keeps a constant
apparent size as the camera moves; [coordSpace](https://api.playcanvas.com/engine/classes/Gizmo.md#coordspace) selects `'world'` or `'local'` axes;
[enabled](https://api.playcanvas.com/engine/classes/Gizmo.md#enabled) hides it without detaching; and [mouseButtons](https://api.playcanvas.com/engine/classes/Gizmo.md#mousebuttons) chooses which buttons
interact. Pointer interaction is reported through the `pointer:down`, `pointer:move` and
`pointer:up` events, node changes through `nodes:attach` and `nodes:detach`, and the
resulting transforms through `position:update`, `rotation:update` and `scale:update`.
[TransformGizmo](https://api.playcanvas.com/engine/classes/TransformGizmo.md) builds the translate, rotate and scale gizmos on this base.

## Constructors

### constructor

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

Creates a new Gizmo 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. This can be provided by the user or will be created
  and added to the scene and camera if not provided. Successive gizmos will share the same layer
  and will be removed from the camera and scene when the last gizmo is destroyed.
- `name` (`string`, optional, default `'gizmo'`): The name of the gizmo. Defaults to 'gizmo'.

**Example**

```ts
const gizmo = new Gizmo(camera, layer);
```

## Properties

### _app

```ts
protected _app: AppBase
```

Internal reference to the app containing the gizmo.

### _camera

```ts
protected _camera: CameraComponent
```

Internal reference to camera component to view the gizmo.

### _coordSpace

```ts
protected _coordSpace: GizmoSpace = 'world'
```

Internal version of coordinate space. Defaults to 'world'.

### _device

```ts
protected _device: GraphicsDevice
```

Internal reference to the graphics device of the app.

### _handles

```ts
protected _handles: EventHandle[] = []
```

Internal list of app event handles for the gizmo.

### _layer

```ts
protected _layer: Layer
```

Internal reference to layer to render the gizmo..

### _mouseButtons

```ts
protected _mouseButtons: [boolean, boolean, boolean]
```

Internal array of mouse buttons that can interact with the gizmo.

### _renderUpdate

```ts
protected _renderUpdate: boolean = false
```

Internal flag to track if a render update is required.

### _scale

```ts
protected _scale: number = 1
```

Internal version of the gizmo scale. Defaults to 1.

### intersectShapes

```ts
intersectShapes: Shape[] = []
```

The intersection shapes for the gizmo.

### nodes

```ts
nodes: GraphNode[] = []
```

The graph nodes attached to the gizmo.

### preventDefault

```ts
preventDefault: boolean = true
```

Flag to indicate whether to call `preventDefault` on pointer events.

### root

```ts
root: Entity
```

The root gizmo entity.

## Accessors

### camera

```ts
get camera(): CameraComponent
set camera(camera: CameraComponent)
```

Gets the camera component to view the gizmo.

### cameraDir

```ts
protected get cameraDir(): Vec3
```

### coordSpace

```ts
get coordSpace(): GizmoSpace
set coordSpace(value: GizmoSpace)
```

Gets the gizmo coordinate space.

### enabled

```ts
get enabled(): boolean
set enabled(state: boolean)
```

Gets the gizmo enabled state.

### facingDir

```ts
protected get facingDir(): Vec3
```

### layer

```ts
get layer(): Layer
set layer(layer: Layer)
```

Gets the gizmo render layer.

### mouseButtons

```ts
get mouseButtons(): [boolean, boolean, boolean]
```

Array of mouse buttons that can interact with the gizmo. The button indices are defined as:

 - 0: Left button
 - 1: Middle button
 - 2: Right button

The full list of button indices can be found here:
[https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button)

### size

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

Gets the gizmo size.

## Methods

### _updatePosition

```ts
protected _updatePosition(): void
```

### _updateRotation

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

### _updateScale

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

### attach

```ts
attach(nodes?: GraphNode | GraphNode[]): void
```

Attach an array of graph nodes to the gizmo.

**Parameters**

- `nodes` ([`GraphNode`](https://api.playcanvas.com/engine/classes/GraphNode.md) `|` [`GraphNode`](https://api.playcanvas.com/engine/classes/GraphNode.md)`[]`, optional, default `[]`): The graph nodes. Defaults to [].

**Example**

```ts
const gizmo = new Gizmo(camera, layer);
gizmo.attach([boxA, boxB]);
```

### destroy

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

Detaches all graph nodes and destroys the gizmo instance.

**Example**

```ts
const gizmo = new Gizmo(camera, layer);
gizmo.attach([boxA, boxB]);
gizmo.destroy();
```

### detach

```ts
detach(): void
```

Detaches all graph nodes from the gizmo.

**Example**

```ts
const gizmo = new Gizmo(camera, layer);
gizmo.attach([boxA, boxB]);
gizmo.detach();
```

### prerender

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

Pre-render method. This is called before the gizmo is rendered.

**Example**

```ts
const gizmo = new Gizmo(camera, layer);
gizmo.attach([boxA, boxB]);
gizmo.prerender();
```

### update

```ts
update(): void
```

Updates the gizmo position, rotation, and scale.

**Example**

```ts
const gizmo = new Gizmo(camera, layer);
gizmo.attach([boxA, boxB]);
gizmo.update();
```

### createLayer

```ts
static createLayer(app: AppBase, layerName?: string, layerIndex?: number): Layer
```

Creates a new gizmo layer and adds it to the scene.

**Parameters**

- `app` ([`AppBase`](https://api.playcanvas.com/engine/classes/AppBase.md)): The app.
- `layerName` (`string`, optional, default `'Gizmo'`): The layer name. Defaults to 'Gizmo'.
- `layerIndex` (`number`, optional, default `app.scene.layers.layerList.length`): The layer index. Defaults to the end of the layer list.

**Returns** [`Layer`](https://api.playcanvas.com/engine/classes/Layer.md): The new layer.

## Events

### EVENT_NODESATTACH

```ts
static EVENT_NODESATTACH: string = 'nodes:attach'
```

Fired when graph nodes are attached.

**Example**

```ts
const gizmo = new Gizmo(camera, layer);
gizmo.on('nodes:attach', () => {
    console.log('Graph nodes attached');
});
```

### EVENT_NODESDETACH

```ts
static EVENT_NODESDETACH: string = 'nodes:detach'
```

Fired when graph nodes are detached.

**Example**

```ts
const gizmo = new Gizmo(camera, layer);
gizmo.on('nodes:detach', () => {
    console.log('Graph nodes detached');
});
```

### EVENT_POINTERDOWN

```ts
static EVENT_POINTERDOWN: string = 'pointer:down'
```

Fired when the pointer is down on the gizmo.

**Example**

```ts
const gizmo = new Gizmo(camera, layer);
gizmo.on('pointer:down', (x, y, meshInstance) => {
    console.log(`Pointer was down on ${meshInstance.node.name} at ${x}, ${y}`);
});
```

### EVENT_POINTERMOVE

```ts
static EVENT_POINTERMOVE: string = 'pointer:move'
```

Fired when the pointer is moving over the gizmo.

**Example**

```ts
const gizmo = new Gizmo(camera, layer);
gizmo.on('pointer:move', (x, y, meshInstance) => {
    console.log(`Pointer was moving on ${meshInstance.node.name} at ${x}, ${y}`);
});
```

### EVENT_POINTERUP

```ts
static EVENT_POINTERUP: string = 'pointer:up'
```

Fired when the pointer is up off the gizmo.

**Example**

```ts
const gizmo = new Gizmo(camera, layer);
gizmo.on('pointer:up', (x, y, meshInstance) => {
    console.log(`Pointer was up on ${meshInstance.node.name} at ${x}, ${y}`);
})
```

### EVENT_POSITIONUPDATE

```ts
static EVENT_POSITIONUPDATE: string = 'position:update'
```

Fired when the gizmo's position is updated.

**Example**

```ts
const gizmo = new Gizmo(camera, layer);
gizmo.on('position:update', (position) => {
    console.log(`The gizmo's position was updated to ${position}`);
})
```

### EVENT_RENDERUPDATE

```ts
static EVENT_RENDERUPDATE: string = 'render:update'
```

Fired when the gizmo render has updated.

**Example**

```ts
const gizmo = new TransformGizmo(camera, layer);
gizmo.on('render:update', () => {
    console.log('Gizmo render has been updated');
});
```

### EVENT_ROTATIONUPDATE

```ts
static EVENT_ROTATIONUPDATE: string = 'rotation:update'
```

Fired when the gizmo's rotation is updated.

**Example**

```ts
const gizmo = new Gizmo(camera, layer);
gizmo.on('rotation:update', (rotation) => {
    console.log(`The gizmo's rotation was updated to ${rotation}`);
});
```

### EVENT_SCALEUPDATE

```ts
static EVENT_SCALEUPDATE: string = 'scale:update'
```

Fired when the gizmo's scale is updated.

**Example**

```ts
const gizmo = new Gizmo(camera, layer);
gizmo.on('scale:update', (scale) => {
    console.log(`The gizmo's scale was updated to ${scale}`);
});
```

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

- `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`
