我如何在没有反应三纤维的情况下访问纯的三j元素?

发布于 2025-01-18 14:57:54 字数 4853 浏览 2 评论 0原文

基本上,我想访问我的3D模型元素,并希望从另一个组件中控制相机和其他内容,例如网格,动画等。我正在使用纯三j,并为此做出反应。 我已经在React App类的ComponentDidmount部分中添加了纯三js代码,我想控制来自ComponentDidMount的相机部分,来自另一个名为CollapseButton的组件。如何从CollapseButton访问那些相机,场景,材料?另外,当我单击CollapseButton中的按钮时,我想在ComponentDidmount中使用三js部分执行特定任务。

简而言之:从CollapseButton开始,我想单击一个按钮,并在ComponentDidMount声明的纯三j部分上执行特定任务。单击CollapseButton&GT中定义的按钮;调用函数或在componentdidmount/trixjs零件上做某事

是我的app.js:js:

// ... App.js
import React from "react";
import ReactDOM from "react-dom";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import './App.css';
import CollapseButton from './CollapseButton'
class App extends React.Component {
  componentDidMount() {
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    this.mount.appendChild(renderer.domElement);

    const sizes = {
      width: window.innerWidth,
      height: window.innerHeight,
    };

    //Creating scene
    var scene = new THREE.Scene();

    //creating camera
    var camera = new THREE.PerspectiveCamera(
      75,
      window.innerWidth / window.innerHeight,
      0.1,
      1000
    );
    camera.position.x = 100;
    camera.position.y = 20;
    camera.position.z = 2;
    camera.lookAt(0, -10, 0);

    window.addEventListener("resize", () => {
      // Update sizes
      sizes.width = window.innerWidth;
      sizes.height = window.innerHeight;

      // Update camera
      camera.aspect = sizes.width / sizes.height;
      camera.updateProjectionMatrix();

      // Update renderer
      renderer.setSize(sizes.width, sizes.height);
      renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
    });

    //loader
    let mesh;
    const gltfLoader = new GLTFLoader();
    gltfLoader.load("LeftBankUnitBoxes.glb", handle_load);
    const texture = new THREE.TextureLoader();
    const grass = texture.load("/textures/Grass.PNG");
    function handle_load(gltf) {
      mesh = gltf.scene;
      mesh.traverse((child) => {
        // if (child.material && child.material.name === "M_UnitBox_349") {
        //     child.material.map=grass

        //     // console.log(child.material)

        //   }
        if (child.material) {
          child.material.map = grass;
          // child.material.metalness=0.8
          // child.material.roughness=0.2
          // child.material = new THREE.MeshStandardMaterial({
          //   map: grass,
          //   metalness:1,
          //   roughness:10,
          //   metalnessMap:asphalt,
          //   envMap:cubeTextureLoader
          //   // transparent:true,
          //   // opacity: 0.2,
          // });
          // console.log(child.material)
        }
      });

      mesh.position.y = -50;
      scene.add(mesh);
    }

    function call(){
      console.log("Calling log")
    }

    //creating controls
    const orbit = new OrbitControls(camera, renderer.domElement);
    orbit.maxPolarAngle = Math.PI / 2;
    // orbit.autoRotate = true;
    orbit.update();

    //creating lights

    var Dirlight = new THREE.DirectionalLight("#ffffff", 1);
    var ambient = new THREE.AmbientLight("#ffffff", 1);
    Dirlight.position.set(-50, 20, 0).normalize();

    Dirlight.castShadow = true;
    scene.add(Dirlight);

    scene.add(ambient);

    //animate
    var animate = function () {
      requestAnimationFrame(animate);

      renderer.render(scene, camera);
      orbit.update();
    };
    animate();
  }

  render() {
    return <div ref={(ref) => (this.mount = ref)} />;
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <>
    <App />
    <div className="Collapse">
      <CollapseButton call={call}/>
    </div>
  </>,
  rootElement
);
export default App;

这是我的colleapsebutton:

import React, { useState } from 'react'
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
import { Button } from '@mui/material';
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';

export default function Collapse({call}) {
    const [icon,setIcon]=useState(false)

    const show=()=>{
        //handleRender()
        call()
        setIcon(!icon)
    }
  return (
    <>
        <Button style={{maxWidth: '30px', maxHeight: '30px', minWidth: '30px', minHeight: '30px'}} onClick={show}>
            {icon?<ArrowBackIosIcon style={{color:'white',fontSize:24}}/>:<ArrowForwardIosIcon  style={{color:'white',fontSize:24,fontWeight:'bold'}} />}
        </Button>
        
    </>
  )
}

我尝试通过componentdidmount的函数传递到collapsebestton到collapsebutton,当我单击colleapsebutton的按钮时,它可能会打电话给,但找不到任何方法传递功能。

Basically, I want to access my 3D model element as well as want to control the camera and other things like mesh, animation etc from another component. I'm using pure threeJs and react for this.
I've added pure threejs code in the componentDidMount part of the react App class and I want to control suppose the camera part from componentDidMount from another component named CollapseButton. How can I access those camera,scene,materials from CollapseButton? Also when I click a button from CollapseButton I want to do a specific task with the threeJs part declared in the componentDidMount.

In short: From CollapseButton I want to click a button and do a specific task on the pure threeJs part declared in ComponentDidMount. Click a button defined in CollapseButton> Call a function or do something on componentDidmount/threejs part

Here is my App.js:

// ... App.js
import React from "react";
import ReactDOM from "react-dom";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import './App.css';
import CollapseButton from './CollapseButton'
class App extends React.Component {
  componentDidMount() {
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    this.mount.appendChild(renderer.domElement);

    const sizes = {
      width: window.innerWidth,
      height: window.innerHeight,
    };

    //Creating scene
    var scene = new THREE.Scene();

    //creating camera
    var camera = new THREE.PerspectiveCamera(
      75,
      window.innerWidth / window.innerHeight,
      0.1,
      1000
    );
    camera.position.x = 100;
    camera.position.y = 20;
    camera.position.z = 2;
    camera.lookAt(0, -10, 0);

    window.addEventListener("resize", () => {
      // Update sizes
      sizes.width = window.innerWidth;
      sizes.height = window.innerHeight;

      // Update camera
      camera.aspect = sizes.width / sizes.height;
      camera.updateProjectionMatrix();

      // Update renderer
      renderer.setSize(sizes.width, sizes.height);
      renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
    });

    //loader
    let mesh;
    const gltfLoader = new GLTFLoader();
    gltfLoader.load("LeftBankUnitBoxes.glb", handle_load);
    const texture = new THREE.TextureLoader();
    const grass = texture.load("/textures/Grass.PNG");
    function handle_load(gltf) {
      mesh = gltf.scene;
      mesh.traverse((child) => {
        // if (child.material && child.material.name === "M_UnitBox_349") {
        //     child.material.map=grass

        //     // console.log(child.material)

        //   }
        if (child.material) {
          child.material.map = grass;
          // child.material.metalness=0.8
          // child.material.roughness=0.2
          // child.material = new THREE.MeshStandardMaterial({
          //   map: grass,
          //   metalness:1,
          //   roughness:10,
          //   metalnessMap:asphalt,
          //   envMap:cubeTextureLoader
          //   // transparent:true,
          //   // opacity: 0.2,
          // });
          // console.log(child.material)
        }
      });

      mesh.position.y = -50;
      scene.add(mesh);
    }

    function call(){
      console.log("Calling log")
    }

    //creating controls
    const orbit = new OrbitControls(camera, renderer.domElement);
    orbit.maxPolarAngle = Math.PI / 2;
    // orbit.autoRotate = true;
    orbit.update();

    //creating lights

    var Dirlight = new THREE.DirectionalLight("#ffffff", 1);
    var ambient = new THREE.AmbientLight("#ffffff", 1);
    Dirlight.position.set(-50, 20, 0).normalize();

    Dirlight.castShadow = true;
    scene.add(Dirlight);

    scene.add(ambient);

    //animate
    var animate = function () {
      requestAnimationFrame(animate);

      renderer.render(scene, camera);
      orbit.update();
    };
    animate();
  }

  render() {
    return <div ref={(ref) => (this.mount = ref)} />;
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <>
    <App />
    <div className="Collapse">
      <CollapseButton call={call}/>
    </div>
  </>,
  rootElement
);
export default App;

Here is my CollapseButton:

import React, { useState } from 'react'
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
import { Button } from '@mui/material';
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';

export default function Collapse({call}) {
    const [icon,setIcon]=useState(false)

    const show=()=>{
        //handleRender()
        call()
        setIcon(!icon)
    }
  return (
    <>
        <Button style={{maxWidth: '30px', maxHeight: '30px', minWidth: '30px', minHeight: '30px'}} onClick={show}>
            {icon?<ArrowBackIosIcon style={{color:'white',fontSize:24}}/>:<ArrowForwardIosIcon  style={{color:'white',fontSize:24,fontWeight:'bold'}} />}
        </Button>
        
    </>
  )
}

I tried to pass a function from ComponentDidMount to CollapseButton which may called when I click a button from CollapseButton but couldn't find any way to pass the function.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

撩动你心 2025-01-25 14:57:54

您可以将对 ThreeJS 组件的引用存储在 React ref 中将其作为道具公开给您的折叠按钮(或者通过 React context 如果您打算使用它在不止一个组件)

作为道具:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.objectRef = React.createRef();
  }

  componentDidMount() {
    // ...three.js code
    this.objectRef.current = myObject;
  }

  render() {
    return (
     <>
       <div ref={(ref) => (this.mount = ref)} />
       <div className="Collapse">
         <CollapseButton call={call} object={objectRef} />
       </div>
     </>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <App />,
  rootElement
);
export default App;
export default function Collapse({ call, object }) {
  // ...

    const show=()=>{
        const myObject = object.current; // Get the object
        // Perform the task here

        call()
        setIcon(!icon)
    }

  // ...
}

使用上下文:

const ThreeContext = React.createContext({});

class App extends React.Component {
  constructor(props) {
    super(props);
    this.objectRef = React.createRef();
  }

  componentDidMount() {
    // ...three.js code
    this.objectRef.current = myObject;
  }

  render() {
    return (
     <ThreeContext.Provider value={{ object: this.objectRef }}>
       <div ref={(ref) => (this.mount = ref)} />
       <div className="Collapse">
         <CollapseButton call={call} />
       </div>
     </ThreeContext.Provider>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <App />,
  rootElement
);
export default App;
export default function Collapse({ call }) {
  // ...

    const show=()=>{
        const myObject = this.context.object?.current; // Get the object
        // Perform the task here

        call()
        setIcon(!icon)
    }

  // ...
}

You can store a reference to your threeJS component in a React ref and expose it to your collapse button as a prop (or by a React context if you plan to use it in more than one component)

As a prop:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.objectRef = React.createRef();
  }

  componentDidMount() {
    // ...three.js code
    this.objectRef.current = myObject;
  }

  render() {
    return (
     <>
       <div ref={(ref) => (this.mount = ref)} />
       <div className="Collapse">
         <CollapseButton call={call} object={objectRef} />
       </div>
     </>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <App />,
  rootElement
);
export default App;
export default function Collapse({ call, object }) {
  // ...

    const show=()=>{
        const myObject = object.current; // Get the object
        // Perform the task here

        call()
        setIcon(!icon)
    }

  // ...
}

Using context:

const ThreeContext = React.createContext({});

class App extends React.Component {
  constructor(props) {
    super(props);
    this.objectRef = React.createRef();
  }

  componentDidMount() {
    // ...three.js code
    this.objectRef.current = myObject;
  }

  render() {
    return (
     <ThreeContext.Provider value={{ object: this.objectRef }}>
       <div ref={(ref) => (this.mount = ref)} />
       <div className="Collapse">
         <CollapseButton call={call} />
       </div>
     </ThreeContext.Provider>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <App />,
  rootElement
);
export default App;
export default function Collapse({ call }) {
  // ...

    const show=()=>{
        const myObject = this.context.object?.current; // Get the object
        // Perform the task here

        call()
        setIcon(!icon)
    }

  // ...
}
满身野味 2025-01-25 14:57:54

移动

文件中

// Creating renderer
const renderer = new THREE.WebGLRenderer();
// Creating scene
const scene = new THREE.Scene();
// Creating camera
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);

const animate = function () {
  // requestAnimationFrame(this.animate);

  renderer.render(scene, camera);
  this.orbit.update();
};

export default {
  renderer,
  scene,
  camera,
  texture: new THREE.TextureLoader(),
  gltfLoader: new GLTFLoader(),
  gltfHandler: function (gltf) {
    console.log(this);
    const grass = this.texture.load('/textures/Grass.PNG');
    let mesh = gltf.scene;
    mesh.traverse((child) => {
      // if (child.material && child.material.name === "M_UnitBox_349") {
      //     child.material.map=grass

      //     // console.log(child.material)

      //   }
      if (child.material) {
        child.material.map = grass;
        // child.material.metalness=0.8
        // child.material.roughness=0.2
        // child.material = new THREE.MeshStandardMaterial({
        //   map: grass,
        //   metalness:1,
        //   roughness:10,
        //   metalnessMap:asphalt,
        //   envMap:cubeTextureLoader
        //   // transparent:true,
        //   // opacity: 0.2,
        // });
        // console.log(child.material)
      }
    });

    mesh.position.y = -50;
    scene.add(mesh);
  },
  orbit: new OrbitControls(camera, renderer.domElement),
  sizes: {
    width: window.innerWidth,
    height: window.innerHeight,
  },
  init: function () {
    this.renderer.setSize(window.innerWidth, window.innerHeight);

    this.camera.position.x = 100;
    this.camera.position.y = 20;
    this.camera.position.z = 2;
    this.camera.lookAt(0, -10, 0);

    window.addEventListener('resize', () => {
      // Update sizes
      this.sizes.width = window.innerWidth;
      this.sizes.height = window.innerHeight;

      // Update camera
      this.camera.aspect = this.sizes.width / this.sizes.height;
      this.camera.updateProjectionMatrix();

      // Update renderer
      this.renderer.setSize(this.sizes.width, this.sizes.height);
      this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
    });

    //loader
    this.gltfLoader.load('LeftBankUnitBoxes.glb', this.gltfHandler);

    //creating controls
    this.orbit.maxPolarAngle = Math.PI / 2;
    // orbit.autoRotate = true;
    this.orbit.update();

    //creating lights
    var Dirlight = new THREE.DirectionalLight('#ffffff', 1);
    var ambient = new THREE.AmbientLight('#ffffff', 1);
    Dirlight.position.set(-50, 20, 0).normalize();

    Dirlight.castShadow = true;
    this.scene.add(Dirlight);
    this.scene.add(ambient);
  },
  animate,
  call: function () {
    console.log('Calling log');
  },
};

import React from 'react';
import './style.css';

import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
import { Button } from '@mui/material';
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
import T3 from './T3'

class App extends React.Component {
  componentDidMount() {
    T3.init();
    this.mount.appendChild(T3.renderer.domElement);
    T3.animate();
  }

  render() {
    return <div ref={(ref) => (this.mount = ref)} />;
  }
}

您可以在不同 /strong>

import React, { useState } from 'react'
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
import { Button } from '@mui/material';
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
import T3 from './T3'

function Collapse({ call }) {
  const [icon, setIcon] = useState(false);

  const show = () => {
    //handleRender()
    T3.call();
    setIcon(!icon);
  };
  return (
    <>
      <Button
        style={{
          maxWidth: '30px',
          maxHeight: '30px',
          minWidth: '30px',
          minHeight: '30px',
        }}
        onClick={show}
      >
        {icon ? (
          <ArrowBackIosIcon style={{ color: 'white', fontSize: 24 }} />
        ) : (
          <ArrowForwardIosIcon
            style={{ color: 'white', fontSize: 24, fontWeight: 'bold' }}
          />
        )}
      </Button>
    </>
  );
}

You can move the three.js related code in different file and import where required

T3.js

// Creating renderer
const renderer = new THREE.WebGLRenderer();
// Creating scene
const scene = new THREE.Scene();
// Creating camera
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);

const animate = function () {
  // requestAnimationFrame(this.animate);

  renderer.render(scene, camera);
  this.orbit.update();
};

export default {
  renderer,
  scene,
  camera,
  texture: new THREE.TextureLoader(),
  gltfLoader: new GLTFLoader(),
  gltfHandler: function (gltf) {
    console.log(this);
    const grass = this.texture.load('/textures/Grass.PNG');
    let mesh = gltf.scene;
    mesh.traverse((child) => {
      // if (child.material && child.material.name === "M_UnitBox_349") {
      //     child.material.map=grass

      //     // console.log(child.material)

      //   }
      if (child.material) {
        child.material.map = grass;
        // child.material.metalness=0.8
        // child.material.roughness=0.2
        // child.material = new THREE.MeshStandardMaterial({
        //   map: grass,
        //   metalness:1,
        //   roughness:10,
        //   metalnessMap:asphalt,
        //   envMap:cubeTextureLoader
        //   // transparent:true,
        //   // opacity: 0.2,
        // });
        // console.log(child.material)
      }
    });

    mesh.position.y = -50;
    scene.add(mesh);
  },
  orbit: new OrbitControls(camera, renderer.domElement),
  sizes: {
    width: window.innerWidth,
    height: window.innerHeight,
  },
  init: function () {
    this.renderer.setSize(window.innerWidth, window.innerHeight);

    this.camera.position.x = 100;
    this.camera.position.y = 20;
    this.camera.position.z = 2;
    this.camera.lookAt(0, -10, 0);

    window.addEventListener('resize', () => {
      // Update sizes
      this.sizes.width = window.innerWidth;
      this.sizes.height = window.innerHeight;

      // Update camera
      this.camera.aspect = this.sizes.width / this.sizes.height;
      this.camera.updateProjectionMatrix();

      // Update renderer
      this.renderer.setSize(this.sizes.width, this.sizes.height);
      this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
    });

    //loader
    this.gltfLoader.load('LeftBankUnitBoxes.glb', this.gltfHandler);

    //creating controls
    this.orbit.maxPolarAngle = Math.PI / 2;
    // orbit.autoRotate = true;
    this.orbit.update();

    //creating lights
    var Dirlight = new THREE.DirectionalLight('#ffffff', 1);
    var ambient = new THREE.AmbientLight('#ffffff', 1);
    Dirlight.position.set(-50, 20, 0).normalize();

    Dirlight.castShadow = true;
    this.scene.add(Dirlight);
    this.scene.add(ambient);
  },
  animate,
  call: function () {
    console.log('Calling log');
  },
};

App.js

import React from 'react';
import './style.css';

import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
import { Button } from '@mui/material';
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
import T3 from './T3'

class App extends React.Component {
  componentDidMount() {
    T3.init();
    this.mount.appendChild(T3.renderer.domElement);
    T3.animate();
  }

  render() {
    return <div ref={(ref) => (this.mount = ref)} />;
  }
}

Collapse.js

import React, { useState } from 'react'
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
import { Button } from '@mui/material';
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
import T3 from './T3'

function Collapse({ call }) {
  const [icon, setIcon] = useState(false);

  const show = () => {
    //handleRender()
    T3.call();
    setIcon(!icon);
  };
  return (
    <>
      <Button
        style={{
          maxWidth: '30px',
          maxHeight: '30px',
          minWidth: '30px',
          minHeight: '30px',
        }}
        onClick={show}
      >
        {icon ? (
          <ArrowBackIosIcon style={{ color: 'white', fontSize: 24 }} />
        ) : (
          <ArrowForwardIosIcon
            style={{ color: 'white', fontSize: 24, fontWeight: 'bold' }}
          />
        )}
      </Button>
    </>
  );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文