@threlte/extras
<Text3DGeometry>
Render 3D text as a geometry using threejs’s TextGeometry.
<script lang="ts">
import { Canvas } from '@threlte/core'
import { Checkbox, Pane, Slider, Textarea } from 'svelte-tweakpane-ui'
import { DEG2RAD } from 'three/src/math/MathUtils.js'
import Scene from './Scene.svelte'
let text = 'Hello\nWorld'
let bevelEnabled = true
let bevelOffset = 0
let bevelSegments = 20
let bevelSize = 0.2
let bevelThickness = 0.1
let curveSegments = 12
let depth = 1
let size = 5
let smooth = 0.1
</script>
<Pane
title="Text3DGeometry"
position="fixed"
>
<Textarea
bind:value={text}
label="text"
/>
<Checkbox
label="bevelEnabled"
bind:value={bevelEnabled}
/>
<Slider
label="bevelOffset"
bind:value={bevelOffset}
min={0}
max={2}
/>
<Slider
label="bevelSegments"
bind:value={bevelSegments}
step={1}
min={0}
max={50}
/>
<Slider
label="bevelSize"
bind:value={bevelSize}
min={0}
max={2}
/>
<Slider
label="bevelThickness"
bind:value={bevelThickness}
min={0}
max={2}
/>
<Slider
label="curveSegments"
bind:value={curveSegments}
step={1}
min={0}
max={50}
/>
<Slider
label="depth"
bind:value={depth}
min={0}
max={5}
/>
<Slider
label="size"
bind:value={size}
min={0}
max={10}
/>
<Slider
label="smooth"
bind:value={smooth}
min={0}
max={180 * DEG2RAD}
/>
</Pane>
<div>
<Canvas>
<Scene
{text}
{bevelEnabled}
{bevelOffset}
{bevelSegments}
{bevelSize}
{bevelThickness}
{curveSegments}
{depth}
{size}
{smooth}
/>
</Canvas>
</div>
<style>
div {
height: 100%;
}
</style>
<script lang="ts">
import { T } from '@threlte/core'
import { Align, Environment, Float, OrbitControls, Text3DGeometry } from '@threlte/extras'
export let text: string
export let bevelEnabled: boolean
export let bevelOffset: number
export let bevelSegments: number
export let bevelSize: number
export let bevelThickness: number
export let curveSegments: number
export let depth: number
export let size: number
export let smooth: number
</script>
<Align>
{#snippet children({ align })}
<T.Mesh>
<Text3DGeometry
font={'/fonts/Inter-semibold.blob'}
{text}
{bevelEnabled}
{bevelOffset}
{bevelSegments}
{bevelSize}
{bevelThickness}
{curveSegments}
{depth}
{size}
{smooth}
oncreate={() => {
align()
}}
/>
<T.MeshStandardMaterial
color="#FD3F00"
toneMapped={false}
metalness={1.0}
roughness={0.1}
/>
</T.Mesh>
{/snippet}
</Align>
<Environment files="/hdr/shanghai_riverside_1k.hdr" />
<Float
rotationIntensity={[0, 3, 0]}
rotationSpeed={1}
floatingRange={[-5, 5]}
speed={1}
>
<T.PerspectiveCamera
makeDefault
position.y={0}
position.z={20}
fov={90}
>
<OrbitControls
enableDamping
enablePan={false}
enableZoom={false}
/>
</T.PerspectiveCamera>
</Float>
Examples
Basic Example
<script lang="ts">
import { T } from '@threlte/core'
import { Text3DGeometry } from '@threlte/extras'
</script>
<T.Mesh>
<Text3DGeometry text={'Hello World'} />
<T.MeshStandardMaterial />
</T.Mesh>
Using a Custom Font
If no font
property is provided, the default font “Helvetiker” will be used
and loaded from the CDN
JSDeliver.
If you want to use a custom font, you can generate a font using
typeface.js. Provide the path to the
resulting JSON file using the prop font
.
Suspense-Ready
The component <Text3DGeometry>
is suspense-ready. Using it in a
<Suspense>
boundary will suspend
rendering until the provided font is loaded:
<script lang="ts">
import { T } from '@threlte/core'
import { Text3DGeometry, Suspense } from '@threlte/extras'
import Fallback from './Fallback.svelte'
</script>
<Suspense>
<T.Mesh>
<Text3DGeometry
font={'path-to-your-font'}
text={'Hello World'}
/>
<T.MeshStandardMaterial />
</T.Mesh>
{#snippet fallback()}
<Fallback />
{/snippet}
</Suspense>
Loading a Font Yourself
You can also load the font yourself and pass it to the component, like so:
<script lang="ts">
import { T, useLoader } from '@threlte/core'
import { Text3DGeometry } from '@threlte/extras'
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js'
let font = useLoader(FontLoader).load('path-to-your-font')
</script>
{#if $font}
<T.Mesh>
<Text3DGeometry
font={$font}
text={'Hello World'}
/>
<T.MeshStandardMaterial />
</T.Mesh>
{/await}
Centering Text
You can center a text by using the <Align>
component and calling the align slot prop when the text geometry is created.
<Align>
{#snippet children({ align })}
<T.Mesh>
<Text3DGeometry
font={'path-to-your-font'}
text={`Hello!`}
oncreate={align}
/>
<T.MeshStandardMaterial />
</T.Mesh>
{/snippet}
</Align>
Smoothing Text
You can smooth the text by setting the smooth
prop to a value above 0 to smooth all edges where the angle between faces is less than the smooth
value.