0

My functional React component is using three.js (below), is it proper to use :

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

to bind three.js to functional React component ? All are see are class based examples of use of three.js with React. I also wonder about usage of animate() keyword itself. It seems that I have run it in body and return part od the component.

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;

1 Answer 1

1

I think you should call the animate function inside the useEffect hook instead of returning it inside of the render. Btw. use can use the react-three-fiber library for mixing React with ThreeJS: https://github.com/pmndrs/react-three-fiber

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.