Reputation: 91
I know this is a trivial question but I assure you I've been trying to solve this for several hours.
The color prop is a string (e.g '#f56d3d'
) and it should change the mesh material color. I'm using useEffect
to initialize the scene and I've tried to use another to change the color
function Scene({ color, shape }) {
const cubeRef = useRef(null);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer({ alpha: true });
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color });
const cube = new THREE.Mesh(geometry, material);
const animate = () => {
requestAnimationFrame(animate);
cube.material.color.setStyle(color);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
};
useEffect(() => {
renderer.setSize(window.innerWidth, window.innerHeight);
cubeRef.current.appendChild(renderer.domElement);
scene.add(cube);
camera.position.z = 5;
animate();
},[]);
return (
<div ref={cubeRef}>
</div>
)
}
export default Scene
What comes to my mind is a way to let know the renderer that the cube inside the scene has changed. What I've tried so far is:
cube.material.needsUpdate = true;
renderer.render(scene, camera);
cube.material = new THREE.MeshBasicMaterial({ color });
All of these inside a useEffect
with `color as dep.Thanks
Upvotes: 1
Views: 3036
Reputation: 241
If you dont mind creating a new object then you can rearrange the variables in the useEffect like this:
const cubeRef = useRef(null);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer({ alpha: true });
const geometry = new THREE.BoxGeometry();
let cube, material;
const animate = () => {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
};
useEffect(() => {
material = new THREE.MeshBasicMaterial({color});
cube = new THREE.Mesh(geometry, material);
renderer.setSize(window.innerWidth, window.innerHeight);
cubeRef.current.innerHTML = '';
cubeRef.current.appendChild(renderer.domElement);
scene.add(cube);
camera.position.z = 5;
animate();
}, [color])
Also you might need to save the previous positioning or rotation somewhere.
Upvotes: 1