如何将 three.js 图形绑定到 React 功能元素?

How to bind three.js graphics to React functional element?

我的功能性 React 组件正在使用 three.js(如下),使用是否合适:

return (
    <div key="0">
        <p key="1">{ animate() }</p>
    </div>
) 

将 three.js 绑定到功能性 React 组件?所有这些都是基于 class 使用 three.js 与 React 的示例。我也想知道 animate() 关键字本身的用法。似乎我在正文中有 运行 它,在组件中有 return 部分。

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import React, { useState, useEffect } from 'react'

const ThreeComp2 = () => {
    const [state, setState] = useState(null)
    
    var renderer = new THREE.WebGLRenderer({antialias:true});
    document.body.appendChild(renderer.domElement);
    renderer.setSize(1000, 1000);
    
    var textureLoader = new THREE.TextureLoader();
    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(28, 1, 1, 1000);
    camera.position.set(75, 25, 50);
    
    camera.lookAt(scene.position);
    scene.add(camera);
    
    camera.add(new THREE.PointLight(0xffffff, 1, Infinity));
    
    var cubeGeo = new THREE.BoxBufferGeometry(3,3, 0.0001);
    var uvs = cubeGeo.attributes.uv;
    
    uvs.setX(0, 1);
    uvs.setY(0, 1);
    uvs.setX(1, 0);
    uvs.setY(1, 1);
    uvs.setX(2, 1);
    uvs.setY(2, 0);
    uvs.setX(3, 0);
    uvs.setY(3, 0);
    uvs.needsUpdate = true;
    
    const geometry = new THREE.Geometry();
    
    geometry.vertices.push(
        new THREE.Vector3( -100,  100, 0 ),
        new THREE.Vector3( -100, -100, 0 ),
        new THREE.Vector3(  100, -100, 0 )
        );
        
    geometry.faces.push( new THREE.Face3(0, 1, 2 ) );
    
    function render() {
        renderer.render(scene, camera);
    }
    
    var controls = new OrbitControls(camera, renderer.domElement );
    controls.addEventListener('change', render); 
    
    function animate() {
        requestAnimationFrame(animate);
        render();
    }

    var texture = new THREE.TextureLoader().load(textureURL, function () { });
                
    var textureURL = "https://upload.wikimedia.org/wikipedia/commons/8/8a/Black_Monday_Dow_Jones.png";
    

    var mat = new THREE.MeshLambertMaterial({
        color: "white",
        map: textureLoader.load(textureURL, function () {
            animate();
            console.log('new THREE.MeshLambertMaterial({')
        })
    })
    
    var cubes = [];
    const n = 400;
    const V = 111;
    
    for (var i = 0; i < n; i++) {
        
        var mesh = new THREE.Mesh(cubeGeo, mat);
        
        cubes[i] = mesh
        var x = V * (Math.random() - .5);
        var y = V * (Math.random() - .5);
        var z = V * (Math.random() - .5);
        var r = Math.sqrt(x ** 2 + y ** 2 + z ** 2) / 20
        x /= r
        y /= r
        z /= r

        cubes[i].position.x = x;
        cubes[i].position.y = y;
        cubes[i].position.z = z;
        scene.add(cubes[i]);
        animate()
    }

    return (
        <div key="0">
            <p key="1">{ animate() }</p>
        </div>
    )
}

export default ThreeComp2;

我认为您应该在 useEffect 挂钩中调用动画函数,而不是在渲染中返回它。 顺便提一句。使用可以使用 react-three-fiber 库将 React 与 ThreeJS 混合:https://github.com/pmndrs/react-three-fiber