From d6c21401721c0635c92cebfd6b7f215734120bf7 Mon Sep 17 00:00:00 2001 From: Antoine BERNIER Date: Sat, 1 Jun 2024 09:32:37 +0200 Subject: [PATCH] chore: wip csf3 --- .storybook/main.ts | 8 + .../stories/AccumulativeShadows.stories.tsx | 42 +++-- .storybook/stories/Adaptive.stories.tsx | 25 ++- .../stories/ArcballControls.stories.tsx | 55 +++--- .storybook/stories/BBAnchor.stories.tsx | 68 ++++--- .storybook/stories/Billboard.stories.tsx | 130 +++++++------ .storybook/stories/CameraControls.stories.tsx | 40 ++-- .storybook/stories/CameraShake.stories.tsx | 91 ++++------ .storybook/stories/Center.stories.tsx | 27 ++- .storybook/stories/Cloud.stories.tsx | 37 ++-- .storybook/stories/ContactShadows.stories.tsx | 37 ++-- .storybook/stories/CubeCamera.stories.tsx | 20 +- .storybook/stories/CurveModifier.stories.tsx | 29 ++- .storybook/stories/Decal.stories.tsx | 14 +- .storybook/stories/Detailed.stories.tsx | 16 +- .storybook/stories/DragControls.stories.tsx | 31 ++-- .storybook/stories/Environment.stories.tsx | 166 ++++++++--------- .storybook/stories/Example.stories.tsx | 43 +++-- .storybook/stories/FaceControls.stories.tsx | 22 +-- .storybook/stories/Facemesh.stories.tsx | 76 ++++---- .../stories/FirstPersonControls.stories.tsx | 61 ++++--- .storybook/stories/Float.stories.tsx | 41 ++--- .storybook/stories/FlyControls.stories.tsx | 43 +++-- .storybook/stories/GizmoHelper.stories.tsx | 171 ++++++------------ .storybook/stories/Grid.stories.tsx | 19 +- .storybook/stories/Helper.stories.tsx | 45 ++--- 26 files changed, 688 insertions(+), 669 deletions(-) diff --git a/.storybook/main.ts b/.storybook/main.ts index ef19ec922..962e8dab2 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -14,6 +14,14 @@ const config: StorybookConfig = { typescript: { reactDocgen: 'react-docgen-typescript', + reactDocgenTypescriptOptions: { + propFilter: (prop, component) => { + // Only include props that belong to the current component + const fileName = prop.declarations?.at(0)?.fileName // 'drei/src/core/AccumulativeShadows.tsx' + const componentName = fileName?.split('/').at(-1)?.split('.').at(0) // 'AccumulativeShadows' + return component.name === componentName + }, + }, }, } diff --git a/.storybook/stories/AccumulativeShadows.stories.tsx b/.storybook/stories/AccumulativeShadows.stories.tsx index d496f0728..eaa0a33dc 100644 --- a/.storybook/stories/AccumulativeShadows.stories.tsx +++ b/.storybook/stories/AccumulativeShadows.stories.tsx @@ -1,6 +1,8 @@ import * as THREE from 'three' import * as React from 'react' +import { ComponentProps } from 'react' import { FlakesTexture } from 'three/examples/jsm/textures/FlakesTexture' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' @@ -8,33 +10,30 @@ import { useGLTF, AccumulativeShadows, RandomizedLight, OrbitControls, Environme export default { title: 'Staging/AccumulativeShadows', - component: AccumulativeShadowScene, + component: AccumulativeShadows, decorators: [(storyFn) => {storyFn()}], -} +} satisfies Meta + +type Story = StoryObj -function AccumulativeShadowScene() { +function AccumulativeShadowScene(props: ComponentProps) { return ( + - + + + ) } -function Suzi(props) { +function Suzi(props: ComponentProps<'group'>) { const { scene, materials } = useGLTF('/suzanne-high-poly.gltf') React.useLayoutEffect(() => { scene.traverse((obj) => (obj as any).isMesh && (obj.receiveShadow = obj.castShadow = true)) @@ -55,5 +54,18 @@ function Suzi(props) { return } -export const AccumulativeShadowSt = () => -AccumulativeShadowSt.storyName = 'Default' +export const AccumulativeShadowSt = { + name: 'Default', + render: (args) => , + args: { + temporal: true, + frames: 100, + color: 'goldenrod', + alphaTest: 0.65, + opacity: 2, + scale: 14, + }, + argTypes: { + color: { control: 'color' }, + }, +} satisfies Story diff --git a/.storybook/stories/Adaptive.stories.tsx b/.storybook/stories/Adaptive.stories.tsx index 9d13cfcf2..2226c9ef3 100644 --- a/.storybook/stories/Adaptive.stories.tsx +++ b/.storybook/stories/Adaptive.stories.tsx @@ -1,5 +1,6 @@ -import React, { Suspense } from 'react' +import React, { ComponentProps, Suspense } from 'react' import { Vector3 } from 'three' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' @@ -10,7 +11,7 @@ import type { GLTF } from 'three-stdlib' export default { title: 'Performance/Adaptive', - component: useGLTF, + component: AdaptiveDpr, decorators: [ (storyFn) => ( ), ], -} +} satisfies Meta + +type Story = StoryObj interface ArcherGLTF extends GLTF { materials: { material_0: Material } @@ -51,7 +54,7 @@ function Archer() { ) } -function AdaptiveScene() { +function AdaptiveScene(props: ComponentProps) { return ( <> @@ -65,14 +68,20 @@ function AdaptiveScene() { castShadow shadow-bias={-0.001} /> - + ) } -export const AdaptiveSceneSt = () => -AdaptiveSceneSt.story = { +export const AdaptiveSceneSt = { name: 'Default', -} + render: (args) => , + args: { + pixelated: true, + }, + argTypes: { + pixelated: { control: 'boolean' }, + }, +} satisfies Story diff --git a/.storybook/stories/ArcballControls.stories.tsx b/.storybook/stories/ArcballControls.stories.tsx index 261c876de..2f796a781 100644 --- a/.storybook/stories/ArcballControls.stories.tsx +++ b/.storybook/stories/ArcballControls.stories.tsx @@ -1,38 +1,43 @@ import { createPortal, useFrame } from '@react-three/fiber' -import React, { useRef, useState } from 'react' +import React, { ComponentProps, useRef, useState } from 'react' import { Scene } from 'three' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' import { ArcballControls, Box, PerspectiveCamera, Plane, useFBO } from '../../src' import type { OrthographicCamera, PerspectiveCamera as PerspectiveCameraType } from 'three' -import type { ArcballControlsProps } from '../../src' - -const args = { - enablePan: true, - enableRotate: true, - enableZoom: true, -} - -export const ArcballControlsStory = (props: ArcballControlsProps) => ( - <> - - - - - -) - -ArcballControlsStory.args = args -ArcballControlsStory.storyName = 'Default' export default { title: 'Controls/ArcballControls', component: ArcballControls, decorators: [(storyFn) => {storyFn()}], + args: { + enablePan: true, + enableRotate: true, + enableZoom: true, + }, +} satisfies Meta + +type Story = StoryObj + +function DefaultScene(props: ComponentProps) { + return ( + <> + + + + + + ) } -const CustomCamera = (props: ArcballControlsProps) => { +export const ArcballControlsSt1 = { + render: (args) => , + name: 'Default', +} satisfies Story + +const CustomCamera = ({ ...props }: ComponentProps) => { /** * we will render our scene in a render target and use it as a map. */ @@ -73,7 +78,7 @@ const CustomCamera = (props: ArcballControlsProps) => { ) } -export const CustomCameraStory = (props: ArcballControlsProps) => - -CustomCameraStory.args = args -CustomCameraStory.storyName = 'Custom Camera' +export const ArcballControlsSt2 = { + render: (args) => , + name: 'Custom Camera', +} satisfies Story diff --git a/.storybook/stories/BBAnchor.stories.tsx b/.storybook/stories/BBAnchor.stories.tsx index d55a2ad34..d857d3a4d 100644 --- a/.storybook/stories/BBAnchor.stories.tsx +++ b/.storybook/stories/BBAnchor.stories.tsx @@ -1,5 +1,7 @@ import * as React from 'react' +import { ComponentProps } from 'react' import * as THREE from 'three' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' @@ -17,27 +19,19 @@ export default { ), ], - argTypes: { - drawBoundingBox: { control: 'boolean' }, - anchorX: { control: { type: 'range', min: -1, max: 1, step: 0.1 } }, - anchorY: { control: { type: 'range', min: -1, max: 1, step: 0.1 } }, - anchorZ: { control: { type: 'range', min: -1, max: 1, step: 0.1 } }, - children: { table: { disable: true } }, - }, -} +} satisfies Meta -type Anchor = THREE.Vector3 | [number, number, number] +type Story = StoryObj function BBAnchorScene({ - anchor, drawBoundingBox, children, -}: { - anchor: Anchor + ...props +}: ComponentProps & { drawBoundingBox: boolean - children?: React.ReactChild + children?: React.ReactNode }) { - const ref = React.useRef() + const ref = React.useRef(null) useHelper(drawBoundingBox && ref, BoxHelper, 'cyan') @@ -46,16 +40,12 @@ function BBAnchorScene({ - {children} + {children} ) } -const Template = ({ drawBoundingBox, anchorX, anchorY, anchorZ, ...args }) => ( - -) - function HtmlComp() { return ( , -} -BBAnchorWithHtml.storyName = 'With Html component' +export const BBAnchorWithHtml = { + render: (args) => ( + + + + ), + args: { + anchor: [1, 1, 1], + }, + name: 'With Html component', +} satisfies Story function MeshComp() { return ( @@ -88,12 +80,14 @@ function MeshComp() { ) } -export const BBAnchorWithMesh = Template.bind({}) -BBAnchorWithMesh.args = { - drawBoundingBox: true, - anchorX: 1, - anchorY: 1, - anchorZ: 1, - children: , -} -BBAnchorWithMesh.storyName = 'With other mesh' +export const BBAnchorWithMesh = { + render: (args) => ( + + + + ), + args: { + anchor: [1, 1, 1], + }, + name: 'With other mesh', +} satisfies Story diff --git a/.storybook/stories/Billboard.stories.tsx b/.storybook/stories/Billboard.stories.tsx index d44d4278a..9d6835c3e 100644 --- a/.storybook/stories/Billboard.stories.tsx +++ b/.storybook/stories/Billboard.stories.tsx @@ -1,9 +1,11 @@ import * as React from 'react' import { Vector3 } from 'three' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' import { Billboard, Plane, Box, Cone, OrbitControls, Text } from '../../src' +import { ComponentProps } from 'react' export default { title: 'Abstractions/Billboard', @@ -15,75 +17,85 @@ export default { ), ], -} + args: { + follow: true, + lockX: false, + lockY: false, + lockZ: false, + }, + argTypes: { + follow: { control: 'boolean' }, + lockX: { control: 'boolean' }, + lockY: { control: 'boolean' }, + lockZ: { control: 'boolean' }, + }, +} satisfies Meta -export const BillboardStory = ({ follow, lockX, lockY, lockZ }) => ( - <> - - - - - - - - - - - - - - - +type Story = StoryObj - - -) +function BillboardScene1(props: ComponentProps) { + return ( + <> + + + + + + + + + + + + + + + -BillboardStory.args = { - follow: true, - lockX: false, - lockY: false, - lockZ: false, + + + ) } -BillboardStory.storyName = 'Planes' +export const BillboardSt1 = { + render: (args) => , + name: 'Planes', +} satisfies Story -export const BillboardTextStory = ({ follow, lockX, lockY, lockZ }) => ( - <> - - - box - - - - - - - +function BillboardScene2(props: ComponentProps) { + return ( + <> + - cone + box - - - - + + + + + + + cone + + + + + + - - - - - - - - -) + + + + + -BillboardTextStory.args = { - follow: true, - lockX: false, - lockY: false, - lockZ: false, + + + ) } -BillboardTextStory.storyName = 'Text' +export const BillboardTextStory = { + render: (args) => , + name: 'Text', +} satisfies Story diff --git a/.storybook/stories/CameraControls.stories.tsx b/.storybook/stories/CameraControls.stories.tsx index d297971d9..170f6bf03 100644 --- a/.storybook/stories/CameraControls.stories.tsx +++ b/.storybook/stories/CameraControls.stories.tsx @@ -1,17 +1,21 @@ import { createPortal, useFrame } from '@react-three/fiber' -import React, { useRef, useState } from 'react' +import React, { Component, ComponentProps, useRef, useState } from 'react' import { Scene } from 'three' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' import { Box, CameraControls, PerspectiveCamera, Plane, useFBO } from '../../src' -import type { Camera } from 'three' -import type { CameraControlsProps } from '../../src' +export default { + title: 'Controls/CameraControls', + component: CameraControls, + decorators: [(storyFn) => {storyFn()}], +} satisfies Meta -const args = {} +type Story = StoryObj -export const CameraControlsStory = (props: CameraControlsProps) => { - const cameraControlRef = useRef(null) +function CameraControlsScene1(props: ComponentProps) { + const cameraControlRef = useRef(null) return ( <> @@ -27,23 +31,19 @@ export const CameraControlsStory = (props: CameraControlsProps) => { ) } -CameraControlsStory.args = args -CameraControlsStory.storyName = 'Default' +export const CameraControlsSt1 = { + render: (args) => , + name: 'Default', +} satisfies Story -export default { - title: 'Controls/CameraControls', - component: CameraControls, - decorators: [(storyFn) => {storyFn()}], -} - -const CustomCamera = (props: CameraControlsProps) => { +const CameraControlsScene2 = (props: ComponentProps) => { /** * we will render our scene in a render target and use it as a map. */ const fbo = useFBO(400, 400) const virtualCamera = useRef() const [virtualScene] = useState(() => new Scene()) - const cameraControlRef = useRef(null) + const cameraControlRef = useRef(null) useFrame(({ gl }) => { if (virtualCamera.current) { @@ -83,7 +83,7 @@ const CustomCamera = (props: CameraControlsProps) => { ) } -export const CustomCameraStory = (props: CameraControlsProps) => - -CustomCameraStory.args = args -CustomCameraStory.storyName = 'Custom Camera' +export const CameraControlsSt2 = { + render: (args) => , + name: 'Custom Camera', +} satisfies Story diff --git a/.storybook/stories/CameraShake.stories.tsx b/.storybook/stories/CameraShake.stories.tsx index 51fb1b2a2..d71d293fc 100644 --- a/.storybook/stories/CameraShake.stories.tsx +++ b/.storybook/stories/CameraShake.stories.tsx @@ -2,46 +2,12 @@ import * as React from 'react' import * as THREE from 'three' import { OrbitControls as OrbitControlsImpl } from 'three-stdlib' import { useFrame } from '@react-three/fiber' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' import { CameraShake, OrbitControls } from '../../src' - -const frequencyArgType = { - control: { - max: 10, - min: 0, - step: 0.1, - type: 'range', - }, -} - -const numberArgType = { - control: { - max: 1, - min: 0, - step: 0.05, - type: 'range', - }, -} - -const args = { - maxPitch: 0.05, - maxRoll: 0.05, - maxYaw: 0.05, - pitchFrequency: 0.8, - rollFrequency: 0.8, - yawFrequency: 0.8, -} - -const argTypes = { - maxPitch: numberArgType, - maxRoll: numberArgType, - maxYaw: numberArgType, - pitchFrequency: frequencyArgType, - rollFrequency: frequencyArgType, - yawFrequency: frequencyArgType, -} +import { ComponentProps } from 'react' export default { title: 'Staging/CameraShake', @@ -53,10 +19,28 @@ export default { ), ], -} + args: { + maxPitch: 0.05, + maxRoll: 0.05, + maxYaw: 0.05, + pitchFrequency: 0.8, + rollFrequency: 0.8, + yawFrequency: 0.8, + }, + argTypes: { + maxPitch: { control: { type: 'range', min: 0, max: 1, step: 0.05 } }, + maxRoll: { control: { type: 'range', min: 0, max: 1, step: 0.05 } }, + maxYaw: { control: { type: 'range', min: 0, max: 1, step: 0.05 } }, + pitchFrequency: { control: { type: 'range', min: 0, max: 10, step: 0.1 } }, + rollFrequency: { control: { type: 'range', min: 0, max: 10, step: 0.1 } }, + yawFrequency: { control: { type: 'range', min: 0, max: 10, step: 0.1 } }, + }, +} satisfies Meta + +type Story = StoryObj -function Scene() { - const cube = React.useRef() +function CameraShakeScene1(props: ComponentProps) { + const cube = React.useRef(null) useFrame(() => { if (cube.current) { @@ -66,6 +50,8 @@ function Scene() { return ( <> + + @@ -78,28 +64,23 @@ function Scene() { ) } -export const CameraShakeStory = ({ ...args }) => ( - <> - - - -) - -CameraShakeStory.args = args -CameraShakeStory.argTypes = argTypes -CameraShakeStory.storyName = 'Default' +export const CameraShakeSt1 = { + render: (args) => , + name: 'Default', +} satisfies Story -export const CameraShakeWithOrbitControlsStory = ({ ...args }) => { +function CameraShakeScene2(props: ComponentProps) { const controlsRef = React.useRef(null) return ( <> - - + + ) } -CameraShakeWithOrbitControlsStory.args = args -CameraShakeWithOrbitControlsStory.argTypes = argTypes -CameraShakeWithOrbitControlsStory.storyName = 'With OrbitControls' +export const CameraShakeSt2 = { + render: (args) => , + name: 'With OrbitControls', +} satisfies Story diff --git a/.storybook/stories/Center.stories.tsx b/.storybook/stories/Center.stories.tsx index 82d141951..953758296 100644 --- a/.storybook/stories/Center.stories.tsx +++ b/.storybook/stories/Center.stories.tsx @@ -1,24 +1,28 @@ import * as React from 'react' import { Vector3 } from 'three' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' import { useTurntable } from '../useTurntable' import { Box, Center, useGLTF } from '../../src' +import { ComponentProps } from 'react' export default { title: 'Staging/Center', component: Center, decorators: [(storyFn) => {storyFn()}], -} +} satisfies Meta + +type Story = StoryObj -const SimpleExample = () => { +const SimpleExample = (props: ComponentProps) => { const { scene } = useGLTF('LittlestTokyo.glb') const ref = useTurntable() return ( -
+
@@ -27,10 +31,15 @@ const SimpleExample = () => { ) } -export const DefaultStory = () => ( - - - -) +function CenterScene(props: ComponentProps) { + return ( + + + + ) +} -DefaultStory.storyName = 'Default' +export const CenterSt = { + render: (args) => , + name: 'Default', +} satisfies Story diff --git a/.storybook/stories/Cloud.stories.tsx b/.storybook/stories/Cloud.stories.tsx index 84f9188be..1f79cc863 100644 --- a/.storybook/stories/Cloud.stories.tsx +++ b/.storybook/stories/Cloud.stories.tsx @@ -1,9 +1,11 @@ import * as React from 'react' import { Vector3 } from 'three' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' import { Cloud, OrbitControls } from '../../src' +import { ComponentProps } from 'react' export default { title: 'Staging/Cloud', @@ -15,19 +17,26 @@ export default { ), ], -} +} satisfies Meta + +type Story = StoryObj -export const CloudStory = () => ( - <> - - - - - - - - - -) +function CloudScene(props: ComponentProps) { + return ( + <> + + + + + + + + + + ) +} -CloudStory.storyName = 'Default' +export const CloudSt = { + render: (args) => , + name: 'Default', +} satisfies Story diff --git a/.storybook/stories/ContactShadows.stories.tsx b/.storybook/stories/ContactShadows.stories.tsx index 73d468d0c..048425a23 100644 --- a/.storybook/stories/ContactShadows.stories.tsx +++ b/.storybook/stories/ContactShadows.stories.tsx @@ -1,18 +1,22 @@ import * as React from 'react' import { useFrame } from '@react-three/fiber' import { Mesh } from 'three' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' import { ContactShadows, Sphere, Plane } from '../../src' +import { ComponentProps } from 'react' export default { title: 'Staging/ContactShadows', component: ContactShadows, decorators: [(storyFn) => {storyFn()}], -} +} satisfies Meta + +type Story = StoryObj -function ContactShadowScene({ colorized }: any) { +function ContactShadowsScene(props: ComponentProps) { const mesh = React.useRef(null!) useFrame(({ clock }) => { mesh.current.position.y = Math.sin(clock.getElapsedTime()) + 2 @@ -23,14 +27,9 @@ function ContactShadowScene({ colorized }: any) { - + + + @@ -38,8 +37,18 @@ function ContactShadowScene({ colorized }: any) { ) } -export const ContactShadowSt = () => -ContactShadowSt.storyName = 'Default' +export const ContactShadowsSt1 = { + render: (args) => , + name: 'Default', +} satisfies Story -export const ContactShadowStColor = () => -ContactShadowStColor.storyName = 'Colorized' +export const ContactShadowsSt2 = { + render: (args) => , + name: 'Colorized', + args: { + color: '#2A8AFF', + }, + argTypes: { + color: { control: 'color' }, + }, +} satisfies Story diff --git a/.storybook/stories/CubeCamera.stories.tsx b/.storybook/stories/CubeCamera.stories.tsx index cee39ceac..c82985f93 100644 --- a/.storybook/stories/CubeCamera.stories.tsx +++ b/.storybook/stories/CubeCamera.stories.tsx @@ -1,16 +1,20 @@ import * as React from 'react' import * as THREE from 'three' import { useFrame } from '@react-three/fiber' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' import { Box, CubeCamera } from '../../src' +import { ComponentProps } from 'react' export default { title: 'Camera/CubeCamera', component: CubeCamera, decorators: [(storyFn) => {storyFn()}], -} +} satisfies Meta + +type Story = StoryObj declare global { namespace JSX { @@ -20,7 +24,7 @@ declare global { } } -function Sphere({ offset = 0, ...props }) { +function Sphere({ offset = 0, ...props }: ComponentProps & { offset?: number }) { const ref = React.useRef() useFrame(({ clock }) => { ref.current!.position.y = Math.sin(offset + clock.elapsedTime) * 5 @@ -38,13 +42,13 @@ function Sphere({ offset = 0, ...props }) { ) } -function Scene() { +function Scene(props: ComponentProps) { return ( <> - - + + @@ -53,5 +57,7 @@ function Scene() { ) } -export const DefaultStory = () => -DefaultStory.storyName = 'Default' +export const DefaultStory = { + render: (args) => , + name: 'Default', +} satisfies Story diff --git a/.storybook/stories/CurveModifier.stories.tsx b/.storybook/stories/CurveModifier.stories.tsx index d1a7447d0..4ffbaffd9 100644 --- a/.storybook/stories/CurveModifier.stories.tsx +++ b/.storybook/stories/CurveModifier.stories.tsx @@ -1,7 +1,8 @@ -import React from 'react' +import React, { Component, ComponentProps } from 'react' import { BufferGeometry, CatmullRomCurve3, LineBasicMaterial, LineLoop, Vector3 } from 'three' import { FontLoader, TextGeometry, TextGeometryParameters } from 'three-stdlib' import { extend, useFrame, useLoader } from '@react-three/fiber' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' import { CurveModifier, CurveModifierRef } from '../../src' @@ -26,9 +27,11 @@ export default { title: 'Modifiers/CurveModifier', component: CurveModifier, decorators: [(storyFn) => {storyFn()}], -} +} satisfies Meta + +type Story = StoryObj -function CurveModifierScene() { +function CurvedText(props: ComponentProps) { const curveRef = React.useRef() const geomRef = React.useRef(null!) const font = useLoader(FontLoader, '/fonts/helvetiker_regular.typeface.json') @@ -64,7 +67,7 @@ function CurveModifierScene() { return ( <> - + ( - - - -) -CurveModifierSt.storyName = 'Default' +function CurveModifierScene(props: ComponentProps) { + return ( + + + + ) +} + +export const CurveModifierSt = { + render: (args) => , + name: 'Default', +} satisfies Story diff --git a/.storybook/stories/Decal.stories.tsx b/.storybook/stories/Decal.stories.tsx index 7304f3d03..50c7642ff 100644 --- a/.storybook/stories/Decal.stories.tsx +++ b/.storybook/stories/Decal.stories.tsx @@ -1,8 +1,10 @@ import * as React from 'react' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' import { Sampler, Decal, useTexture, useSurfaceSampler, PerspectiveCamera, OrbitControls } from '../../src' import { Euler, InstancedBufferAttribute, Matrix4, Mesh, Quaternion, Vector3 } from 'three' +import { ComponentProps } from 'react' function LoopOverInstancedBufferAttribute({ children, buffer }: { buffer?: InstancedBufferAttribute; children: any }) { const [m] = React.useState(() => new Matrix4()) @@ -31,9 +33,11 @@ export default { ), ], -} +} satisfies Meta + +type Story = StoryObj -function DecalScene() { +function DecalScene(props: ComponentProps) { const ref = React.useRef() const [reactMap, threeMap] = useTexture(['/decals/react.png', '/decals/three.png']) @@ -83,5 +87,7 @@ function DecalScene() { ) } -export const DecalSt = () => -DecalSt.storyName = 'Default' +export const DecalSt = { + render: (args) => , + name: 'Default', +} satisfies Story diff --git a/.storybook/stories/Detailed.stories.tsx b/.storybook/stories/Detailed.stories.tsx index 6f047b7c2..702491717 100644 --- a/.storybook/stories/Detailed.stories.tsx +++ b/.storybook/stories/Detailed.stories.tsx @@ -1,9 +1,11 @@ import * as React from 'react' import { Vector3 } from 'three' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' import { Detailed, Icosahedron, OrbitControls } from '../../src' +import { ComponentProps } from 'react' export default { title: 'Abstractions/Detailed', @@ -15,12 +17,14 @@ export default { ), ], -} +} satisfies Meta + +type Story = StoryObj -function DetailedScene() { +function DetailedScene(props: ComponentProps) { return ( <> - + @@ -36,5 +40,7 @@ function DetailedScene() { ) } -export const DetailedSt = () => -DetailedSt.storyName = 'Default' +export const DetailedSt = { + render: (args) => , + name: 'Default', +} satisfies Story diff --git a/.storybook/stories/DragControls.stories.tsx b/.storybook/stories/DragControls.stories.tsx index 553489c20..c8e631b4c 100644 --- a/.storybook/stories/DragControls.stories.tsx +++ b/.storybook/stories/DragControls.stories.tsx @@ -3,36 +3,25 @@ import * as THREE from 'three' import { Box } from '../../src' import { Setup } from '../Setup' import { DragControls } from '../../src/web/DragControls' -import { Meta } from '@storybook/react' +import { Meta, StoryObj } from '@storybook/react' +import { ComponentProps } from 'react' export default { title: 'Gizmos/DragControls', component: DragControls, decorators: [(storyFn) => {storyFn()}], - argTypes: { - axisLock: { - control: { type: 'select', options: ['', 'x', 'y', 'z'] }, - description: 'Lock dragging to a specific axis', - defaultValue: '', - }, - dragLimits: { - control: 'object', - description: 'Set limits for dragging', - defaultValue: {}, - }, - autoTransform: { control: false }, - matrix: { control: false }, - }, -} as Meta +} satisfies Meta -const Template = ({ axisLock, dragLimits }) => { +type Story = StoryObj + +const DragControlsScene = (props: ComponentProps) => { const planes = [ { axis: 'x', normal: new THREE.Vector3(1, 0, 0), color: 0xff0000 }, // X-axis { axis: 'y', normal: new THREE.Vector3(0, 1, 0), color: 0x00ff00 }, // Y-axis { axis: 'z', normal: new THREE.Vector3(0, 0, 1), color: 0x0000ff }, // Z-axis ] const planeHelpers = planes - .filter(({ axis }) => !axisLock || axis === axisLock) + .filter(({ axis }) => !props.axisLock || axis === props.axisLock) .map(({ normal, color }) => new THREE.PlaneHelper(new THREE.Plane(normal, 0), 5, color)) return ( @@ -40,7 +29,7 @@ const Template = ({ axisLock, dragLimits }) => { {planeHelpers.map((planeHelper, index) => ( ))} - + @@ -49,4 +38,6 @@ const Template = ({ axisLock, dragLimits }) => { ) } -export const DragControlsStory = Template.bind({}) +export const DragControlsStory = { + render: (args) => , +} satisfies Story diff --git a/.storybook/stories/Environment.stories.tsx b/.storybook/stories/Environment.stories.tsx index 755dda795..e3bdf19b9 100644 --- a/.storybook/stories/Environment.stories.tsx +++ b/.storybook/stories/Environment.stories.tsx @@ -1,11 +1,13 @@ import * as React from 'react' import { Vector3 } from 'three' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' import { Environment, ContactShadows, PerspectiveCamera, OrbitControls } from '../../src' import { presetsObj } from '../../src/helpers/environment-assets' +import { ComponentProps } from 'react' export default { title: 'Staging/Environment', @@ -17,102 +19,100 @@ export default { ), ], -} +} satisfies Meta -export const EnvironmentStory = ({ background, preset, blur }) => ( - <> - - - - - - - -) +type Story = StoryObj const presets = Object.keys(presetsObj) -EnvironmentStory.args = { - background: true, - blur: 0, - preset: presets[0], +function EnvironmentScene1(props: ComponentProps) { + return ( + <> + + + + + + + + ) } -EnvironmentStory.argTypes = { - preset: { - options: presets, - control: { - type: 'select', +export const EnvironmentSt1 = { + render: (args) => , + args: { + background: true, + backgroundBlurriness: 0, + preset: 'apartment', + }, + argTypes: { + background: { control: 'boolean' }, + backgroundBlurriness: { control: { type: 'range', min: 0, max: 1, step: 0.01 } }, + preset: { + options: presets, + control: { + type: 'select', + }, }, }, - blur: { control: { type: 'range', min: 0, max: 1, step: 0.01 } }, -} - -EnvironmentStory.storyName = 'Default' -export const EnvironmentFilesStory = ({ background }) => ( - <> - - - - - - - -) - -EnvironmentFilesStory.args = { - background: true, + name: 'Default', +} satisfies Story + +function EnvironmentScene2(props: ComponentProps) { + return ( + <> + + + + + + + + ) } -EnvironmentFilesStory.storyName = 'Files' - -export const EnvironmentGroundStory = ({ preset, height, radius }) => ( - <> - - - - - - - - - -) - -EnvironmentGroundStory.args = { - height: 15, - radius: 60, - preset: 'park', +export const EnvironmentSt2 = { + render: (args) => , + args: { + background: true, + path: 'cube/', + files: ['px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png'], + }, + argTypes: { + background: { control: 'boolean' }, + }, + name: 'Files', +} satisfies Story + +function EnvironmentScene3(props: ComponentProps) { + return ( + <> + + + + + + + + + + ) } -EnvironmentGroundStory.argTypes = { - preset: { - options: presets, - control: { - type: 'select', - }, +export const EnvironmentSt3 = { + render: (args) => , + args: { + ground: { height: 15, radius: 60 }, + preset: 'park', }, - height: { - control: { - type: 'range', - min: 0, - max: 50, - step: 0.1, + argTypes: { + preset: { + options: presets, + control: { + type: 'select', + }, }, }, - radius: { - control: { - type: 'range', - min: 0, - max: 200, - step: 1, - }, - }, -} - -EnvironmentGroundStory.storyName = 'Ground' + name: 'Ground', +} satisfies Story diff --git a/.storybook/stories/Example.stories.tsx b/.storybook/stories/Example.stories.tsx index 8b2d56ec7..aebe6e4cb 100644 --- a/.storybook/stories/Example.stories.tsx +++ b/.storybook/stories/Example.stories.tsx @@ -1,6 +1,7 @@ import * as THREE from 'three' import * as React from 'react' import { Vector3 } from 'three' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' @@ -16,9 +17,11 @@ export default { ), ], -} +} satisfies Meta + +type Story = StoryObj -export const ExampleSt = ({ fontUrl, color, bevelSize, debug }) => { +function ExampleScene(props: React.ComponentProps) { const apiRef = React.useRef(null) return ( @@ -27,10 +30,7 @@ export const ExampleSt = ({ fontUrl, color, bevelSize, debug }) => { { if ((e as any as PointerEvent).metaKey) { @@ -43,18 +43,23 @@ export const ExampleSt = ({ fontUrl, color, bevelSize, debug }) => { ) } -ExampleSt.args = { - fontUrl: '/fonts/Inter_Bold.json', - bevelSize: undefined, - color: '#cbcbcb', - debug: false, -} -ExampleSt.argTypes = { - fontUrl: { control: 'select', options: ['/fonts/Inter_Bold.json', '/fonts/helvetiker_regular.typeface.json'] }, - bevelSize: { control: { type: 'range', min: 0, max: 0.1, step: 0.01 } }, - color: { control: { type: 'color' } }, - debug: { control: { type: 'boolean' } }, -} +export const ExampleSt = { + render: (args) => , + + args: { + font: '/fonts/Inter_Bold.json', + bevelSize: undefined, + color: '#cbcbcb', + debug: false, + }, + + argTypes: { + font: { control: 'select', options: ['/fonts/Inter_Bold.json', '/fonts/helvetiker_regular.typeface.json'] }, + bevelSize: { control: { type: 'range', min: 0, max: 0.1, step: 0.01 } }, + color: { control: { type: 'color' } }, + debug: { control: { type: 'boolean' } }, + }, -ExampleSt.storyName = 'Default' + name: 'Default', +} satisfies Story diff --git a/.storybook/stories/FaceControls.stories.tsx b/.storybook/stories/FaceControls.stories.tsx index b33a42f41..6b232a6f3 100644 --- a/.storybook/stories/FaceControls.stories.tsx +++ b/.storybook/stories/FaceControls.stories.tsx @@ -1,18 +1,22 @@ /* eslint react-hooks/exhaustive-deps: 1 */ import * as THREE from 'three' import * as React from 'react' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' import { FaceLandmarker, FaceControls, Box } from '../../src' +import { ComponentProps } from 'react' export default { title: 'Controls/FaceControls', component: FaceControls, decorators: [(storyFn) => {storyFn()}], -} +} satisfies Meta + +type Story = StoryObj -function FaceControlsScene(props) { +function FaceControlsScene(props: ComponentProps) { return ( <> @@ -31,13 +35,7 @@ function FaceControlsScene(props) { ) } -export const FaceControlsSt = (args) => -FaceControlsSt.args = { - eyes: undefined, -} - -FaceControlsSt.argTypes = { - eyes: { control: { type: 'boolean' } }, -} - -FaceControlsSt.storyName = 'Default' +export const FaceControlsSt = { + render: (args) => , + name: 'Default', +} satisfies Story diff --git a/.storybook/stories/Facemesh.stories.tsx b/.storybook/stories/Facemesh.stories.tsx index 0236b4f40..38306fe1b 100644 --- a/.storybook/stories/Facemesh.stories.tsx +++ b/.storybook/stories/Facemesh.stories.tsx @@ -1,6 +1,7 @@ import * as THREE from 'three' import * as React from 'react' import { Vector3 } from 'three' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' @@ -16,47 +17,42 @@ export default { ), ], -} +} satisfies Meta -export const FacemeshSt = ({ depth, origin, eyes, eyesAsOrigin, offset, offsetScalar, debug }) => ( - <> - - - - - - - -) -FacemeshSt.args = { - depth: undefined, - origin: undefined, - eyes: undefined, - eyesAsOrigin: undefined, - offset: undefined, - offsetScalar: undefined, - debug: true, -} +type Story = StoryObj -FacemeshSt.argTypes = { - depth: { control: { type: 'range', min: 0, max: 6.5, step: 0.01 } }, - origin: { control: 'select', options: [undefined, 168, 9] }, - eyes: { control: { type: 'boolean' } }, - eyesAsOrigin: { control: { type: 'boolean' } }, - offset: { control: { type: 'boolean' } }, - offsetScalar: { control: { type: 'range', min: 0, max: 200, step: 1 } }, - debug: { control: { type: 'boolean' } }, +function FacemeshScene(props: React.ComponentProps) { + return ( + <> + + + + + + + + ) } -FacemeshSt.storyName = 'Default' +export const FacemeshSt = { + render: (args) => , + args: { + debug: true, + }, + argTypes: { + depth: { control: { type: 'range', min: 0, max: 6.5, step: 0.01 } }, + origin: { control: 'select', options: [undefined, 168, 9] }, + eyes: { control: { type: 'boolean' } }, + eyesAsOrigin: { control: { type: 'boolean' } }, + offset: { control: { type: 'boolean' } }, + offsetScalar: { control: { type: 'range', min: 0, max: 200, step: 1 } }, + debug: { control: { type: 'boolean' } }, + }, + + name: 'Default', +} satisfies Story diff --git a/.storybook/stories/FirstPersonControls.stories.tsx b/.storybook/stories/FirstPersonControls.stories.tsx index a5b8f7409..e5556f847 100644 --- a/.storybook/stories/FirstPersonControls.stories.tsx +++ b/.storybook/stories/FirstPersonControls.stories.tsx @@ -1,38 +1,45 @@ import * as React from 'react' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' import { Box, FirstPersonControls } from '../../src' -export const FirstPersonControlsStory = ({ ...args }) => ( - <> - - - - - -) - -FirstPersonControlsStory.args = { - activeLook: true, - autoForward: false, - constrainVertical: false, - enabled: true, - heightCoef: 1, - heightMax: 1, - heightMin: 0, - heightSpeed: false, - lookVertical: true, - lookSpeed: 0.005, - movementSpeed: 1, - verticalMax: Math.PI, - verticalMin: 0, -} - -FirstPersonControlsStory.storyName = 'Default' - export default { title: 'Controls/FirstPersonControls', component: FirstPersonControls, decorators: [(storyFn) => {storyFn()}], +} satisfies Meta + +type Story = StoryObj + +function FirstPersonControlsScene(props: React.ComponentProps) { + return ( + <> + + + + + + ) } + +export const FirstPersonControlsSt = { + render: ({ ...args }) => , + args: { + activeLook: true, + autoForward: false, + constrainVertical: false, + enabled: true, + heightCoef: 1, + heightMax: 1, + heightMin: 0, + heightSpeed: false, + lookVertical: true, + lookSpeed: 0.005, + movementSpeed: 1, + verticalMax: Math.PI, + verticalMin: 0, + }, + name: 'Default', +} satisfies Story diff --git a/.storybook/stories/Float.stories.tsx b/.storybook/stories/Float.stories.tsx index f04c6b97b..c989b4162 100644 --- a/.storybook/stories/Float.stories.tsx +++ b/.storybook/stories/Float.stories.tsx @@ -1,6 +1,7 @@ -import React, { forwardRef, Suspense, useRef } from 'react' +import React, { ComponentProps, forwardRef, Suspense, useRef } from 'react' import * as THREE from 'three' import { useFrame } from '@react-three/fiber' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' @@ -11,20 +12,17 @@ export default { title: 'Staging/Float', component: Float, decorators: [(storyFn) => {storyFn()}], -} +} satisfies Meta + +type Story = StoryObj -function FloatScene({ floatingRangeMin, floatingRangeMax, ...args }) { - const cube = useRef() +function FloatScene(props: ComponentProps) { + const cube = useRef(null) return ( <> - + @@ -41,15 +39,14 @@ function FloatScene({ floatingRangeMin, floatingRangeMax, ...args }) { ) } -export const FloatSt = (args) => -FloatSt.storyName = 'Default' -FloatSt.args = { - floatingRangeMin: undefined, - floatingRangeMax: 1, - rotationIntensity: 4, - floatIntensity: 2, - speed: 5, -} -FloatSt.argTypes = { - floatingRangeMin: { control: 'number' }, -} +export const FloatSt = { + render: (args) => , + name: 'Default', + + args: { + floatingRange: [undefined, 1], + rotationIntensity: 4, + floatIntensity: 2, + speed: 5, + }, +} satisfies Story diff --git a/.storybook/stories/FlyControls.stories.tsx b/.storybook/stories/FlyControls.stories.tsx index b5451126f..ea73dd324 100644 --- a/.storybook/stories/FlyControls.stories.tsx +++ b/.storybook/stories/FlyControls.stories.tsx @@ -1,29 +1,36 @@ import * as React from 'react' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' import { Box, FlyControls } from '../../src' -export const FlyControlsStory = ({ ...args }) => ( - <> - - - - - -) - -FlyControlsStory.args = { - autoForward: false, - dragToLook: false, - movementSpeed: 1.0, - rollSpeed: 0.005, -} - -FlyControlsStory.storyName = 'Default' - export default { title: 'Controls/FlyControls', component: FlyControls, decorators: [(storyFn) => {storyFn()}], +} satisfies Meta + +type Story = StoryObj + +function FlyControlsScene(props: React.ComponentProps) { + return ( + <> + + + + + + ) } + +export const FlyControlsSt = { + render: ({ ...args }) => , + args: { + autoForward: false, + dragToLook: false, + movementSpeed: 1.0, + rollSpeed: 0.005, + }, + name: 'Default', +} satisfies Story diff --git a/.storybook/stories/GizmoHelper.stories.tsx b/.storybook/stories/GizmoHelper.stories.tsx index a6da15da1..d1cfda34e 100644 --- a/.storybook/stories/GizmoHelper.stories.tsx +++ b/.storybook/stories/GizmoHelper.stories.tsx @@ -1,7 +1,22 @@ import * as React from 'react' import { Vector3 } from 'three' +import { Meta, StoryObj } from '@storybook/react' + import { GizmoHelper, OrbitControls, useGLTF, GizmoViewcube, TrackballControls, GizmoViewport } from '../../src' import { Setup } from '../Setup' +import { ComponentProps } from 'react' + +const alignments = [ + 'top-left', + 'top-right', + 'bottom-right', + 'bottom-left', + 'bottom-center', + 'center-right', + 'center-left', + 'center-center', + 'top-center', +] as const export default { title: 'Gizmos/GizmoHelper', @@ -13,131 +28,59 @@ export default { ), ], -} + args: { + alignment: alignments[2], + margin: [80, 80], + }, + argTypes: { + alignment: { + control: { type: 'select' }, + options: alignments, + }, + }, +} satisfies Meta -const alignment = [ - 'top-left', - 'top-right', - 'bottom-right', - 'bottom-left', - 'bottom-center', - 'center-right', - 'center-left', - 'center-center', - 'top-center', -] -const controls = ['OrbitControls', 'TrackballControls'] -const faces = ['Right', 'Left', 'Top', 'Bottom', 'Front', 'Back'] -const gizmos = ['GizmoViewcube', 'GizmoViewport'] +type Story = StoryObj -const args = { - alignment: alignment[2], - color: 'white', - colorX: 'red', - colorY: 'green', - colorZ: 'blue', - controls: controls[0], - faces, - gizmo: gizmos[0], - hideNegativeAxes: false, - hoverColor: '#999', - labelColor: 'black', - marginX: 80, - marginY: 80, - opacity: 1, - strokeColor: 'gray', - textColor: 'black', +function Tokyo() { + const { scene } = useGLTF('LittlestTokyo.glb') + + return } -const colorArgType = { control: { type: 'color' } } -const generalTable = { table: { categry: 'General' } } -const helperTable = { table: { category: 'GizmoHelper' } } -const viewcubeTable = { table: { category: 'GizmoViewcube' } } -const viewportTable = { table: { category: 'GizmoViewport' } } +const GizmoHelperScene1 = (props: ComponentProps) => { + return ( + + -const argTypes = { - alignment: { control: { type: 'select' }, options: alignment, ...helperTable }, - color: { ...colorArgType, ...viewcubeTable }, - colorX: { ...colorArgType, ...viewportTable }, - colorY: { ...colorArgType, ...viewportTable }, - colorZ: { ...colorArgType, ...viewportTable }, - controls: { - control: { type: 'select' }, - name: 'Controls', - options: controls, - ...generalTable, - }, - faces: { - control: { type: 'array' }, - options: faces, - ...viewcubeTable, - }, - gizmo: { - control: { type: 'select' }, - name: 'Gizmo', - options: gizmos, - ...generalTable, - }, - hideNegativeAxes: { ...viewportTable }, - hoverColor: { ...viewportTable }, - labelColor: { ...viewportTable }, - marginX: { ...helperTable }, - marginY: { ...helperTable }, - opacity: { - control: { min: 0, max: 1, step: 0.01, type: 'range' }, - ...viewcubeTable, - }, - strokeColor: { ...colorArgType, ...viewcubeTable }, - textColor: { ...colorArgType, ...viewcubeTable }, + + + + + + ) } -const GizmoHelperStoryImpl = ({ - alignment, - color, - colorX, - colorY, - colorZ, - controls, - faces, - gizmo, - hideNegativeAxes, - hoverColor, - labelColor, - marginX, - marginY, - opacity, - strokeColor, - textColor, -}) => { - const { scene } = useGLTF('LittlestTokyo.glb') +export const GizmoHelperSt1: Story = { + name: 'Cube', + render: (args) => , +} satisfies Story +const GizmoHelperScene2 = (props: ComponentProps) => { return ( - <> - - - {gizmo === 'GizmoViewcube' ? ( - - ) : ( - - )} + + + + + - {controls === 'TrackballControls' ? : } - + + ) } -export const GizmoHelperStory = (props) => - -GizmoHelperStory.args = args -GizmoHelperStory.argTypes = argTypes -GizmoHelperStory.storyName = 'Default' +export const GizmoHelperSt2: Story = { + name: 'Viewport', + render: (args) => , +} satisfies Story diff --git a/.storybook/stories/Grid.stories.tsx b/.storybook/stories/Grid.stories.tsx index 47563592f..1ae91a58c 100644 --- a/.storybook/stories/Grid.stories.tsx +++ b/.storybook/stories/Grid.stories.tsx @@ -1,5 +1,6 @@ import * as React from 'react' import { Vector3 } from 'three' +import { Meta, StoryObj } from '@storybook/react' import { Setup } from '../Setup' import { Grid, Box } from '../../src' @@ -8,12 +9,14 @@ export default { title: 'Gizmos/Grid', component: Grid, decorators: [(storyFn) => {storyFn()}], -} +} satisfies Meta + +type Story = StoryObj -function UseGridScene() { +function GridScene(props: React.ComponentProps) { return ( - + @@ -22,7 +25,11 @@ function UseGridScene() { ) } -export const UseGridSceneSt = () => -UseGridSceneSt.story = { +export const GridSt = { + render: (args) => , + args: { + cellColor: 'white', + args: [10, 10], + }, name: 'Default', -} +} satisfies Story diff --git a/.storybook/stories/Helper.stories.tsx b/.storybook/stories/Helper.stories.tsx index 0a6c415ac..2b1ee1976 100644 --- a/.storybook/stories/Helper.stories.tsx +++ b/.storybook/stories/Helper.stories.tsx @@ -3,47 +3,38 @@ import * as React from 'react' import * as THREE from 'three' import { BoxHelper, CameraHelper } from 'three' import { VertexNormalsHelper } from 'three-stdlib' +import { Meta, StoryObj } from '@storybook/react' + import { Helper, PerspectiveCamera, Sphere } from '../../src' import { Setup } from '../Setup' +import { ComponentProps } from 'react' export default { title: 'Gizmos/Helper', component: Helper, decorators: [(storyFn) => {storyFn()}], - args: { - showHelper: true, - }, - argTypes: { - showHelper: { - type: 'boolean', - }, - }, -} +} satisfies Meta -type StoryProps = { - showHelper: boolean -} +type Story = StoryObj -const Scene: React.FC = ({ showHelper }) => { +const HelperScene1 = (props: ComponentProps) => { return ( - {showHelper && ( - <> - - - - )} + + ) } -export const DefaultStory = (args: StoryProps) => -DefaultStory.storyName = 'Default' +export const HelperSt1 = { + render: (args) => , + name: 'Default', +} satisfies Story -const CameraScene: React.FC = ({ showHelper }) => { - const camera = React.useRef() +const HelperScene2 = (props: ComponentProps) => { + const camera = React.useRef(null) useFrame(({ clock }) => { const t = clock.getElapsedTime() @@ -60,10 +51,12 @@ const CameraScene: React.FC = ({ showHelper }) => { - {showHelper && } + ) } -export const CameraStory = (args: StoryProps) => -CameraStory.storyName = 'Camera Helper' +export const HelperSt2 = { + render: (args) => , + name: 'Camera Helper', +} satisfies Story