🎃

React+TypeScriptなWebアプリで、R3Fのtutorial11。(パラメータを設定できるやつ。Leva)

2023/12/24に公開

Abstract

今回の参考はここ(Leva)

結論

今回の成果物はココ↓
https://github.com/aaaa1597/react-r3f-tutorial011

前提

手順

1.プロジェクト生成 -> VSCodeで開く

めんどいから、このスケルトンコードから始める。react-r3f-tutorial009
で、下記コマンドでフォルダ名とか整備する。

フォルダリネームとか
$ BaseProject=react-r3f-tutorial009
$ NewProject=react-r3f-tutorial011
$ cd ~
$ rm -rf ${BaseProject}
$ git clone https://github.com/aaaa1597/${BaseProject}.git
$ rm -rf ${BaseProject}/.git
$ mv ${BaseProject} ${NewProject}
$ cd ${NewProject}

準備

$ npm install --save three
$ npm install --save @types/three
$ npm install --save @react-three/fiber
$ npm install --save @react-three/drei
$ npm install --save-dev leva

App.tsx

まず全体。

App.tsx
-import React, {useRef} from 'react';
+import React, {useRef, useMemo } from 'react';
import './App.css';
import { Canvas, useFrame, MeshProps  } from '@react-three/fiber'
import * as THREE from 'three'
import { OrbitControls } from '@react-three/drei'
+import { useControls } from 'leva'

const Box = (props: MeshProps) => {
  const ref = useRef<THREE.Mesh>(null!)

  useFrame((_, delta) => {
    if( !ref.current) return
    ref.current.rotation.x += 1 * delta
    ref.current.rotation.y += 0.5 * delta
  })

  return (
    <mesh {...props} ref={ref}>
      <boxGeometry />
      <meshBasicMaterial color={0x00ff00} wireframe />
    </mesh>
  )
}

const App = () => {
+  const options = useMemo(() => {
+    return {
+      x: { value: 0, min: 0, max: Math.PI * 2, step: 0.01 },
+      y: { value: 0, min: 0, max: Math.PI * 2, step: 0.01 },
+      z: { value: 0, min: 0, max: Math.PI * 2, step: 0.01 },
+      visible: true,
+      color: { value: 'lime' },
+    }
+  }, [])
+
+  const pA = useControls('Polyhedron A', options)
+  const pB = useControls('Polyhedron B', options)

return (
    <div style={{ width: "75vw", height: "75vh" }}>
      <Canvas camera={{ position: [3, 1, 2] }}>
        <ambientLight />
        <directionalLight />
-       <Box position={[-0.75, 0, 0]} name="A" />
-       <Box position={[0.75, 0, 0]} name="B" />
+       <Box position={[-0.75, 0, 0]} name="A" rotation={[pA.x, pA.y, pA.z]} visible={pA.visible}/>
+       <Box position={[0.75, 0, 0]} name="B" rotation={[pB.x, pB.y, pB.z]} visible={pB.visible}/>
-       <OrbitControls />
+       <OrbitControls target-y={1}/> /* ←これは意味なしtarget-y追加したらどうなるかな~と思っただけ */
        <axesHelper args={[5]} />
-       <gridHelper rotation={[Math.PI / 4, 0, 0]} />
+       <gridHelper args={[10,10]} />
      </Canvas>
    </div>
  );
}

export default App;


出来た!!
けど、colorの渡し方が分からんかったけん、実装できてない。

  • optionsの中に、colorを入れるだけで、colorピッカーが表示される。
  • const Box = (color: string, props: MeshProps) => { って形で、"color: string,"を追加する。
  • <Box />の引数に渡してあげる必要がある。 ← ----- ここが分からんかった。
    ↑これは自分の宿題。

まとめ

1.levaをインストール

$ npm install --save-dev leva

2.levaをimport

import { useControls } from 'leva'

3.levaを定義

optionsを定義する -> useControls()の引数に渡す。

  const options = useMemo(() => {
    return {
      x: { value: 0, min: 0, max: Math.PI * 2, step: 0.01 },
      y: { value: 0, min: 0, max: Math.PI * 2, step: 0.01 },
      z: { value: 0, min: 0, max: Math.PI * 2, step: 0.01 },
      visible: true,
      color: { value: 'lime' },
    }
  }, [])

  const pA = useControls('Polyhedron A', options)
  const pB = useControls('Polyhedron B', options)

4.levaを呼び出し

pA.xの形で、値をElementに設定する。

以上。


宿題解決!!

出来た!!

1.新規に型を作る。

App.tsx
+type BoxProps = Omit<MeshProps, string> & {
+  color?: string;
+  props: MeshProps;
+}

2.受けの型を変更

App.tsx
-const Box = (props: MeshProps) => {
+const Box = (boxprops: BoxProps) => {

3.引数の値を設定

App.tsx
   return (
-    <mesh {...props} ref={ref}>
+    <mesh {...boxprops.props} ref={ref}>
       <boxGeometry />
-      <meshBasicMaterial color={0x00ff00} wireframe />
+      <meshBasicMaterial color={boxprops.color} wireframe />
     </mesh>

4.引数に値を渡す

App.tsx
-        <Box position={[-0.75, 0, 0]} name="A" rotation={[pA.x, pA.y, pA.z]} visible={pA.visible}/>
-        <Box position={[0.75, 0, 0]} name="B" rotation={[pB.x, pB.y, pB.z]} visible={pB.visible}/>
+        <Box color={pA.color} props={{position:[-0.75, 0, 0], name:"A", rotation:[pA.x, pA.y, pA.z], visible:pA.visible}} />
+        <Box color={pB.color} props={{position:[ 0.75, 0, 0], name:"B", rotation:[pB.x, pB.y, pB.z], visible:pB.visible}} />

React+TypeScriptなWebアプリで、R3Fのtutorial10。(gridHelper、axesHelper)


React+TypeScriptなWebアプリで、R3Fのtutorial12。(Materials)

Discussion