From d3989465e4fc2bd6bb148b73fd0aaa4eb42a760d Mon Sep 17 00:00:00 2001 From: divyap Date: Sun, 12 Apr 2026 12:53:53 +0530 Subject: [PATCH] feat: implement multi-object selection behavior audit for week 3 task 4 in vanilla --- Week-3/Task-4/vanilla/index.html | 18 +++++-- Week-3/Task-4/vanilla/main.js | 83 +++++++++++++++++++------------- Week-3/Task-4/vanilla/style.css | 43 +++++++++++++++++ 3 files changed, 105 insertions(+), 39 deletions(-) create mode 100644 Week-3/Task-4/vanilla/style.css diff --git a/Week-3/Task-4/vanilla/index.html b/Week-3/Task-4/vanilla/index.html index 9f0b5a6..ae44819 100644 --- a/Week-3/Task-4/vanilla/index.html +++ b/Week-3/Task-4/vanilla/index.html @@ -2,13 +2,21 @@ - Task 4 — Click To Highlight / Select - + Task 4 — Selection Behavior Audit + -

Interaction Pattern- click on the object

+ +
+

Task 4 Audit

+

Click objects to select/deselect them.

+ +
+ \ No newline at end of file diff --git a/Week-3/Task-4/vanilla/main.js b/Week-3/Task-4/vanilla/main.js index 30c4b97..1e3fd08 100644 --- a/Week-3/Task-4/vanilla/main.js +++ b/Week-3/Task-4/vanilla/main.js @@ -5,66 +5,81 @@ const scene = new THREE.Scene(); scene.background = new THREE.Color("white"); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); -camera.position.z = 5; +camera.position.set(0, 3, 10); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); -const geometry = new THREE.TorusKnotGeometry(1, 0.4, 100, 16); -const material = new THREE.MeshStandardMaterial({ color: "#ccc", roughness: 0.5 }); -const mesh = new THREE.Mesh(geometry, material); -scene.add(mesh); - scene.add(new THREE.AmbientLight(0xffffff, 0.6)); -const pointLight = new THREE.PointLight(0xffffff, 1); -pointLight.position.set(5, 5, 5); -scene.add(pointLight); +const light = new THREE.DirectionalLight(0xffffff, 1); +light.position.set(5, 10, 5); +scene.add(light); + +const objects = []; +const geometries = [ + new THREE.BoxGeometry(2, 2, 2), + new THREE.SphereGeometry(1.2, 32, 32), + new THREE.TorusGeometry(1.2, 0.4, 16, 100) +]; +const positions = [-5, 0, 5]; +const colors = ["#ff4f4f", "#4f8cff", "#4fff8c"]; + +geometries.forEach((geo, i) => { + const mat = new THREE.MeshStandardMaterial({ + color: colors[i], + roughness: 0.4, + metalness: 0.3, + emissive: new THREE.Color(0x000000) + }); + const mesh = new THREE.Mesh(geo, mat); + mesh.position.set(positions[i], 0, 0); + scene.add(mesh); + objects.push(mesh); +}); + +let selectedObject = null; +const raycaster = new THREE.Raycaster(); +const mouse = new THREE.Vector2(); const controls = new OrbitControls(camera, renderer.domElement); controls.enableDamping = true; -const raycaster = new THREE.Raycaster(); -const mouse = new THREE.Vector2(); -let isSelected = false; - window.addEventListener("click", (event) => { mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; raycaster.setFromCamera(mouse, camera); - const intersects = raycaster.intersectObject(mesh); + const intersects = raycaster.intersectObjects(objects); + + if (selectedObject) { + selectedObject.scale.set(1, 1, 1); + selectedObject.material.emissive.setHex(0x000000); + } if (intersects.length > 0) { - isSelected = !isSelected; - updateAppearance(); + const clicked = intersects[0].object; + if (selectedObject === clicked) { + selectedObject = null; + } else { + selectedObject = clicked; + selectedObject.scale.set(1.25, 1.25, 1.25); + selectedObject.material.emissive.setHex(0x333333); + } + } else { + selectedObject = null; } }); -function updateAppearance() { - if (isSelected) { - mesh.scale.set(1.2, 1.2, 1.2); - mesh.material.color.set("#3498db"); - mesh.material.emissive.set("#1e3799"); - mesh.material.emissiveIntensity = 0.5; - } else { - mesh.scale.set(1, 1, 1); - mesh.material.color.set("#ccc"); - mesh.material.emissive.set("#000"); - mesh.material.emissiveIntensity = 0; - } -} - function animate() { requestAnimationFrame(animate); controls.update(); - mesh.rotation.y += 0.01; renderer.render(scene, camera); } animate(); window.addEventListener("resize", () => { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - renderer.setSize(window.innerWidth, window.innerHeight); + camera.aspect = window.innerWidth / window.innerHeight; + camera.updateProjectionMatrix(); + renderer.setSize(window.innerWidth, window.innerHeight); }); diff --git a/Week-3/Task-4/vanilla/style.css b/Week-3/Task-4/vanilla/style.css new file mode 100644 index 0000000..c1c35d9 --- /dev/null +++ b/Week-3/Task-4/vanilla/style.css @@ -0,0 +1,43 @@ +body { + margin: 0; + overflow: hidden; + font-family: 'Inter', system-ui, -apple-system, sans-serif; +} + +#instructions { + position: absolute; + top: 20px; + left: 20px; + background: rgba(255, 255, 255, 0.85); + backdrop-filter: blur(12px); + padding: 24px; + border-radius: 16px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08); + border: 1px solid rgba(255, 255, 255, 0.3); + max-width: 300px; + z-index: 100; +} + +h2 { + margin: 0 0 12px 0; + font-size: 1.25rem; + color: #1a1a1a; +} + +p { + margin: 0 0 12px 0; + font-size: 0.95rem; + color: #4a4a4a; + line-height: 1.5; +} + +ul { + margin: 0; + padding-left: 20px; + color: #666; + font-size: 0.85rem; +} + +li { + margin-bottom: 6px; +}