@threlte/extras
<TrackballControls>
<TrackballControls> allow the camera to orbit freely around a target without causing gimbal lock. This type of camera controller is commonly used when the concepts of up and down are less important than the ability to carefully inspect a model from every angle. For an alternative camera controller, see <OrbitControls>.
If placed as a child of a camera component, <TrackballControls> will attach to that
camera. Otherwise, it attaches to the scene’s default camera. A camera can also be
passed explicitly via the camera prop. By default, damping is enabled. You can
disable this by setting staticMoving to true.
Unlike <OrbitControls>, <TrackballControls> does not support autoRotate.
<script lang="ts">
import { Canvas } from '@threlte/core'
import Scene from './Scene.svelte'
import Settings from './Settings.svelte'
let staticMoving: boolean = false
let noRotate: boolean = false
let rotateSpeed: number = 1
let noZoom: boolean = false
let zoomSpeed: number = 1.2
let noPan: boolean = false
let panSpeed: number = 0.3
</script>
<div>
<Canvas>
<Scene
{staticMoving}
{noRotate}
{rotateSpeed}
{noZoom}
{zoomSpeed}
{noPan}
{panSpeed}
/>
</Canvas>
</div>
<Settings
bind:staticMoving
bind:noRotate
bind:rotateSpeed
bind:noZoom
bind:zoomSpeed
bind:noPan
bind:panSpeed
/>
<style>
div {
position: relative;
height: 100%;
width: 100%;
background-color: rgb(14, 22, 37);
}
</style>
<script lang="ts">
import { T } from '@threlte/core'
import { Gizmo, TrackballControls } from '@threlte/extras'
interface Props {
staticMoving: boolean
noRotate: boolean
rotateSpeed: number
noZoom: boolean
zoomSpeed: number
noPan: boolean
panSpeed: number
}
let { staticMoving, noRotate, rotateSpeed, noZoom, zoomSpeed, noPan, panSpeed }: Props = $props()
</script>
<T.PerspectiveCamera
makeDefault
position={[10, 5, 10]}
lookAt.y={0.5}
>
<TrackballControls
{staticMoving}
{noRotate}
{rotateSpeed}
{noZoom}
{zoomSpeed}
{noPan}
{panSpeed}
>
<Gizmo />
</TrackballControls>
</T.PerspectiveCamera>
<T.DirectionalLight
position.y={10}
position.z={10}
/>
<T.AmbientLight intensity={0.3} />
<T.GridHelper args={[10, 10]} />
<T.Mesh position.y={1}>
<T.BoxGeometry args={[2, 2, 2]} />
<T.MeshStandardMaterial />
</T.Mesh>
<script lang="ts">
import { Checkbox, Pane, ThemeUtils, Slider } from 'svelte-tweakpane-ui'
interface Props {
staticMoving: boolean
noRotate: boolean
rotateSpeed: number
noZoom: boolean
zoomSpeed: number
noPan: boolean
panSpeed: number
}
let {
staticMoving = $bindable(),
noRotate = $bindable(),
rotateSpeed = $bindable(),
noZoom = $bindable(),
zoomSpeed = $bindable(),
noPan = $bindable(),
panSpeed = $bindable()
}: Props = $props()
</script>
<Pane
theme={ThemeUtils.presets.light}
position="fixed"
title="TrackballControls"
>
<Checkbox
bind:value={staticMoving}
label="staticMoving"
/>
<Checkbox
bind:value={noRotate}
label="noRotate"
/>
<Checkbox
bind:value={noPan}
label="noPan"
/>
<Checkbox
bind:value={noZoom}
label="noZoom"
/>
<Slider
label="rotateSpeed"
bind:value={rotateSpeed}
min={0.1}
max={2}
step={0.1}
/>
<Slider
label="panSpeed"
bind:value={panSpeed}
min={0.05}
max={1.0}
step={0.05}
/>
<Slider
label="zoomSpeed"
bind:value={zoomSpeed}
min={0.1}
max={2}
step={0.1}
/>
</Pane>
This example shows off just a few of the configurable properties of <TrackballControls>. To see all 15+ properties, consult the Three.js docs.
Usage
<script>
import { TrackballControls } from '@threlte/extras'
import { T } from '@threlte/core'
</script>
<T.PerspectiveCamera
makeDefault
fov={50}
>
<TrackballControls />
</T.PerspectiveCamera>
<TrackballControls> is a light wrapper that will use its parent as the target camera
(or the default camera if not a child of one) and the DOM element the renderer is
rendering to as the DOM element to listen to. It will also by demand invalidate the
frame loop.
useTrackballControls
To access the underlying TrackballControls instance from another component —
without a bind:ref — use the useTrackballControls hook. It returns a reactive
accessor whose current is the instance registered by the nearest
<TrackballControls> within the <Canvas>, or undefined until it has mounted.
<script lang="ts">
import { useTrackballControls } from '@threlte/extras'
const controls = useTrackballControls()
</script>
<button onclick={() => controls.current?.reset()}>Reset camera</button>
Component Signature
<TrackballControls> extends
<
T
.
TrackballControls
>
and supports all its props, snippets, bindings and events.