# Instances

The core idea of **Tres** is an _autogenerated catalogue_ of all the ThreeJS elements. This catalogue is generated from the ThreeJS source code, so it's always up to date.

When using ThreeJS, you need to import the elements you want to use. For example, if you want to use a `PerspectiveCamera`, you need to import it from the `three` package:

```js
import { PerspectiveCamera } from 'three'

const camera = new PerspectiveCamera(45, width / height, 1, 1000)
```

With **Tres** you don't need to import anything, that's because **Tres** automatically generate a **Vue Component based of the Three Object you want to use in CamelCase with a Tres prefix**. For example, if you want to use a `PerspectiveCamera` you would use `<TresPerspectiveCamera />` component.

```vue
<template>
  <TresCanvas>
    <TresPerspectiveCamera />
    <!-- Your scene goes here -->
  </TresCanvas>
</template>
```

This means that you can use the same [documentation](https://threejs.org/docs/) as you would when using plain ThreeJS, but with the power of Vue.

## Declaring objects

If we follow this argument, you should be able to lay out an instance like this: ❌

```vue
<template>
  <TresCanvas>
    <TresPerspectiveCamera visible :position="new THREE.Vector3(1, 2, 3)" />
    <!-- Your scene goes here -->
  </TresCanvas>
</template>
```

But with **Tres** this is not needed, you can define properties declaratively like this: ✅

```vue
<template>
  <TresCanvas>
    <TresPerspectiveCamera visible :position="[1, 2, 3]" />
    <!-- Your scene goes here -->
  </TresCanvas>
</template>
```

## Arguments

Some ThreeJS objects have arguments, for example, the `PerspectiveCamera` constructor has the following arguments:

- `fov` - Camera frustum vertical field of view.
- `aspect` - Camera frustum aspect ratio.
- `near` - Camera frustum near plane.
- `far` - Camera frustum far plane.

To pass these arguments to the `TresPerspectiveCamera` component, you can use the `args` prop:

```vue
<template>
  <TresCanvas>
    <TresPerspectiveCamera :args="[45, 1, 0.1, 1000]" />
    <!-- Your scene goes here -->
  </TresCanvas>
</template>
```

This is the same as doing this:

```ts
const camera = new PerspectiveCamera(45, 1, 0.1, 1000)
```

## Props

You can also pass props to the component, for example, the `TresAmbientLight` has a `intensity` property, so you can pass it to the component like this:

```html
<TresAmbientLight :intensity="0.5" />
```

### Set

All properties whose underlying object has a `.set()` method have a shortcut to recieve the value as an array. For example, the `TresPerspectiveCamera` has a `position` property, which is a `Vector3` object, so you can pass it to the component like this:

```html
<TresPerspectiveCamera :position="[1, 2, 3]" />
```

To specify transformation properties such as position, rotation, and scale, a shorthand is available that allows you to directly indicate the axis you wish to set within the props. A similar shorthand is also available for color property.

<!-- I changed color syntax from vue to html, because vue seems broken and does not color nested components -->
```html
<TresMesh :position-x="1" :scale-y="2" :rotation-x="Math.PI * 2">
  <TresMeshBasicMaterial :color-r="0.7" :color-b="0.3" />
</TresMesh>
```

::: warning
When you set the rotation property in [three.js](https://threejs.org/docs/index.html#api/en/math/Euler), it will use the 'XYZ' order by default.
It is important to note that when setting the rotation property with the shorthand, the order in which you set the angles matters. For more information on this topic, please refer to  [Euler angles](https://en.wikipedia.org/wiki/Euler_angles)
:::

```vue
<TresMesh :rotation-x="1" :rotation-y="2" :rotation-z="Math.PI * 2" />

<TresMesh :rotation-z="Math.PI * 2" :rotation-x="1" :rotation-y="2" />

<!-- Note that the order of the rotation properties matters, and swapping the order can result in different outcomes. -->
```

### Scalar

Another shortcut you can use is pass a scalar value to a property that expects a `Vector3` object, using the same value for the rest of the Vector:

```html
<TresPerspectiveCamera :position="5" /> ✅
```

```html
<TresPerspectiveCamera :position="[5, 5, 5]" /> ✅
```

### Colors

You can pass colors to the components using the `color` prop, which accepts a string with the color name or a hex value:

```html
<TresAmbientLight color="teal" /> ✅
```

```html
<TresAmbientLight color="#008080" /> ✅
```

### Methods

Some underlying properties are actually methods, the `TresPerspectiveCamera` has a `lookAt` method inherit from [Object3d](https://threejs.org/docs/#api/en/core/Object3D.lookAt), so you can pass it the coords to the component like this:

```html
<TresPerspectiveCamera :look-at="[1, 2, 3]" />
```
