2

I want to tween my camera, from Position A to B. I did it a few times using react spring with a little workaround:

import { useSpring } from "react-spring/three";

const springProps = useSpring({
config: { duration: 1000, easing: easings.easeCubicInOut },
to: {
  position: props.position,
  lookAt: props.lookAt,
  offset: props.offset,
},
onRest: (ya) => {
  if (props.enableOrbit) {
    props.parentStateModifier({ enableOrbit: true });
  }
},
});

useFrame(({ clock, camera, mouse }) => {
  camera.position.x = springProps.position.payload[0].value;
  camera.position.y = springProps.position.payload[1].value;
  camera.position.z = springProps.position.payload[2].value;

  camera.lookAt(
    springProps.lookAt.payload[0].value,
    springProps.lookAt.payload[1].value,
    springProps.lookAt.payload[2].value
  );
  camera.updateProjectionMatrix();
});

This was'nt a very good approach, but it worked.

I am now using @react-spring/three and its not working anymore. "payload" is undefined now and I was able to get the coordinates by calling springProps.x.animation.values[0]._value

But values is empty when not animating. I'm sure there must be a better way to animate camera.

I love react spring for animating three meshes. I hope I can use it for my camera as well.

tinytree
  • 1,009
  • 2
  • 12
  • 28
  • Does this answer your question? [Tween camera target in three.js](https://stackoverflow.com/questions/44763104/tween-camera-target-in-three-js) The top answer to that question addresses your problem exactly. – M - Dec 01 '21 at 22:09
  • Didn't know about the lerp method. But as far as I understood the docs, lerp is only linear. No easing for example. Using spring you can for example add every d3-ease curve. – tinytree Dec 02 '21 at 07:45

1 Answers1

2

Ok, I managed to update my code so that my camera is animating again:

const { gl, camera } = useThree();

const springProps = useSpring({
  config: { duration: 1000, easing: easings.easeCubic },
  from: {
    x: - 0.1,
    y: - 0.1,
    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],
  }
});

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
    );
  }
});

Problem is, that if the from and to values are the same, values[0] will be undefined. So for example this will not work with my code:

from: {
  x: 0
  y: 0,
  z: 0,
},
to: {
  x: 0,
  y: 2,
  z: 4,
}

because x has the same value. I hope someone can provide a better way of animating cameras in r3f.

tinytree
  • 1,009
  • 2
  • 12
  • 28