Search code examples
javascriptreactjsthree.jsreact-springreact-three-fiber

Unable to animate THREE.js property using React Spring


I would like to have React Spring animate a property of a material in Three.js.

However, I'm getting an error when I try to do so:

THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.

Here is my code, I am trying to animate props.theta from 6.3 to 1.3:

import React, { useRef, useState, useEffect } from 'react';
import { useFrame } from 'react-three-fiber';
import { useSpring, a } from 'react-spring/three';

function RingBuffer() {
  const ringBuffer = useRef();

  const props = useSpring({
    to: async (next, cancel) => {
      await next({ theta: 1.3 });
    },
    from: { theta: 6.3 },
  });

  useFrame(() => {
    ringBuffer.current.rotation.z += 0.03;
  });

  return (
    <a.mesh ref={ringBuffer}>
      <a.ringBufferGeometry attach="geometry" args={[1, 2, 30, 30, 0, props.theta]} />
      <meshLambertMaterial attach="material" wireframe={true} color={'#4FFF9C'} />
    </a.mesh>
  );
}

I am using react-three-fiber which is a react reconciler for Three.js.


Solution

  • args is for constructor arguments. if you change an arg, the object will re-instanciate, as in: <foo args={[123]} /> is the same as new Foo(123). animating something that constructs 60fps is a no go, and it's also not possible with react-spring. in praxis you should find means to mutate things as fast as possible, if you can get away with it animate scale, or make a ring shader whose uniforms you animate.