Move camera as time passes

Hi there,

For my project I want to make a nice beginning after loading by zooming in on my GLTF object. However I have no idea how to make that. I already tried some things but have the feeling that I’m not going to figure it out by myself so what I have is this:

function MoveCamera(props) {

  useFrame((state) => {
    state.camera.zoom += 0.001
    
  })
  return null
}

let App = () => {
  
  return (
    <Canvas>
      <PerspectiveCamera makeDefault position={[0, 1.2, 12]} fov={30} zoom={0.5} />
      <Suspense fallback={null}>
        <spotLight position={[0, 15, 0]} angle={0.3} penumbra={1} castShadow intensity={2} shadow-bias={-0.0001} />
        <ambientLight intensity={0.2} />

        <Car scale={1} position={[0, 0, 0]} rotation={[0, Math.PI / 5, 0]}/>
        
        <OrbitControls enablePan enableZoom enableRotate maxPolarAngle={Math.PI / 2.1} /> 
      </Suspense>
      
      <MoveCamera />
    </Canvas>
  );
}


export default App;

So I thought I zoom in a bit each frame but nothing is happening. I think its something with rerendering but couldn’t find anything about that so I hope someone can help me.

Some clarification:
from:


to:

you’re missing state.camera.updateProjectionMatrix() and <MoveCamera> should be inside the suspense bound, which means it would start zooming once the model has loaded, not before. currently it starts when the app loads.

demo: gltf simple example - CodeSandbox

ps in react 18 you dont have to return null any longer, you dont need to return anything.

1 Like

one more thing, if later on you decide to move the camera, not just zoom, keep in mind that you have orbitcontrols in your scene which mutate the camera every frame, it will cancel your own calculations out or create a race condition. the solution is to give orbitcontrols makeDefault and now controls are accessible as state.controls, so you can call state.controls.update() in your useFrame after you’ve written into the camera.

2 Likes