@threlte/extras
useGltfAnimations
A convenience hook to use gltf animations loaded by a <GLTF> component or by the useGltf
hook.
<script lang="ts">
import Scene from './Scene.svelte'
import { Button, Folder, Pane } from 'svelte-tweakpane-ui'
import { Canvas } from '@threlte/core'
let scene = $state()
let animating = $state(false)
const actions = $derived(scene?.actions)
const action = $derived($actions?.['Take 001'])
// start animating as soon as the action is ready
$effect(() => {
action?.play()
animating = true
})
</script>
<Pane
position="fixed"
title="littlest tokyo"
>
<Folder title="animation">
<Button
disabled={animating}
on:click={() => {
action?.play()
animating = true
}}
title="play"
/>
<Button
disabled={!animating}
on:click={() => {
action?.stop()
animating = false
}}
title="stop"
/>
<Button
disabled={!animating}
on:click={() => {
action?.reset()
}}
title="reset"
/>
</Folder>
</Pane>
<div>
<Canvas>
<Scene bind:this={scene} />
</Canvas>
</div>
<style>
div {
height: 100%;
}
</style>
<script lang="ts">
import { Environment, OrbitControls, useDraco, useGltf, useGltfAnimations } from '@threlte/extras'
import { T } from '@threlte/core'
const dracoLoader = useDraco()
const gltf = useGltf('/models/LittlestTokyo.glb', { dracoLoader })
export const { actions, mixer } = useGltfAnimations<'Take 001'>(gltf)
</script>
<T.PerspectiveCamera
makeDefault
position={[600, 200, -600]}
near={10}
far={10_000}
>
<OrbitControls
autoRotate
autoRotateSpeed={0.2}
enableDamping
enableZoom={false}
target={[-60, -75, 0]}
/>
</T.PerspectiveCamera>
<Environment
url="/textures/equirectangular/hdr/industrial_sunset_puresky_1k.hdr"
isBackground
/>
{#await gltf then { scene }}
<T is={scene} />
{/await}
Model: Littlest Tokyo by Glen Fox, CC Attribution.
Examples
<GLTF>
component
With the Without any arguments, useGltfAnimations
returns a store which can be bound to the <GLTF>
component.
<script lang="ts">
import { GLTF, useGltfAnimations } from '@threlte/extras'
const { gltf, actions, mixer } = useGltfAnimations<'All Animations'>()
mixer.timeScale = 0.5
export const triggerAnimation = () => {
$actions['All Animations']?.play()
}
</script>
<GLTF
url="/path/to/model.glb"
bind:gltf={$gltf}
/>
useGltf
hook
With the For cases where you want to reuse parts of the GLTF such as materials, nodes, or the embedded camera, useGltfAnimations
accepts a writable store as its first argument. useGltf
returns a store that can be directly passed to useGltfAnimations
.
<script lang="ts">
import { T } from '@threlte/core'
import { useGltfAnimations, useGltf } from '@threlte/extras'
const gltf = useGltf('/path/to/model.glb')
const { actions, mixer } = useGltfAnimations<'All Animations'>(gltf)
$effect(() => {
$actions['All Animations']?.play()
})
</script>
{#await gltf then { scene }}
<T is={scene} />
{/await}
Applying Animations to a Different Root
useGltfAnimations
’s second optional argument allows you to apply the animations to a root other than the GLTF scene.
<script>
import { useGltfAnimations, useGltf } from '@threlte/extras'
import { Group } from 'three'
const gltf = useGltf('/path/to/model.glb')
const group = new Group()
const { root } = useGltfAnimations(gltf, group)
// $root === group
</script>
{#await gltf then { scene }}
<T is={group}>
<T is={scene} />
</T>
{/await}
You can also set the root store without passing in the second argument
<script>
import { useGltfAnimations, useGltf } from '@threlte/extras'
import { Group } from 'three'
const gltf = useGltf('/path/to/model.glb')
const { root } = useGltfAnimations(gltf)
</script>
{#await gltf then { scene }}
<T.Group bind:ref={$root}>
<T is={scene} />
</T.Group>
{/await}