From 3e989a11fd5a61be15b8f80f0b15565fffe393f3 Mon Sep 17 00:00:00 2001 From: divyap Date: Mon, 30 Mar 2026 23:41:56 +0530 Subject: [PATCH] feat: implement hover interaction in vanilla --- Week-1/Task-3/vanilla/index.html | 12 ++++++ Week-1/Task-3/vanilla/main.js | 59 ++++++++++++++++++++++++++++++ Week-1/Task-3/vanilla/package.json | 16 ++++++++ Week-1/Task-3/vanilla/style.css | 16 ++++++++ 4 files changed, 103 insertions(+) create mode 100644 Week-1/Task-3/vanilla/index.html create mode 100644 Week-1/Task-3/vanilla/main.js create mode 100644 Week-1/Task-3/vanilla/package.json create mode 100644 Week-1/Task-3/vanilla/style.css diff --git a/Week-1/Task-3/vanilla/index.html b/Week-1/Task-3/vanilla/index.html new file mode 100644 index 0000000..9ea9d7f --- /dev/null +++ b/Week-1/Task-3/vanilla/index.html @@ -0,0 +1,12 @@ + + + + + + Task 3 — Hover Interaction (Vanilla Three.js) + + + + + + diff --git a/Week-1/Task-3/vanilla/main.js b/Week-1/Task-3/vanilla/main.js new file mode 100644 index 0000000..6ca663f --- /dev/null +++ b/Week-1/Task-3/vanilla/main.js @@ -0,0 +1,59 @@ +import * as THREE from 'three' + +const scene = new THREE.Scene() +scene.background = new THREE.Color('#111111') + +const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000) +camera.position.z = 5 + +const renderer = new THREE.WebGLRenderer() +renderer.setSize(window.innerWidth, window.innerHeight) +document.body.appendChild(renderer.domElement) + +const geometry = new THREE.BoxGeometry(2, 2, 2) +const material = new THREE.MeshBasicMaterial({ color: 'orange' }) +const cube = new THREE.Mesh(geometry, material) +scene.add(cube) + +const raycaster = new THREE.Raycaster() +const mouse = new THREE.Vector2() +let isHovered = false + +window.addEventListener('mousemove', (e) => { + mouse.x = (e.clientX / window.innerWidth) * 2 - 1 + mouse.y = -(e.clientY / window.innerHeight) * 2 + 1 + + raycaster.setFromCamera(mouse, camera) + const hits = raycaster.intersectObject(cube) + + if (hits.length > 0) { + if (!isHovered) { + isHovered = true + cube.material.color.set('hotpink') + cube.scale.set(1.15, 1.15, 1.15) + document.body.style.cursor = 'pointer' + } + } else { + if (isHovered) { + isHovered = false + cube.material.color.set('orange') + cube.scale.set(1, 1, 1) + document.body.style.cursor = 'default' + } + } +}) + +window.addEventListener('resize', () => { + camera.aspect = window.innerWidth / window.innerHeight + camera.updateProjectionMatrix() + renderer.setSize(window.innerWidth, window.innerHeight) +}) + +function animate() { + requestAnimationFrame(animate) + cube.rotation.x += 0.01 + cube.rotation.y += 0.01 + renderer.render(scene, camera) +} + +animate() diff --git a/Week-1/Task-3/vanilla/package.json b/Week-1/Task-3/vanilla/package.json new file mode 100644 index 0000000..243f770 --- /dev/null +++ b/Week-1/Task-3/vanilla/package.json @@ -0,0 +1,16 @@ +{ + "name": "task-3-vanilla", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build" + }, + "devDependencies": { + "vite": "^5.0.0" + }, + "dependencies": { + "three": "^0.163.0" + } +} diff --git a/Week-1/Task-3/vanilla/style.css b/Week-1/Task-3/vanilla/style.css new file mode 100644 index 0000000..1ce9053 --- /dev/null +++ b/Week-1/Task-3/vanilla/style.css @@ -0,0 +1,16 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body, html { + width: 100%; + height: 100%; + overflow: hidden; + background: #111; +} + +canvas { + display: block; +}