@threlte/extras
useGltfAnimations
Convenience hook to use animations loaded with a <GLTF>
Threlte component or 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
Basic
<script lang="ts">
import { GLTF, useGltfAnimations } from '@threlte/extras'
// `useGltfAnimations` returns stores that populate
// when the `<GLTF>` component finished loading.
const { gltf, actions, mixer } = useGltfAnimations<'All Animations'>()
// Play them whenever you need
export const triggerAnimation = () => {
if ($mixer) {
$mixer.timeScale = 0.5
}
$actions['All Animations']?.play()
}
</script>
<!-- Bind the store `gltf` -->
<GLTF
url="/Bengal.glb"
bind:gltf={$gltf}
/>
useGltf
Hook
Using the Sometimes you might want to use the hook useGltf
to reuse parts of a model or use the embedded camera. In this case, the hook useGltf
returns an object with a property gltf
which you can pass as the first argument to the hook useGltfAnimations
.
<script lang="ts">
import { T } from '@threlte/core'
import { useGltfAnimations, useGltf } from '@threlte/extras'
// In this example, the useGltf hook returns a Writable<THREE.GLTF> store
const gltf = useGltf('/path/to/model.glb')
// Provide that store to the hook useGltfAnimations
const { actions, mixer } = useGltfAnimations<'All Animations'>(gltf)
// play the animation as soon as it's loaded
$effect(() => {
$actions['All Animations']?.play()
})
</script>
{#await gltf then { scene }}
<T is={scene} />
{/await}
Applying Animations to a Different Root
Sometimes you want to apply the animations to a root other than the GLTF scene. In this case, pass the root as the second argument.
<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)
</script>
{#await gltf then { scene }}
<T is={group}>
<T is={scene} />
</T>
{/await}
This can also be done after the animations have been loaded. In this case, you can use the bind:ref
directive to bind the root to the root
store returned by the hook.
<script>
import { useGltfAnimations, useGltf } from '@threlte/extras'
import { Group } from 'three'
const gltf = useGltf('/path/to/model.glb')
const { root } = useGltfAnimations(gltf, group)
</script>
{#await gltf then { scene }}
<T.Group bind:ref={$root}>
<T is={scene} />
</T.Group>
{/await}
Types
const {
gltf, // Writable<GLTF | undefined>
mixer, // AnimationMixer
actions, // CurrentWritable<Record<string, AnimationAction>>
root // CurrentWritable<Root | undefined>
} = useGLtfAnimations()