diff --git a/Week-2/Task-2/vanilla/index.html b/Week-2/Task-2/vanilla/index.html
index f168821..ac81e38 100644
--- a/Week-2/Task-2/vanilla/index.html
+++ b/Week-2/Task-2/vanilla/index.html
@@ -8,10 +8,11 @@
html,
body {
margin: 0;
- background: white;
+ background: #f3f5f8;
width: 100%;
height: 100%;
overflow: hidden;
+ font-family: "Avenir Next", "Segoe UI", sans-serif;
}
canvas {
@@ -19,10 +20,78 @@
width: 100%;
height: 100%;
}
+
+ #state-panel {
+ position: fixed;
+ top: 16px;
+ left: 16px;
+ z-index: 10;
+ background: rgba(255, 255, 255, 0.82);
+ border: 1px solid rgba(0, 0, 0, 0.12);
+ border-radius: 12px;
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
+ padding: 12px;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ backdrop-filter: blur(6px);
+ }
+
+ #state-panel h2 {
+ margin: 0;
+ font-size: 14px;
+ letter-spacing: 0.03em;
+ color: #1b2530;
+ font-weight: 700;
+ }
+
+ .state-buttons {
+ display: flex;
+ gap: 8px;
+ flex-wrap: wrap;
+ }
+
+ .state-btn {
+ border: 1px solid #cfd8e3;
+ background: #ffffff;
+ color: #203448;
+ border-radius: 8px;
+ padding: 8px 10px;
+ font-size: 13px;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ }
+
+ .state-btn:hover {
+ border-color: #8ea2b8;
+ transform: translateY(-1px);
+ }
+
+ .state-btn.active {
+ background: #203448;
+ border-color: #203448;
+ color: #f4f8fb;
+ }
+
+ #hint {
+ margin: 0;
+ font-size: 12px;
+ color: #4f647a;
+ }
-
+
+
+
Scene States
+
+
+
+
+
+
Press 1, 2, or 3 to switch state.
+
+
\ No newline at end of file
diff --git a/Week-2/Task-2/vanilla/main.js b/Week-2/Task-2/vanilla/main.js
index e69de29..5634170 100644
--- a/Week-2/Task-2/vanilla/main.js
+++ b/Week-2/Task-2/vanilla/main.js
@@ -0,0 +1,130 @@
+import * as THREE from 'three'
+
+const scene = new THREE.Scene()
+scene.background = new THREE.Color(0xf3f5f8)
+
+const camera = new THREE.PerspectiveCamera(
+ 55,
+ window.innerWidth / window.innerHeight,
+ 0.1,
+ 100
+)
+camera.position.set(0, 2, 7)
+camera.lookAt(0, 0, 0)
+
+const renderer = new THREE.WebGLRenderer({ antialias: true })
+renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
+renderer.setSize(window.innerWidth, window.innerHeight)
+document.body.appendChild(renderer.domElement)
+
+scene.add(new THREE.AmbientLight(0xffffff, 0.9))
+
+const keyLight = new THREE.DirectionalLight(0xffffff, 1)
+keyLight.position.set(3, 4, 5)
+scene.add(keyLight)
+
+const objects = {
+ center: new THREE.Mesh(
+ new THREE.BoxGeometry(1.2, 1.2, 1.2),
+ new THREE.MeshStandardMaterial({ color: 0x2a9d8f })
+ ),
+ left: new THREE.Mesh(
+ new THREE.BoxGeometry(0.9, 0.9, 0.9),
+ new THREE.MeshStandardMaterial({ color: 0xe76f51 })
+ ),
+ right: new THREE.Mesh(
+ new THREE.BoxGeometry(0.9, 0.9, 0.9),
+ new THREE.MeshStandardMaterial({ color: 0x457b9d })
+ ),
+}
+
+scene.add(objects.center, objects.left, objects.right)
+
+const states = {
+ state1: {
+ center: { position: [0, 0, 0], rotation: [0, 0, 0], visible: true },
+ left: { position: [0, 0, 0], rotation: [0, 0, 0], visible: false },
+ right: { position: [0, 0, 0], rotation: [0, 0, 0], visible: false },
+ },
+ state2: {
+ center: { position: [0, 0, 0], rotation: [0.25, 0.4, 0], visible: true },
+ left: { position: [-2.1, 0, 0.2], rotation: [0, 0.2, 0], visible: true },
+ right: { position: [2.1, 0, -0.2], rotation: [0, -0.2, 0], visible: true },
+ },
+ state3: {
+ center: { position: [0, 1.3, 0], rotation: [0.6, 0.9, 0], visible: true },
+ left: { position: [-1.2, -1, 1.2], rotation: [0.3, 0.3, 0.1], visible: true },
+ right: { position: [0, 0, 0], rotation: [0, 0, 0], visible: false },
+ },
+}
+
+const targets = {
+ center: { position: new THREE.Vector3(), rotation: new THREE.Euler() },
+ left: { position: new THREE.Vector3(), rotation: new THREE.Euler() },
+ right: { position: new THREE.Vector3(), rotation: new THREE.Euler() },
+}
+
+const buttons = Array.from(document.querySelectorAll('.state-btn'))
+let activeState = 'state1'
+
+function updateButtonState(stateName) {
+ buttons.forEach((button) => {
+ button.classList.toggle('active', button.dataset.state === stateName)
+ })
+}
+
+function applyState(stateName) {
+ const nextState = states[stateName]
+ if (!nextState) {
+ return
+ }
+
+ activeState = stateName
+
+ Object.keys(objects).forEach((name) => {
+ const object = objects[name]
+ const config = nextState[name]
+
+ targets[name].position.set(...config.position)
+ targets[name].rotation.set(...config.rotation)
+ object.visible = config.visible
+ })
+
+ updateButtonState(stateName)
+}
+
+buttons.forEach((button) => {
+ button.addEventListener('click', () => {
+ applyState(button.dataset.state)
+ })
+})
+
+window.addEventListener('keydown', (event) => {
+ if (event.key === '1') applyState('state1')
+ if (event.key === '2') applyState('state2')
+ if (event.key === '3') applyState('state3')
+})
+
+applyState(activeState)
+
+function animate() {
+ Object.keys(objects).forEach((name) => {
+ const object = objects[name]
+ const target = targets[name]
+
+ object.position.lerp(target.position, 0.1)
+ object.rotation.x += (target.rotation.x - object.rotation.x) * 0.1
+ object.rotation.y += (target.rotation.y - object.rotation.y) * 0.1
+ object.rotation.z += (target.rotation.z - object.rotation.z) * 0.1
+ })
+
+ renderer.render(scene, camera)
+}
+
+renderer.setAnimationLoop(animate)
+
+window.addEventListener('resize', () => {
+ camera.aspect = window.innerWidth / window.innerHeight
+ camera.updateProjectionMatrix()
+ renderer.setSize(window.innerWidth, window.innerHeight)
+})