es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Utilizar React Spring con Orbit Controls en React Three Fiber

Estoy tratando de usar Orbitcontrols en combinación con React Spring para animar mi cámara en React Three Fiber. Este es mi enfoque hasta ahora:

function Controls({ cameraData, duration }) {
  const [orbit, setOrbit] = useState(true);
  const [target, setTarget] = useState(cameraData.lookAt);
  const { gl, camera } = useThree();

  const springProps = useSpring({
    config: { duration: duration ? duration : 1000, easing: easings.easeCubic },
    from: {
      x: camera.position.x - 0.1,
      y: camera.position.y - 0.1,
      z: camera.position.z - 0.1,
      lookAtX: camera.lookAt.x - 0.1,
      lookAtY: camera.lookAt.y - 0.1,
      lookAtZ: camera.lookAt.z - 0.1,
    },
    to: {
      x: cameraData.position[0],
      y: cameraData.position[1],
      z: cameraData.position[2],
      lookAtX: cameraData.lookAt[0],
      lookAtY: cameraData.lookAt[1],
      lookAtZ: cameraData.lookAt[2],
    },
    onStart: (ya) => {
      setOrbit(false);
    },
    onRest: (ya) => {
      setOrbit(true);
      setTarget(cameraData.lookAt)
    },
  });

  useFrame((state, delta) => {
    if (!orbit) {
      camera.position.x = springProps.x.animation.values[0]._value;
      camera.position.y = springProps.y.animation.values[0]._value;
      camera.position.z = springProps.z.animation.values[0]._value;
      camera.lookAt(
        springProps.lookAtX.animation.values[0]._value,
        springProps.lookAtY.animation.values[0]._value,
        springProps.lookAtZ.animation.values[0]._value
      );
    }
  });

  return (
    <orbitcontrols enabled="{orbit}" target="{target}" args="{[camera," gl.domelement]}=""></orbitcontrols>
  );
}

Desactivo OrbitControls cuando comienza mi animación de Spring. Todo funciona. Pero: cuando uso OrbitControl, la posición de mi cámara cambia. Después de eso, cuando inicio mi animación de Spring, los valores ‘from’ no se actualizan.

Por ejemplo, hago una interpolación de x: 100 a x: 500. Luego roto mi cámara a través de OrbitControls a x: 700. Cuando inicio mi próxima animación de Spring, se anima comenzando desde x: 500 en lugar de x: 700.

¿Cómo puedo actualizar mis valores ‘from’?

Gracias.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para actualizar los valores from, puedes crear un estado separado para almacenar la posición inicial de la cámara y los valores de lookAt antes de utilizar los controles de órbita. Puedes actualizar este estado con la posición actual de la cámara y los valores de lookAt cada vez que se utilicen los controles de órbita. Luego, utiliza estos valores iniciales actualizados en tu animación de resorte en lugar de los valores iniciales estáticos.

    Aquí tienes un ejemplo de implementación:

    function Controls({ cameraData, duration }) {
      const [orbit, setOrbit] = useState(true);
      const [target, setTarget] = useState(cameraData.lookAt);
      const { gl, camera } = useThree();
      const [initialValues, setInitialValues] = useState({
        position: [camera.position.x, camera.position.y, camera.position.z],
        lookAt: [cameraData.lookAt[0], cameraData.lookAt[1], cameraData.lookAt[2]]
      });
    
      useEffect(() => {
        if (orbit) {
          // Actualiza los valores iniciales cuando se utilizan los controles de órbita
          setInitialValues({
            position: [camera.position.x, camera.position.y, camera.position.z],
            lookAt: [camera.position.x, camera.position.y, camera.position.z - 1]
          });
        }
      }, [orbit, camera.position]);
    
      const springProps = useSpring({
        config: { duration: duration ? duration : 1000, easing: easings.easeCubic },
        from: {
          x: initialValues.position[0],
          y: initialValues.position[1],
          z: initialValues.position[2],
          lookAtX: initialValues.lookAt[0],
          lookAtY: initialValues.lookAt[1],
          lookAtZ: initialValues.lookAt[2],
        },
        to: {
          x: cameraData.position[0],
          y: cameraData.position[1],
          z: cameraData.position[2],
          lookAtX: cameraData.lookAt[0],
          lookAtY: cameraData.lookAt[1],
          lookAtZ: cameraData.lookAt[2],
        },
        onStart: () => {
          setOrbit(false);
        },
        onRest: () => {
          setOrbit(true);
          setTarget(cameraData.lookAt);
        },
      });
    
      useFrame((state, delta) => {
        if (!orbit) {
          camera.position.x = springProps.x.animation.values[0]._value;
          camera.position.y = springProps.y.animation.values[0]._value;
          camera.position.z = springProps.z.animation.values[0]._value;
          camera.lookAt(
            springProps.lookAtX.animation.values[0]._value,
            springProps.lookAtY.animation.values[0]._value,
            springProps.lookAtZ.animation.values[0]._value
          );
        }
      });
    
      return (
        <orbitcontrols enabled="{orbit}" target="{target}" args="{[camera," gl.domelement]}=""></orbitcontrols>
      );
    }
    

    En esta implementación, el estado initialValues se actualiza cada vez que cambia la posición de la cámara debido a los controles de órbita. Estos valores iniciales actualizados se utilizan luego en la animación de resorte.

Comments are closed.