React Three Fiber camera transition

I spent the whole day really finding why my camera transitions are not working, I am all ears to here you nice solutions here is the code “The Animation is in the intro function”:

import React, { Suspense, useEffect, useRef, useState } from ‘react’;
import * as swipeAnimation from ‘./Swipe.json’;
import { Canvas, useFrame } from ‘@react-three/fiber’;
import { easeCubic } from ‘d3-ease’;
import {
Reflector,
useTexture,
PerspectiveCamera,
Text
} from ‘@react-three/drei’;
import { IntroDef } from “…/…/Avatars/IntroDef”;
import * as THREE from ‘three’;
import Lottie from “lottie-react”;

const cameraPositions = [
[0, 3, 100],
[20, 10, 80],
[-20, 5, 75],
[10, 12, 90]
];

const timings = [5000, 3000, 4000, 6000];

export default function IntroAvatar() {
const defaultOptions = {
loop: true,
autoplay: true,
animationData: swipeAnimation.default,
};

const characterRef = useRef();
const cameraRef = useRef(); // Declare a camera reference
const [cameraPosition, setCameraPosition] = useState({ x: 0, y: 3, z: 100 });
const [currentPosition, setCurrentPosition] = useState(0);

const handleTransition = () => {
    let nextPosition = (currentPosition + 1);
    setCurrentPosition(nextPosition);
    setCameraPosition({x: cameraPositions[nextPosition][0],y: cameraPositions[nextPosition][1],z: cameraPositions[nextPosition][2]});

};

useEffect(() => {
    if(currentPosition<timings.length) {
        const interval = setTimeout(handleTransition, timings[currentPosition]);
        console.log(currentPosition);
        return () => clearTimeout(interval);
    }
}, [currentPosition]);


return (
    <div className={'intro-avatar-3d'}>
        <div className="swipe-animation">
            <Lottie options={defaultOptions} animationData={swipeAnimation.default} />
        </div>
        <Canvas concurrent gl={{ alpha: true }} pixelRatio={[1, 1.5]}>
            <perspectiveCamera ref={cameraRef} position={cameraPosition} fov={15} />
            <color attach="background" args={['black']} />
            <fog attach="fog" args={['black', 15, 20]} />
            <Suspense fallback={null}>
                <group position={[0, -1, 0]}>
                    <IntroDef characterRef={characterRef} rotation={[0, 0, 0]} scale={[1, 1, 1]} />
                    <VideoText character={characterRef} position={[0, 1.3, -1]} />
                    <Ground />
                </group>
                <Intro cameraRef={cameraRef} targetPosition={cameraPosition} />
            </Suspense>
        </Canvas>
    </div>
);

}

function Ground() {
const [floor, normal] = useTexture([‘/textures/reflect/wooden_diff.jpg’, ‘/textures/reflect/wooden_nordxl.jpg’]);
return (
<Reflector blur={[400, 100]} resolution={1024} args={[10, 10]} mirror={0.5} mixBlur={6} mixStrength={1.5} rotation={[-Math.PI / 2, 0, Math.PI / 2]}>
{(Material, props) => <Material color=“#a0a0a0” metalness={0.4} normalScale={[2, 2]} {…props} />}

);
}

function VideoText(props) {
const textRef = useRef();
const [distance, setDistance] = useState(100);
const [spacing, setSpacing] = useState(1);

function lerp(a, b, t) {
    return a + t * (b - a);
}

useFrame(() => {
    const characterPosition = props.character.current.position;
    const newDistance = characterPosition.distanceTo(textRef.current.position);

    const targetSpacing = newDistance < 2 ? 10 : 1;
    const t = easeCubic(0.3);
    const newSpacing = lerp(spacing, targetSpacing, t);

    setSpacing(newSpacing);
    setDistance(newDistance);
});

const renderedText = `WELCOME TO${' '.repeat(Math.round(spacing))}MY PORTFOLIO!`;

return (
    <Text ref={textRef} font="/intro.ttf" fontSize={0.7} color={'#0e758f'} letterSpacing={0.1} {...props}>
        {renderedText}
        <meshBasicMaterial toneMapped={false} />
    </Text>
);

}

function Intro(props) {
const { cameraRef, targetPosition } = props;

return useFrame(() => {
    if (cameraRef.current) {

        cameraRef.current.position.lerp(new THREE.Vector3(targetPosition.x, targetPosition.y, targetPosition.z), 0.05);
        cameraRef.current.lookAt(0, 0, 0);
        cameraRef.current.updateProjectionMatrix();

    }
});

}

it’s too much unrelated code. i would isolate the issue with just the camera move. don’t even need to setTimeout stuff for that, just make sure you get the lerping right.

btw, i have been using GitHub - yomotsu/camera-controls: A camera control for three.js, similar to THREE.OrbitControls yet supports smooth transitions and more features. recently to move the camera, it made it really easy. it has a drei helper as well. for instance
Enter portals - CodeSandbox