見出し画像

CodePenでesm.shでお手軽にReact Three Fiberを使用してみるテスト1 基本図形表示

 前回からのつづきです。 esm.shを使用したCodePenのコードで、React Three Fiberによる基本的な3Dオブジェクトを表示してみました。


概要

 最初に、Test01やTest02のコードにて、前回のJavaScriptコードの書き方にHTMLをまぜないようにして、よく見るReact Three Fiberのコードのサンプルに近い見た目になるようにしました(←でないと自分がよくわからなくなってしまうのでw)。 それに合わせてCodePenではBabelをPreprocessorに設定しています。 

 そうしてできるだけ、本家サイトのサンプルコードの見た目に近づけてから、後はそこからfork(コードのコピペのようなもの)して、Test03~Test11で、それぞれの基本的な3Dオブジェクトを表示させるコードを作成しています。

参考:import文そのままになりますが、使用したライブラリ等のバージョンは以下になります

react、react-dom、react-three/fiberのバージョンはコードを書き始めたときに、本家サイトのサンプルのlive demoで使用されていたものにあわせています。 threeのものはesm.shでバージョンを何も指定しない場合のもの(そのときの最新版?)をそのままテキトーw使用しています。

import ReactDOM from 'https://esm.sh/react-dom@18.2.0'
import React, { useRef, useState } from 'https://esm.sh/react@18.2.0'
import { Canvas, useFrame } from 'https://esm.sh/@react-three/fiber@8.15.12'
import { DoubleSide } from 'https://esm.sh/three@0.163.0'
import * as THREE from 'https://esm.sh/three@0.163.0'

以下作成したコードのリストとなります。 各コードにて、タイトル文字によるリンクはコード付きCodePenへのリンク、サムネイル画像によるリンクはコードなしのコード実行結果の全画面表示へのリンク、となります。 

あと、JavaScriptのコードをそのまま載せているので、冗長な感じでこのnoteエントリけっこう長いです、ご注意ください。


React Three Fiber 8.15.12 Test01

React Three Fiber 8.15.12 Test01

HTML

CSS

* {
  box-sizing: border-box;
}

html,
body,
#root {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

body {
  background: #f0f0f0;
}

JS(JavaScript)

import ReactDOM from 'https://esm.sh/react-dom@18.2.0'
import React, { useRef, useState } from 'https://esm.sh/react@18.2.0'
import { Canvas, useFrame } from 'https://esm.sh/@react-three/fiber@8.15.12'

function Box(props) {
  const meshRef = useRef();
  useFrame((state, delta) => (meshRef.current.rotation.z += 0.01));
  
  return (
    <mesh
      {...props}
      ref={meshRef}>
      <boxGeometry args={props.size} />
      <meshStandardMaterial color={props.color} />
    </mesh>
  )
}

const App = () => (
  <Canvas shadows camera={{ position: [0, -15, 5], fov: 22 }}>
    <ambientLight intensity={Math.PI / 2} />
    <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
    <pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
    <Box name='box' position={[0, 0, 1]} size={[2, 2, 2]} color='orange' />

  </Canvas>
);

ReactDOM.render(
  <App/>,
  document.body
);

 最初の、前回のJavaScriptコードからできるだけHTMLの部分を削除したものです。 今後の作業のしやすさのため、自分の理解のしやすさのため、できるだけ基本的なサンプルコードの見た目となるようにしました。 

 イメージとしては本家サイトにある React Three Fiber > Installation > Without build tools の Full example で出てくるコードを、こちらも本家サイト React Three Fiber > Introduction > What does it look like? の live demo に使用されているコードのような 見た目にした感じでしょうか。

 その基本的なサンプルに近い見た目とするため、CodePenではPreprocessorとしてBebelを使用するようにしました。 TypescriptのPreprocessorでも動くようでしたが、Typescript感の全くない自分に甘々ヴァニラなJavaScriptコードなのでBabel使用ですw。

以下のコードとサイトを参考にさせていただきました
react-three-fiber
React Three Fiber > GETTING STARTED > Introduction


React Three Fiber 8.15.12 Test02

React Three Fiber 8.15.12 Test02

HTML

<div id="root"></div>

CSS

* {
  box-sizing: border-box;
}

html,
body,
#root {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

body {
  background: #f0f0f0;
}

JS(JavaScript)

import ReactDOM from 'https://esm.sh/react-dom@18.2.0'
import React, { useRef, useState } from 'https://esm.sh/react@18.2.0'
import { Canvas, useFrame } from 'https://esm.sh/@react-three/fiber@8.15.12'

const Box = (props) => {
  const meshRef = useRef();
  const [hovered, setHover] = useState(false)
  const [active, setActive] = useState(false)
  useFrame((state, delta) => (meshRef.current.rotation.x += delta))
  return (
    <mesh
      {...props}
      ref={meshRef}
      scale={active ? 1.5 : 1}
      onClick={(event) => setActive(!active)}
      onPointerOver={(event) => setHover(true)}
      onPointerOut={(event) => setHover(false)}>
      <boxGeometry args={[1, 1, 1]} />
      <meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
    </mesh>
  )
}

const App = () => (
  <Canvas>
    <ambientLight intensity={Math.PI / 2} />
    <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
    <pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
    <Box position={[-1.2, 0, 0]} />
    <Box position={[1.2, 0, 0]} />
  </Canvas>
);

ReactDOM.render(
  <App/>,
  document.getElementById("root")
);

 Test01から2個のBoxが表示されるようにして、より基本的なサンプルに近づけました。 
HTMLへの<div id="root"></div>、
JavaScriptへのdocument.getElementById("root")、
も追加しています。 あとで React Router と一緒に React Three Fiber が使えないか実験するため、CodePenで動いた React Router のコードの形と同じにしています。

自分の作成したものも含め、以下のコードとサイトを参考にさせていただきました
React Three Fiber > GETTING STARTED > Introduction
hello-react-router-v6 test06


React Three Fiber 8.15.12 Test03 Box

React Three Fiber 8.15.12 Test03 Box

HTML Test02と同じです

CSS Test02と同じです

JS(JavaScript)

import ReactDOM from 'https://esm.sh/react-dom@18.2.0'
import React, { useRef, useState } from 'https://esm.sh/react@18.2.0'
import { Canvas, useFrame } from 'https://esm.sh/@react-three/fiber@8.15.12'

const Box = (props) => {
  const meshRef = useRef();
  const [hovered, setHover] = useState(false)
  const [active, setActive] = useState(false)

  useFrame((state) => {
    meshRef.current.rotation.x = state.mouse.x * 5
    meshRef.current.rotation.y = state.mouse.y * 5
  }, [])

  return (
    <mesh
      {...props}
      ref={meshRef}
      scale={active ? 1.5 : 1}
      onClick={(event) => setActive(!active)}
      onPointerOver={(event) => setHover(true)}
      onPointerOut={(event) => setHover(false)}>
      <boxGeometry args={[1, 1, 1]} />
      <meshStandardMaterial color={hovered ? 'red' : 'blue'} />
    </mesh>
  )
}

const App = () => (
  <Canvas>
    <ambientLight intensity={Math.PI / 2} />
    <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
    <pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
    <Box position={[-1.2, 0, 0]} />
    <Box position={[1.2, 0, 0]} />
  </Canvas>
);

ReactDOM.render(
  <App/>,
  document.getElementById("root")
);

 Boxの3Dオブジェクトを表示しています。 元々の基本サンプルのBoxから、Boxの色を赤と青に変更して、マウスの位置を元にBoxが回転するように修正しています。

前に自分で作成した以下のサイトの記録を参考にして作成してみました
CodeSandboxでReact Three Fiber実験その1 > React Three Fiber Practice02 Box Rotation by Mouse Move


React Three Fiber 8.15.12 Test04 Plane

React Three Fiber 8.15.12 Test04 Plane

HTML Test02と同じです

CSS Test02と同じです

JS(JavaScript)

import ReactDOM from 'https://esm.sh/react-dom@18.2.0'
import React, { useRef, useState } from 'https://esm.sh/react@18.2.0'
import { Canvas, useFrame } from 'https://esm.sh/@react-three/fiber@8.15.12'
import { DoubleSide } from 'https://esm.sh/three@0.163.0'

const Plane = (props) => {
  const meshRef = useRef();
  const [hovered, setHover] = useState(false)
  const [active, setActive] = useState(false)

  useFrame((state) => {
    meshRef.current.rotation.x = state.mouse.x * 5
    meshRef.current.rotation.y = state.mouse.y * 5
  }, [])

  return (
    <mesh
      {...props}
      ref={meshRef}
      scale={active ? 1.5 : 1}
      onClick={(event) => setActive(!active)}
      onPointerOver={(event) => setHover(true)}
      onPointerOut={(event) => setHover(false)}>
      <planeGeometry args={[2, 2, 2]} />
      <meshStandardMaterial color={hovered ? 'red' : 'blue'} side={DoubleSide} />
    </mesh>
  )
}

const App = () => (
  <Canvas>
    <ambientLight intensity={Math.PI / 2} />
    <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
    <pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
    <Plane position={[-2.0, 0, 0]} />
    <Plane position={[2.0, 0, 0]} />
  </Canvas>
);

ReactDOM.render(
  <App/>,
  document.getElementById("root")
);

 表示する3DオブジェクトをBoxからPlaneに変更しています。

Plane の DoubleSide を使用するにあたって以下のコードを参考にさせていただきました
The texture is not applied to the second side, or it is applied, but the model becomes flat #2950
【React Three Fiber】Reactで作る3D【#10useTexture】

自分で作成した以下のサイト・コードも参考にしました
CodeSandboxでReact Three Fiber実験その1 > React Three Fiber Practice06 Plane


React Three Fiber 8.15.12 Test05 Sphere

React Three Fiber 8.15.12 Test05 Sphere

HTML Test02と同じです

CSS Test02と同じです

JS(JavaScript)

import ReactDOM from 'https://esm.sh/react-dom@18.2.0'
import React, { useRef, useState } from 'https://esm.sh/react@18.2.0'
import { Canvas, useFrame } from 'https://esm.sh/@react-three/fiber@8.15.12'

const Sphere = (props) => {
  const meshRef = useRef();
  const [hovered, setHover] = useState(false)
  const [active, setActive] = useState(false)

  useFrame((state) => {
    meshRef.current.rotation.x = state.mouse.x * 5
    meshRef.current.rotation.y = state.mouse.y * 5
  }, [])

  return (
    <mesh
      {...props}
      ref={meshRef}
      scale={active ? 1.5 : 1}
      onClick={(event) => setActive(!active)}
      onPointerOver={(event) => setHover(true)}
      onPointerOut={(event) => setHover(false)}>
      <sphereGeometry args={[2, 25, 25]} />
      <meshStandardMaterial wireframe color={hovered ? 'red' : 'blue'} />
    </mesh>
  )
}

const App = () => (
  <Canvas>
    <ambientLight intensity={Math.PI / 2} />
    <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
    <pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
    <Sphere position={[0, 0, 0]} />
  </Canvas>
);

ReactDOM.render(
  <App/>,
  document.getElementById("root")
);

 Sphereの3Dオブジェクトを表示しています。

前に自分で作成した以下のサイトの記録を参考にして作成してみました
CodeSandboxでReact Three Fiber実験その1 > React Three Fiber Practice07 Sphere


React Three Fiber 8.15.12 Test06 Torus

React Three Fiber 8.15.12 Test06 Torus

HTML Test02と同じです

CSS Test02と同じです

JS(JavaScript)

import ReactDOM from 'https://esm.sh/react-dom@18.2.0'
import React, { useRef, useState } from 'https://esm.sh/react@18.2.0'
import { Canvas, useFrame } from 'https://esm.sh/@react-three/fiber@8.15.12'

const Torus = (props) => {
  const meshRef = useRef();
  const [hovered, setHover] = useState(false)
  const [active, setActive] = useState(false)

  useFrame((state) => {
    meshRef.current.rotation.x = state.mouse.x * 5
    meshRef.current.rotation.y = state.mouse.y * 5
  }, [])

  return (
    <mesh
      {...props}
      ref={meshRef}
      scale={active ? 1.5 : 1}
      onClick={(event) => setActive(!active)}
      onPointerOver={(event) => setHover(true)}
      onPointerOut={(event) => setHover(false)}>
      <torusGeometry args={[1.2, 0.3, 16, 100]} />
      <meshStandardMaterial color={hovered ? 'tomato' : 'green'} />
    </mesh>
  )
}

const App = () => (
  <Canvas>
    <ambientLight intensity={Math.PI / 2} />
    <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
    <pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
    <Torus position={[0, 0, 0]} />
  </Canvas>
);

ReactDOM.render(
  <App/>,
  document.getElementById("root")
);

 Torusオブジェトの表示です。

前に自分で作成した以下のサイトの記録を参考にして作成してみました
CodeSandboxでReact Three Fiber実験その1 > React Three Fiber Practice08 Torus


React Three Fiber 8.15.12 Test07 TorusKnot

React Three Fiber 8.15.12 Test07 TorusKnot

HTML Test02と同じです

CSS Test02と同じです

JS(JavaScript)

import ReactDOM from 'https://esm.sh/react-dom@18.2.0'
import React, { useRef, useState } from 'https://esm.sh/react@18.2.0'
import { Canvas, useFrame } from 'https://esm.sh/@react-three/fiber@8.15.12'

const Torusknot = (props) => {
  const meshRef = useRef();
  const [hovered, setHover] = useState(false)
  const [active, setActive] = useState(false)

  useFrame((state) => {
    meshRef.current.rotation.x = state.mouse.x * 5
    meshRef.current.rotation.y = state.mouse.y * 5
  }, [])

  return (
    <mesh
      {...props}
      ref={meshRef}
      scale={active ? 1.5 : 1}
      onClick={(event) => setActive(!active)}
      onPointerOver={(event) => setHover(true)}
      onPointerOut={(event) => setHover(false)}>
      <torusKnotGeometry args={[1.2, 0.3, 16, 100]} />
      <meshStandardMaterial color={hovered ? 'tomato' : 'green'} />
    </mesh>
  )
}

const App = () => (
  <Canvas>
    <ambientLight intensity={Math.PI / 2} />
    <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
    <pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
    <Torusknot position={[0, 0, 0]} />
  </Canvas>
);

ReactDOM.render(
  <App/>,
  document.getElementById("root")
);

 TorusKnotオブジェクトの表示です。

前に自分で作成した以下のサイトの記録を参考にして作成してみました
CodeSandboxでReact Three Fiber実験その1 > React Three Fiber Practice09 Torusknot

React Three Fiber 8.15.12 Test08 Cylinder

React Three Fiber 8.15.12 Test08 Cylinder

HTML Test02と同じです

CSS Test02と同じです

JS(JavaScript)

import ReactDOM from 'https://esm.sh/react-dom@18.2.0'
import React, { useRef, useState } from 'https://esm.sh/react@18.2.0'
import { Canvas, useFrame } from 'https://esm.sh/@react-three/fiber@8.15.12'

const Cylinder = (props) => {
  const meshRef = useRef();
  const [hovered, setHover] = useState(false)
  const [active, setActive] = useState(false)

  useFrame((state) => {
    meshRef.current.rotation.x = state.mouse.x * 5
    meshRef.current.rotation.y = state.mouse.y * 5
    meshRef.current.rotation.z = (state.mouse.x + state.mouse.y) / 2  * 5
  }, [])

  return (
    <mesh
      {...props}
      ref={meshRef}
      scale={active ? 1.5 : 1}
      onClick={(event) => setActive(!active)}
      onPointerOver={(event) => setHover(true)}
      onPointerOut={(event) => setHover(false)}>
      <cylinderGeometry args={[0.5, 1, 2, 16]} />
      <meshStandardMaterial color={hovered ? 'red' : props.color} />
    </mesh>
  )
}

const App = () => (
  <Canvas>
    <ambientLight intensity={Math.PI / 2} />
    <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
    <pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
    <Cylinder position={[0, 0, 0]}  color={'blue'} />
  </Canvas>
);

ReactDOM.render(
  <App/>,
  document.getElementById("root")
);

 Cylinderオブジェクトの表示です。

前に自分で作成した以下のサイトの記録を参考にして作成してみました
CodeSandboxでReact Three Fiber実験その1 > React Three Fiber Practice10 Cylinder


React Three Fiber 8.15.12 Test09 Textured Box

React Three Fiber 8.15.12 Test09 Textured Box

HTML Test02と同じです

CSS

* {
  box-sizing: border-box;
}

html,
body,
#root {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

body {
  background: #101010;
}

JS(JavaScript)

import ReactDOM from 'https://esm.sh/react-dom@18.2.0'
import React, { useRef, useState } from 'https://esm.sh/react@18.2.0'
import { Canvas, useFrame } from 'https://esm.sh/@react-three/fiber@8.15.12'
import * as THREE from 'https://esm.sh/three@0.163.0'
//↓これをつかうとエラー発生
//import img from 'https://rawcdn.githack.com/mrdoob/three.js/2ff77e4b335e31c108aac839a07401664998c730/examples/textures/crate.gif'

const textureImageURL = 'https://rawcdn.githack.com/mrdoob/three.js/2ff77e4b335e31c108aac839a07401664998c730/examples/textures/crate.gif'

const Box = (props) => {

  const textureImg = new THREE.TextureLoader().load(textureImageURL);

  const meshRef = useRef();

  const [clicked, click] = useState(false)

  useFrame((state) => {
    meshRef.current.rotation.x = state.mouse.x * 5
    meshRef.current.rotation.y = state.mouse.y * 5
    meshRef.current.rotation.z = (state.mouse.x + state.mouse.y) / 2  * 5
  }, [])

  return (
    <mesh
      {...props}
      ref={meshRef}
      scale={clicked ? 1.5 : 1}
      onClick={(event) => click(!clicked)}>
      <boxGeometry args={[2, 2, 2]} />
      <meshStandardMaterial map={textureImg} />
    </mesh>
  )

}

const App = () => (
  <Canvas>
    <ambientLight intensity={Math.PI / 2} />
    <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
    <pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
    <Box position={[0, 0, 0]} />
  </Canvas>
);

ReactDOM.render(
  <App/>,
  document.getElementById("root")
);

 Boxにテクスチャーを貼り付けたものを表示しています。 テクスチャーはThree.jsのサンプルにあったものを githack 経由で使用しています。 見やすさのために背景もCSSで黒に変更してみました。 
 CodeSandboxで使用していた import img from 'https://…. は使えないようでした。 ファイルが同じ鯖上publicフォルダにないと使えない?

以下のサイトを参考にさせていただきました
mrdoob/three.js/examples/textures/crate.gif
Loading three.js texture in react as base64 string

自分で作成した以下のサイト・コードも参考にしました
Three.js r110でテクスチャを貼り付けたBoxを表示
CodeSandboxでReact Three Fiber実験その1 > React Three Fiber Practice11 Box Texture


React Three Fiber 8.15.12 Test09_02 Textured Box

React Three Fiber 8.15.12 Test09_02 Textured Box

HTML Test09 Textured Box と同じです

CSS Test09 Textured Box と同じです

JS(JavaScript)

import ReactDOM from 'https://esm.sh/react-dom@18.2.0'
import React, { useRef, useState } from 'https://esm.sh/react@18.2.0'
import { Canvas, useFrame } from 'https://esm.sh/@react-three/fiber@8.15.12'
import * as THREE from 'https://esm.sh/three@0.163.0'

const textureImageURL = 'data:image/jpeg;base64,/9j/4AAQS ~ 省略 ~ UUUAf/2Q=='

const Box = (props) => {

  const textureImg = new THREE.TextureLoader().load(textureImageURL);

  const meshRef = useRef();

  const [clicked, click] = useState(false)

  useFrame((state) => {
    meshRef.current.rotation.x = state.mouse.x * 5
    meshRef.current.rotation.y = state.mouse.y * 5
    meshRef.current.rotation.z = (state.mouse.x + state.mouse.y) / 2  * 5
  }, [])

  return (
    <mesh
      {...props}
      ref={meshRef}
      scale={clicked ? 1.5 : 1}
      onClick={(event) => click(!clicked)}>
      <boxGeometry args={[2, 2, 2]} />
      <meshStandardMaterial map={textureImg} />
    </mesh>
  )

}

const App = () => (
  <Canvas>
    <ambientLight intensity={Math.PI / 2} />
    <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
    <pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
    <Box position={[0, 0, 0]} />
  </Canvas>
);

ReactDOM.render(
  <App/>,
  document.getElementById("root")
);

 Boxにテクスチャーを貼り付けたものを表示しています。 このコードではテクスチャーに使用する画像をBase64によるものにしています。 こちらのBase64方式でもテクスチャの画像として使用できるようです。

自分で作成した以下のサイト・コードを参考にしました
Three.js r110でテクスチャを貼り付けたBoxを表示
CodeSandboxでReact Three Fiber実験その1 > React Three Fiber Practice11 Box Texture


Texture Images by Base64

Texture Images by Base64

HTML なし

CSS なし

JS(JavaScript)

const zakuLikeImage = "data:image/jpeg;base64,/9j/4AAQSk ~ 省略 ~ UUUAf/2Q==";

const slimeLikeImage = "data:image/jpeg;base64,/9j/4AAQSk ~ 省略 ~ ABRRRQB//Z";

const earthImage = "data:image/jpeg;base64,/9j/4AAQSk ~ 省略 ~ c7Dc//2Q==";

 Test09_02 Textured BoxでBase64がテクスチャー用画像として使用できたので、CodePenの機能でBase64の文字列を外出ししたファイルから読み込むような感じにしてみました。 Base64の文字列が長くていろいろ作業が煩雑なので外部に切り出しです。 
 
 具体的には、この Texture Images by Base64 にテクスチャ画像として使用するBase64文字列をまとめて記述して、ほかのCodePenコードから読み込むようにしました。 その後、Texture Images by Base64 を他のCodePenのコードで取り込むようにすれば、あとはzakuLikeImage、slimeLikeImage、earthImageを参照・代入するだけでBase64の文字列が使用できるようになりました。


React Three Fiber 8.15.12 Test09_03 Textured Box

React Three Fiber 8.15.12 Test09_03 Textured Box

HTML Test09 Textured Box と同じです

CSS Test09 Textured Box と同じです

JS(JavaScript)

import ReactDOM from 'https://esm.sh/react-dom@18.2.0'
import React, { useRef, useState } from 'https://esm.sh/react@18.2.0'
import { Canvas, useFrame } from 'https://esm.sh/@react-three/fiber@8.15.12'
import * as THREE from 'https://esm.sh/three@0.163.0'

const textureImageURL = zakuLikeImage

const Box = (props) => {

  const textureImg = new THREE.TextureLoader().load(textureImageURL);

  const meshRef = useRef();

  const [clicked, click] = useState(false)

  useFrame((state) => {
    meshRef.current.rotation.x = state.mouse.x * 5
    meshRef.current.rotation.y = state.mouse.y * 5
    meshRef.current.rotation.z = (state.mouse.x + state.mouse.y) / 2  * 5
  }, [])

  return (
    <mesh
      {...props}
      ref={meshRef}
      scale={clicked ? 1.5 : 1}
      onClick={(event) => click(!clicked)}>
      <boxGeometry args={[2, 2, 2]} />
      <meshStandardMaterial map={textureImg} />
    </mesh>
  )

}

const App = () => (
  <Canvas>
    <ambientLight intensity={Math.PI / 2} />
    <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
    <pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
    <Box position={[0, 0, 0]} />
  </Canvas>
);

ReactDOM.render(
  <App/>,
  document.getElementById("root")
);

 BoxにBase64による画像のテクスチャを貼り付けて表示しています。 画像のBase64文字列は上記で作成した Texture Images by Base64 より取得しています。

自分で作成した以下のサイト・コードを参考にしました
Three.js r110でテクスチャを貼り付けたBoxを表示
CodeSandboxでReact Three Fiber実験その1 > React Three Fiber Practice11 Box Texture


React Three Fiber 8.15.12 Test10 Textured Plane

React Three Fiber 8.15.12 Test10 Textured Plane

HTML Test09 Textured Box と同じです

CSS Test09 Textured Box と同じです

JS(JavaScript)

import ReactDOM from 'https://esm.sh/react-dom@18.2.0'
import React, { useRef, useState } from 'https://esm.sh/react@18.2.0'
import { Canvas, useFrame } from 'https://esm.sh/@react-three/fiber@8.15.12'
import * as THREE from 'https://esm.sh/three@0.163.0'
import { DoubleSide } from 'https://esm.sh/three@0.163.0'

const textureImageURL = slimeLikeImage

const Plane = (props) => {

  const textureImg = new THREE.TextureLoader().load(textureImageURL);

  const meshRef = useRef();

  const [clicked, click] = useState(false)

  useFrame((state) => {
    meshRef.current.rotation.x = state.mouse.x * 5
    meshRef.current.rotation.y = state.mouse.y * 5
    meshRef.current.rotation.z = (state.mouse.x + state.mouse.y) / 2  * 5
  }, [])

  return (
    <mesh
      {...props}
      ref={meshRef}
      scale={clicked ? 1.5 : 1}
      onClick={(event) => click(!clicked)}>
      <planeGeometry args={[3, 3, 3]} />
      <meshStandardMaterial map={textureImg} side={DoubleSide} />
    </mesh>
  )

}

const App = () => (
  <Canvas>
    <ambientLight intensity={Math.PI / 2} />
    <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
    <pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
    <Plane position={[0, 0, 0]} />
  </Canvas>
);

ReactDOM.render(
  <App/>,
  document.getElementById("root")
);

 PlaneにBase64による画像のテクスチャを貼り付けて表示しています。 画像のBase64文字列は上記で作成した Texture Images by Base64 より取得しています。

Plane の DoubleSide を使用するにあたって以下のコードを参考にさせていただきました
The texture is not applied to the second side, or it is applied, but the model becomes flat #2950
【React Three Fiber】Reactで作る3D【#10useTexture】

自分で作成した以下のサイト・コードも参考にしました
Three.js r110でテクスチャを貼り付けたPlaneを表示
CodeSandboxでReact Three Fiber実験その1 > React Three Fiber Practice12 Plane Texture


React Three Fiber 8.15.12 Test11 Textured Sphere

React Three Fiber 8.15.12 Test11 Textured Sphere

HTML Test09 Textured Box と同じです

CSS Test09 Textured Box と同じです

JS(JavaScript)

import ReactDOM from 'https://esm.sh/react-dom@18.2.0'
import React, { useRef, useState } from 'https://esm.sh/react@18.2.0'
import { Canvas, useFrame } from 'https://esm.sh/@react-three/fiber@8.15.12'
import * as THREE from 'https://esm.sh/three@0.163.0'

const textureImageURL = earthImage

const Plane = (props) => {

  const textureImg = new THREE.TextureLoader().load(textureImageURL);

  const meshRef = useRef();

  const [clicked, click] = useState(false)

  useFrame((state) => {
    meshRef.current.rotation.x = state.mouse.x * 5
    meshRef.current.rotation.y = state.mouse.y * 5
    meshRef.current.rotation.z = (state.mouse.x + state.mouse.y) / 2  * 5
  }, [])

  return (
    <mesh
      {...props}
      ref={meshRef}
      scale={clicked ? 1.5 : 1}
      onClick={(event) => click(!clicked)}>
      <sphereGeometry args={[2, 25, 25]} />
      <meshStandardMaterial map={textureImg} />
    </mesh>
  )

}

const App = () => (
  <Canvas>
    <ambientLight intensity={Math.PI / 2} />
    <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
    <pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
    <Plane position={[0, 0, 0]} />
  </Canvas>
);

ReactDOM.render(
  <App/>,
  document.getElementById("root")
);

 SphereにBase64による画像のテクスチャを貼り付けて表示しています。 画像のBase64文字列は上記で作成した Texture Images by Base64 より取得しています。

自分で作成した以下のサイト・コードを参考にしました
Three.js r110でテクスチャを貼り付けたSphereを表示
CodeSandboxでReact Three Fiber実験その1 > React Three Fiber Practice13 Sphere Texture


次回


この記事が気に入ったらサポートをしてみませんか?