diff --git a/Week-1/Task-3/r3f/index.html b/Week-1/Task-3/r3f/index.html
new file mode 100644
index 0000000..22e4ebb
--- /dev/null
+++ b/Week-1/Task-3/r3f/index.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+ Task 3 R3F - Cube Clone
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week-1/Task-3/r3f/package.json b/Week-1/Task-3/r3f/package.json
index 97b288b..5056248 100644
--- a/Week-1/Task-3/r3f/package.json
+++ b/Week-1/Task-3/r3f/package.json
@@ -2,11 +2,23 @@
"name": "week-1-task-3-r3f",
"private": true,
"version": "0.0.0",
+ "type": "module",
"packageManager": "yarn@1.22.22",
"scripts": {
- "dev": "echo 'Add your React Three Fiber dev script here'",
- "build": "echo 'Add your React Three Fiber build script here'",
- "lint": "echo 'Add your lint script here'",
+ "dev": "vite",
+ "build": "vite build",
+ "lint": "echo 'Lint not configured yet'",
+ "preview": "vite preview",
"clean": "rm -rf dist build .next"
+ },
+ "dependencies": {
+ "@react-three/fiber": "^9.5.0",
+ "react": "^19.2.4",
+ "react-dom": "^19.2.4",
+ "three": "^0.183.2"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-react": "^6.0.0",
+ "vite": "^8.0.3"
}
}
\ No newline at end of file
diff --git a/Week-1/Task-3/r3f/src/App.jsx b/Week-1/Task-3/r3f/src/App.jsx
new file mode 100644
index 0000000..44f01cc
--- /dev/null
+++ b/Week-1/Task-3/r3f/src/App.jsx
@@ -0,0 +1,16 @@
+import { Canvas } from '@react-three/fiber'
+import CubePair from './CubeDuplicate'
+import GroupedStructure from './Group'
+
+export default function App() {
+ return (
+
+ )
+}
diff --git a/Week-1/Task-3/r3f/src/CubeDuplicate.jsx b/Week-1/Task-3/r3f/src/CubeDuplicate.jsx
new file mode 100644
index 0000000..53bd2b8
--- /dev/null
+++ b/Week-1/Task-3/r3f/src/CubeDuplicate.jsx
@@ -0,0 +1,47 @@
+import { useFrame } from '@react-three/fiber'
+import { useEffect, useMemo, useRef } from 'react'
+import * as THREE from 'three'
+
+function CubePair() {
+ const leftCubeRef = useRef()
+ const rightCubeRef = useRef()
+
+ const sharedGeometry = useMemo(() => new THREE.BoxGeometry(1, 1, 1), [])
+ const sharedMaterial = useMemo(() => new THREE.MeshStandardMaterial({ color: '#5bc0eb' }), [])
+
+ useEffect(() => {
+ return () => {
+ sharedGeometry.dispose()
+ sharedMaterial.dispose()
+ }
+ }, [sharedGeometry, sharedMaterial])
+
+ useFrame((state) => {
+ const seconds = state.clock.elapsedTime
+
+ if (leftCubeRef.current) {
+ leftCubeRef.current.rotation.x = seconds
+ leftCubeRef.current.rotation.y = seconds
+ }
+
+ if (rightCubeRef.current) {
+ rightCubeRef.current.rotation.x = seconds
+ rightCubeRef.current.rotation.y = -seconds
+ }
+ })
+
+ return (
+ <>
+
+
+
+ >
+ )
+}
+
+export default CubePair
\ No newline at end of file
diff --git a/Week-1/Task-3/r3f/src/Group.jsx b/Week-1/Task-3/r3f/src/Group.jsx
new file mode 100644
index 0000000..4f87dea
--- /dev/null
+++ b/Week-1/Task-3/r3f/src/Group.jsx
@@ -0,0 +1,44 @@
+import { Canvas, useFrame } from '@react-three/fiber'
+import { useRef } from 'react'
+
+function GroupedStructure({ position = [0, 0, 0], direction = 1 }) {
+ const groupRef = useRef()
+
+ useFrame((state) => {
+ const seconds = state.clock.elapsedTime
+
+ if (!groupRef.current) return
+
+ groupRef.current.rotation.y = direction * seconds * 0.7
+ groupRef.current.rotation.x = Math.sin(seconds * 1.1) * 0.2
+ })
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default GroupedStructure
+
+// export default function GroupApp() {
+// return (
+//
+// )
+// }
diff --git a/Week-1/Task-3/r3f/src/index.css b/Week-1/Task-3/r3f/src/index.css
new file mode 100644
index 0000000..77c24e1
--- /dev/null
+++ b/Week-1/Task-3/r3f/src/index.css
@@ -0,0 +1,18 @@
+html,
+body,
+#root {
+ margin: 0;
+ width: 100%;
+ height: 100%;
+}
+
+body {
+ overflow: hidden;
+ background: #101418;
+}
+
+canvas {
+ display: block;
+ width: 100%;
+ height: 100%;
+}
\ No newline at end of file
diff --git a/Week-1/Task-3/r3f/src/main.jsx b/Week-1/Task-3/r3f/src/main.jsx
new file mode 100644
index 0000000..104325b
--- /dev/null
+++ b/Week-1/Task-3/r3f/src/main.jsx
@@ -0,0 +1,10 @@
+import { StrictMode } from 'react'
+import { createRoot } from 'react-dom/client'
+import App from './App.jsx'
+import './index.css'
+
+createRoot(document.getElementById('root')).render(
+
+
+ ,
+)
diff --git a/Week-1/Task-3/r3f/vite.config.js b/Week-1/Task-3/r3f/vite.config.js
new file mode 100644
index 0000000..9ffcc67
--- /dev/null
+++ b/Week-1/Task-3/r3f/vite.config.js
@@ -0,0 +1,6 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+
+export default defineConfig({
+ plugins: [react()],
+})