diff --git a/Week-2/Task-3/r3f/src/App.jsx b/Week-2/Task-3/r3f/src/App.jsx
index 625ff5b..4ad0299 100644
--- a/Week-2/Task-3/r3f/src/App.jsx
+++ b/Week-2/Task-3/r3f/src/App.jsx
@@ -1,6 +1,177 @@
-export default function App() {
+import { useEffect, useMemo, useRef, useState } from 'react'
+import { Canvas, useFrame, useThree } from '@react-three/fiber'
+import * as THREE from 'three'
+
+const STEPS = [
+ {
+ label: 'Step 1: Focus on object A',
+ detail: 'Camera frames object A only.',
+ cameraPosition: [0, 1.4, 5],
+ lookAt: [-1.2, 0, 0],
+ a: { position: [-1.2, 0, 0], rotation: [0, 0.25, 0], visible: true },
+ b: { position: [1.4, 0, 0], rotation: [0, 0, 0], visible: false },
+ },
+ {
+ label: 'Step 2: Move camera + reveal object B',
+ detail: 'Camera shifts right and object B becomes visible.',
+ cameraPosition: [2.2, 1.4, 5],
+ lookAt: [1.4, 0, 0],
+ a: { position: [-1.2, 0, 0], rotation: [0.2, 0.8, 0], visible: true },
+ b: { position: [1.4, 0, 0], rotation: [0, 0.2, 0], visible: true },
+ },
+ {
+ label: 'Step 3: Final combined scene',
+ detail: 'Both objects stay visible in one balanced view.',
+ cameraPosition: [0.3, 2.2, 7],
+ lookAt: [0, 0, 0],
+ a: { position: [-1.5, 0, 0], rotation: [0.3, 1.1, 0], visible: true },
+ b: { position: [1.5, 0, 0], rotation: [0.1, 0.6, 0], visible: true },
+ },
+]
+
+function GuidedScene({ stepIndex }) {
+ const { camera } = useThree()
+ const objectARef = useRef()
+ const objectBRef = useRef()
+ const initializedRef = useRef(false)
+
+ const targets = useMemo(
+ () => ({
+ cameraPosition: new THREE.Vector3(),
+ cameraLookAt: new THREE.Vector3(),
+ lookCurrent: new THREE.Vector3(),
+ aPosition: new THREE.Vector3(),
+ aRotation: new THREE.Euler(),
+ bPosition: new THREE.Vector3(),
+ bRotation: new THREE.Euler(),
+ }),
+ []
+ )
+
+ useEffect(() => {
+ const step = STEPS[stepIndex]
+
+ targets.cameraPosition.set(...step.cameraPosition)
+ targets.cameraLookAt.set(...step.lookAt)
+
+ targets.aPosition.set(...step.a.position)
+ targets.aRotation.set(...step.a.rotation)
+
+ targets.bPosition.set(...step.b.position)
+ targets.bRotation.set(...step.b.rotation)
+
+ if (objectARef.current) objectARef.current.visible = step.a.visible
+ if (objectBRef.current) objectBRef.current.visible = step.b.visible
+
+ if (!initializedRef.current && objectARef.current && objectBRef.current) {
+ camera.position.copy(targets.cameraPosition)
+ targets.lookCurrent.copy(targets.cameraLookAt)
+ objectARef.current.position.copy(targets.aPosition)
+ objectARef.current.rotation.copy(targets.aRotation)
+ objectBRef.current.position.copy(targets.bPosition)
+ objectBRef.current.rotation.copy(targets.bRotation)
+ initializedRef.current = true
+ }
+ }, [camera, stepIndex, targets])
+
+ useFrame(() => {
+ if (!objectARef.current || !objectBRef.current) return
+
+ objectARef.current.position.lerp(targets.aPosition, 0.1)
+ objectBRef.current.position.lerp(targets.bPosition, 0.1)
+
+ objectARef.current.rotation.x += (targets.aRotation.x - objectARef.current.rotation.x) * 0.1
+ objectARef.current.rotation.y += (targets.aRotation.y - objectARef.current.rotation.y) * 0.1
+ objectARef.current.rotation.z += (targets.aRotation.z - objectARef.current.rotation.z) * 0.1
+
+ objectBRef.current.rotation.x += (targets.bRotation.x - objectBRef.current.rotation.x) * 0.1
+ objectBRef.current.rotation.y += (targets.bRotation.y - objectBRef.current.rotation.y) * 0.1
+ objectBRef.current.rotation.z += (targets.bRotation.z - objectBRef.current.rotation.z) * 0.1
+
+ camera.position.lerp(targets.cameraPosition, 0.08)
+ targets.lookCurrent.lerp(targets.cameraLookAt, 0.08)
+ camera.lookAt(targets.lookCurrent)
+ })
+
return (
- <>>
+ <>
+
{step.label}
+{step.detail}
+ +Use buttons or keys 1, 2, 3.
+