@threlte/extras
Getting Started
The package '@threlte/extras'
provides useful utilities, abstractions and plugins for your Threlte application.
Installation
npm install @threlte/extras
Usage
The content of this package can be used directly but it’s also meant to be a recipe for creating your own abstractions and plugins depending on your use case.
Components
Most components are abstractions of one or more <T>
components and forward all props and event listeners to it.
Let’s look at an example, the <OrbitControls>
. They are a common component in Three.js applications and can be used to easily manipulate the camera. Let’s implement it:
<script>
import { OrbitControls } from '@threlte/extras'
import { T } from '@threlte/core'
</script>
<T.PerspectiveCamera
makeDefault
position={[5, 5, 5]}
>
<OrbitControls />
</T.PerspectiveCamera>
In a regular Three.js application, you would have to create a OrbitControls
instance by
passing the camera and a DOM element to it. In Threlte, you can just use the <OrbitControls>
component and it will automatically use the default camera and the <canvas>
element the
renderer is rendering to. It will also automatically invalidate the frame on demand.
Under the hood though, there’s still a regular <T>
component that is doing the work of
applying props and registering event listeners. Internally, <OrbitControls>
is
forwarding all props and event listeners, so you can use it just like a regular <T>
component.
Let’s add an event listener that’s called when the camera is moved:
<script>
import { OrbitControls } from '@threlte/extras'
import { T } from '@threlte/core'
</script>
<T.PerspectiveCamera
makeDefault
position={[5, 5, 5]}
>
<OrbitControls
on:change={(e) => {
console.log(e)
}}
/>
</T.PerspectiveCamera>
The event listener is forwarded to the <T>
component and will be called when the camera is moved.
Keep in mind that these events are not hand-wired in the component, but are forwarded to the
underlying <T>
component which in turn forwards them to the Three.js object. So you can use any
event listener that is supported by the <T>
component.
Plugins
The package also provides a few plugins that can be used to extend the functionality of Threlte and <T>
components.
The most notable one is probably the plugin interactivity
that provides a way to interact with the scene. We can
extend our example from above and implement interactivity
:
<script>
import { OrbitControls, interactivity } from '@threlte/extras'
import { T } from '@threlte/core'
interactivity()
</script>
<T.PerspectiveCamera
makeDefault
position={[5, 5, 5]}
>
<OrbitControls />
</T.PerspectiveCamera>
<T.Mesh
on:click={() => {
console.log('clicked')
}}
>
<T.BoxGeometry />
<T.MeshBasicMaterial color="red" />
</T.Mesh>
Now, when we click on the box, we will see a message in the console. The interactivity
plugin
registers a global event listener on the <canvas>
element and forwards all events to the
respective <T>
components. Check out the guide on events for more
information on how to use events in Threlte.
Plugins are injected via context and therefore need to be implement at the root of your
application, this is typically your Scene.svelte
component. Check out our recommended app
structure.
Hooks
Hooks are regular functions with the limitation that they can only be invoked from the top level of
a component. '@threlte/extras'
provides useful hooks for loading assets, creating animations
and more. Let’s look at an example where we use the hook useGltf
to load an asset:
<script>
import { useGltf } from '@threlte/extras'
import { T } from '@threlte/core'
// Place the model in your public folder
const model = useGltf('/model.glb')
</script>
The hook will return the special Threlte store AsyncWritable
that makes it easy to consume the
result of the loader. The store will be updated once the asset is loaded and can be used in the
template either with the {#await}
or the {#if}
block. Let’s use the {#await}
block to
display a loading message:
<script>
import { useGltf } from '@threlte/extras'
import { T } from '@threlte/core'
import LoadingPlaceholder from './LoadingPlaceholder.svelte'
const model = useGltf('/model.glb')
</script>
{#await model}
<LoadingPlaceholder />
{:then value}
<T is={value} />
{/await}
Keep in mind that the hook useGltf
caches the result as it’s using
useLoader
internally.