Help to implement animation with gsap

I’ve tried all sorts of things, but nothing works.

I need to create an animation that smoothly transitions the camera’s focus to the platform’s target using GSAP here:

const SceneContent = ({ clouds, platforms, currentPlatformIndex, handlePlaneStop, handlePlaneAcceleration }) => {
const planeRef = useRef(); // linked to plane

useFrame(({ camera }) => {
if (currentPlatformIndex !== null) {
const target = platforms[currentPlatformIndex].cameraTarget;
camera.lookAt(new THREE.Vector3(…target)); //turn camera to platform target
} else if (planeRef.current) {
const forward = new THREE.Vector3(0, 0, -1);
forward.applyQuaternion(planeRef.current.quaternion); //apply plane orientation
camera.position.copy(planeRef.current.position).add(forward.clone().multiplyScalar(-10)); // camera forward the plane
camera.lookAt(planeRef.current.position.clone().add(forward.multiplyScalar(10)));
}
});

Full code of component

import React, { Suspense, useState, useRef } from “react”;
import { Canvas, useFrame } from “@react-three/fiber”;
import { useLocation } from “react-router-dom”;
import * as THREE from “three”;
import BackgroundModel from “./BackgroundModel”;
import Navbar from “…/navbar/NavbarDemo”;
import Cloud from “./Cloud”;
import FloatingIsland from “./FloatingIsland”;
import AnimatedFloatingIsland from “./AnimatedFloatingIsland”;
import ControlledPlane from “./ControlledPlane”;
import Board from “./Board”;
import GlowingPlatform from ‘./GlowingPlatform’;
import cloud1 from “…/…/assets/model/cloud1.glb”;
import cloud2 from “…/…/assets/model/cloud2.glb”;
import cloud3 from “…/…/assets/model/cloud3.glb”;
import cloud4 from “…/…/assets/model/cloud4.glb”;
import islandModel1 from “…/…/assets/model/island1.glb”;
import islandModel2 from “…/…/assets/model/island2.glb”;
import islandModel3 from “…/…/assets/model/island3.glb”;
import islandModel4 from “…/…/assets/model/island4.glb”;
import islandModel5 from “…/…/assets/model/island5.glb”;
import islandModel7 from “…/…/assets/model/island7.glb”;
import boardModel from “…/…/assets/model/board.glb”;
import img1 from ‘…/…/assets/img/screen1.jpg’;
import img2 from ‘…/…/assets/img/aboutMe.jpg’;

const Demo = ({ handleOnclick }) => {
const location = useLocation();

const platforms = [
{ position: [-3.5, 0, -7.8], cameraTarget: [-4.6, -0.1, -9.8] }, // walking girl
{ position: [ 15.5, 1.4, -22.8], cameraTarget: [17, 1.9, -24] }, // dinosaur
{ position: [101, 1110, 110], cameraTarget: [0, 0, 0] }
];

const [currentPlatformIndex, setCurrentPlatformIndex] = useState(null);

const handlePlaneStop = (index) => {
setCurrentPlatformIndex(index);
};

const handlePlaneAcceleration = () => {
setCurrentPlatformIndex(null);
};

const [clouds] = useState([
{
modelPath: cloud1,
position: [0, -20, -20],
scale: [0.05, 0.05, 0.05],
materialProps: { color: new THREE.Color(“rgb(255, 192, 203)”) },
},
{
modelPath: cloud2,
position: [20, 0, -55],
scale: [3.5, 3.5, 3.5],
materialProps: { color: new THREE.Color(“rgb(255, 192, 203)”) },
},
{
modelPath: cloud3,
position: [-30, 0, -30],
scale: [8.5, 8.5, 8.5],
materialProps: { color: new THREE.Color(“rgb(255, 192, 203)”) },
},
{
modelPath: cloud4,
position: [20, -5, 30],
scale: [8.5, 8.5, 8.5],
materialProps: { color: new THREE.Color(“rgb(255, 192, 203)”) },
},
]);

return (
<>

<Canvas
style={{ height: “100vh” }}
shadows={{ type: THREE.PCFSoftShadowMap }}
camera={{ position: [0, 5, 20], fov: 50 }}
>




<directionalLight
position={[-250, 0, -100]}
intensity={1}
color={new THREE.Color(“rgb(255, 182, 193)”)}
castShadow={true} // Enable shadow casting
/>

</>
);
};

const SceneContent = ({ clouds, platforms, currentPlatformIndex, handlePlaneStop, handlePlaneAcceleration }) => {
const planeRef = useRef(); // linked to plane

useFrame(({ camera }) => {
if (currentPlatformIndex !== null) {
const target = platforms[currentPlatformIndex].cameraTarget;
camera.lookAt(new THREE.Vector3(…target)); //turn camera to platform target
} else if (planeRef.current) {
const forward = new THREE.Vector3(0, 0, -1);
forward.applyQuaternion(planeRef.current.quaternion); //apply plane orientation
camera.position.copy(planeRef.current.position).add(forward.clone().multiplyScalar(-10)); // camera forward the plane
camera.lookAt(planeRef.current.position.clone().add(forward.multiplyScalar(10)));
}
});

return (
<>

{clouds.map((cloud, index) => (

))}

  {platforms.map((platform, index) => (
    <GlowingPlatform
      key={index}
      position={platform.position}
      scale={[10, 10, 10]}
    />
  ))}

  {/* walking girl */}
  <AnimatedFloatingIsland
    modelPath={islandModel1}
    position={[-5, 0, -10]}
    scale={[1, 1, 1]}
    rotation={[0, Math.PI / 10, 0]}
  />
  <Board 
    modelPath={boardModel} 
    texturePath={img1}
    position={[-4.6, -0.1, -9.8]} 
    scale={[0.5, 0.5, 0.5]} 
    rotation={[0, Math.PI / 5, 0]} 
    url="https://example.com"
  />

  {/* sakura waterfall */}
  <FloatingIsland
    modelPath={islandModel2}
    position={[0, -3, -30]}
    scale={[0.006, 0.006, 0.006]}
    rotation={[0, Math.PI / 25, 0]}
  />

  {/* dinosaur */}
  <FloatingIsland
    modelPath={islandModel3}
    position={[20, 0, -26]}
    scale={[0.6, 0.6, 0.6]}
    rotation={[0, Math.PI / -3, 0]}
  />
  <Board 
    modelPath={boardModel} 
    texturePath={img2}
    position={[17, 1.4, -24]} 
    scale={[0.5, 0.5, 0.5]} 
    rotation={[0, Math.PI / -3, 0]} 
    url="https://example.com"
  />

  {/* nihon */}
  <FloatingIsland
    modelPath={islandModel4}
    position={[10, -2, 10]}
    scale={[0.6, 0.6, 0.6]}
    rotation={[0, Math.PI / -1.1, 0]}
  />

  {/* floating house island */}
  <FloatingIsland
    modelPath={islandModel5}
    position={[-20, 0, 1]}
    scale={[0.4, 0.4, 0.4]}
    rotation={[0, Math.PI / 2, 0]}
  />

  {/* greeting girl */}
  <AnimatedFloatingIsland
    modelPath={islandModel7}
    position={[15, 0, -5]}
    scale={[1, 1, 1]}
    rotation={[0, Math.PI / -2, 0]}
  />

  {/* Controlled Plane with additional logic */}
  <ControlledPlane
    scale={[0.3, 0.3, 0.3]}
    initialRotationX={Math.PI / 9}
    initialRotationY={Math.PI / 0.9}
    initialRotationZ={Math.PI / 20}
    onStop={(index) => handlePlaneStop(index)} // Triggered when plane stops on the platform
    onAccelerate={handlePlaneAcceleration} // Triggered when plane accelerates
    platforms={platforms}
  />
</>

);
};

export default Demo;

That should help you.

1 Like