createClassParser
The prop class can be used on <Box> and <Flex> to easily configure the
flexbox with predefined class names just as you would do in CSS. In order to use
the prop, you need to create a ClassParser which accepts a single string and
returns NodeProps. The function createClassParser is a helper function that
provides the proper types.
Let’s assume, you want to create a parser that supports the following class names but in 3D space:
.container { display: flex; flex-direction: row; justify-content: center; align-items: stretch; gap: 10px; padding: 10px;}.item { width: auto; height: auto; flex: 1;}You then need to create a ClassParser which returns the corresponding props:
import { createClassParser } from '@threlte/flex'
const classParser = createClassParser((string, props) => { const classNames = string.split(' ') for (const className of classNames) { switch (className) { case 'container': props.flexDirection = 'Row' props.justifyContent = 'Center' props.alignItems = 'Stretch' props.gap = 10 props.padding = 10 break case 'item': props.width = 'auto' props.height = 'auto' props.flex = 1 } } return props})Now you can use the prop class on <Flex> and <Box> to configure the flexbox:
<script lang="ts"> import { Canvas, T } from '@threlte/core' import Scene from './Scene.svelte' import { NoToneMapping } from 'three' import { OrbitControls } from '@threlte/extras'
let innerWidth = 0</script>
<svelte:window bind:innerWidth />
<div class="relative h-screen w-screen"> <Canvas toneMapping={NoToneMapping}> <T.OrthographicCamera makeDefault position.z={1000} zoom={innerWidth / 500} > <OrbitControls /> </T.OrthographicCamera>
<Scene /> </Canvas></div><script lang="ts"> import { T } from '@threlte/core' import { Shape, ShapeGeometry } from 'three'
export let color: string = 'white' export let height = 1 export let width = 1 export let radius = 5 export let depth = 0
let x = 1 let y = 1
const createGeometry = (width: number, height: number, radius: number): ShapeGeometry => { let shape = new Shape() shape.moveTo(x, y + radius) shape.lineTo(x, y + height - radius) shape.quadraticCurveTo(x, y + height, x + radius, y + height) shape.lineTo(x + width - radius, y + height) shape.quadraticCurveTo(x + width, y + height, x + width, y + height - radius) shape.lineTo(x + width, y + radius) shape.quadraticCurveTo(x + width, y, x + width - radius, y) shape.lineTo(x + radius, y) shape.quadraticCurveTo(x, y, x, y + radius)
const geometry = new ShapeGeometry(shape) geometry.center() return geometry }
$: geometry = createGeometry(width, height, radius)</script>
<T.Mesh position.z={depth * 20} renderOrder={depth}> <T is={geometry} /> <T.MeshBasicMaterial {color} /></T.Mesh><script lang="ts"> import { Box, Flex, createClassParser } from '@threlte/flex' import RoundedPlane from './RoundedPlane.svelte'
const classParser = createClassParser((string, props) => { const classNames = string.split(' ') for (const className of classNames) { switch (className) { case 'container': props.flexDirection = 'Row' props.justifyContent = 'Center' props.alignItems = 'Stretch' props.gap = 10 props.padding = 10 break case 'item': props.width = 'auto' props.height = 'auto' props.flex = 1 } } return props })</script>
<Flex width={300} height={150} {classParser} class="container"> <RoundedPlane radius={15} color="#FE3D00" width={300} height={150} /> <Box class="item"> {#snippet children({ width, height })} <RoundedPlane color="#EB1688" {width} {height} depth={1} /> {/snippet} </Box> <Box class="item"> {#snippet children({ width, height })} <RoundedPlane color="#113BFA" {width} {height} depth={1} /> {/snippet} </Box> <Box class="item"> {#snippet children({ width, height })} <RoundedPlane color="#590C65" {width} {height} depth={1} /> {/snippet} </Box></Flex>