component
Shore
Sloped beach/shore strip to meet a Lake.
⌖ Explore the library in 3D → · View as Markdown
Add it
npx @runek/cli add shore
Pulls @react-three/rapier@^2.2.0, @runek/core@^0.15.0.
Use it
import { Shore } from './runek/Shore'
<Shore position={[0, 0, 0]} />
Or as a node in a world file (worlds as data):
{ "type": "Shore", "props": { "position": [0, 0, 0] } }
Props
| Prop | Type | Default | Description |
|---|---|---|---|
position |
[x, y, z] |
[0, 0, 0] |
Position [x, y, z] in units (1 unit = 1 m, Y-up). |
rotation |
[x, y, z] |
[0, 0, 0] |
Euler rotation [x, y, z] in radians. |
seed |
number |
Accepted for the component contract; this component has no seeded variation yet. | |
size |
[number, number] |
[24, 24] |
[width, depth] in units. The sandy top sits at the component origin. |
thickness |
number |
0.3 |
Thickness, in units. |
color |
color |
palette sand |
Defaults to the world palette’s sand slot. |
Registry manifest
registry manifest /r/components/shore.json Self-contained JSON: inlined source plus resolved dependencies, exactly whatrunek add shore fetches.
Browse the whole catalog in the gallery →.
Source (2 files)
Shore.tsx
import { RigidBody } from '@react-three/rapier'
import { useWorld, type Vec3 } from '@runek/core'
import { shoreSurface } from './surfaces/shore'
export interface ShoreProps {
position?: Vec3
rotation?: Vec3
/** Accepted for the component contract; this component has no seeded variation yet. */
seed?: number
/** `[width, depth]` in units. The sandy top sits at the component origin. */
size?: [number, number]
thickness?: number
/** Defaults to the world palette's `sand` slot. */
color?: string
}
export function Shore({
position = [0, 0, 0],
rotation = [0, 0, 0],
size = [24, 24],
thickness = 0.3,
color,
}: ShoreProps) {
const { unit, palette } = useWorld()
const sandColor = color ?? palette.sand
const w = size[0] * unit
const d = size[1] * unit
const t = thickness * unit
return (
<RigidBody type="fixed" colliders="cuboid" position={position} rotation={rotation}>
<mesh receiveShadow position={[0, -t / 2, 0]}>
<boxGeometry args={[w, t, d]} />
<meshStandardMaterial color={sandColor} roughness={1} />
</mesh>
</RigidBody>
)
}
Shore.surface = shoreSurface surfaces/shore.ts
import type { SurfaceDef } from '@runek/core'
/** Shore's sandy top, a flat band at the origin. */
export const shoreSurface: SurfaceDef = {
kind: 'terrain',
build(props, { unit }) {
const [w, d] = (props.size as [number, number] | undefined) ?? [24, 24]
return (x, z) => (Math.abs(x) <= (w * unit) / 2 && Math.abs(z) <= (d * unit) / 2 ? 0 : null)
},
}