+
SIH Cam
Another project related to the Smart India Hackathon.
@@ -331,12 +357,13 @@
SIH Cam
@@ -728,10 +755,176 @@
Let's work together
});
}
+ // --- 3D Thumbnail Data Storage ---
+ const thumbnailDataMap = new Map();
+
+ // --- 3D Thumbnail Generator for Project/Demo Cards ---
+ function createThumb3D(container, shapeType, accentColor) {
+ if (!container) return null;
+
+ const width = container.clientWidth;
+ const height = container.clientHeight;
+
+ // Scene
+ const scene = new THREE.Scene();
+
+ // Camera - adjusted FOV for better fit
+ const camera = new THREE.PerspectiveCamera(50, width / height, 0.1, 1000);
+ camera.position.z = 4;
+
+ // Renderer
+ const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
+ renderer.setSize(width, height);
+ renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
+ container.appendChild(renderer.domElement);
+
+ // Colors - Metallic palette with neon accents
+ const accentHex = accentColor === 'pink' ? 0xec4899 : 0x3b82f6;
+ const metallicColor = 0x9ca3af; // Silver/gray
+
+ // Geometry creation based on shape type
+ let geometry;
+ const scale = 1.2; // Base scale for all objects
+
+ switch(shapeType) {
+ case 'trophy':
+ geometry = new THREE.ConeGeometry(0.8 * scale, 1.4 * scale, 6);
+ break;
+ case 'torus':
+ geometry = new THREE.TorusGeometry(0.7 * scale, 0.25 * scale, 16, 50);
+ break;
+ case 'robot':
+ geometry = new THREE.BoxGeometry(1 * scale, 1.2 * scale, 0.8 * scale);
+ break;
+ case 'octahedron':
+ geometry = new THREE.OctahedronGeometry(0.9 * scale, 0);
+ break;
+ case 'dodecahedron':
+ geometry = new THREE.DodecahedronGeometry(0.85 * scale, 0);
+ break;
+ case 'icosahedron':
+ geometry = new THREE.IcosahedronGeometry(0.9 * scale, 0);
+ break;
+ case 'torusKnot':
+ geometry = new THREE.TorusKnotGeometry(0.5 * scale, 0.18 * scale, 80, 12);
+ break;
+ case 'gear':
+ geometry = new THREE.CylinderGeometry(0.8 * scale, 0.8 * scale, 0.3 * scale, 12);
+ break;
+ default:
+ geometry = new THREE.IcosahedronGeometry(0.9 * scale, 0);
+ }
+
+ // Metallic material for the main object
+ const mainMaterial = new THREE.MeshStandardMaterial({
+ color: metallicColor,
+ metalness: 0.7,
+ roughness: 0.2
+ });
+ const mainMesh = new THREE.Mesh(geometry, mainMaterial);
+ mainMesh.position.set(0, 0, 0);
+ scene.add(mainMesh);
+
+ // Wireframe overlay with accent color
+ const wireframeMaterial = new THREE.MeshBasicMaterial({
+ color: accentHex,
+ wireframe: true,
+ transparent: true,
+ opacity: 0.4
+ });
+ const wireframeMesh = new THREE.Mesh(geometry, wireframeMaterial);
+ wireframeMesh.position.set(0, 0, 0);
+ scene.add(wireframeMesh);
+
+ // Lighting setup
+ const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
+ scene.add(ambientLight);
+
+ const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
+ directionalLight.position.set(2, 3, 4);
+ scene.add(directionalLight);
+
+ // Colored rim light for glow effect
+ const rimLight = new THREE.PointLight(accentHex, 0.6, 10);
+ rimLight.position.set(-2, 1, 2);
+ scene.add(rimLight);
+
+ // Second accent light
+ const secondLight = new THREE.PointLight(accentColor === 'pink' ? 0x3b82f6 : 0xec4899, 0.3, 8);
+ secondLight.position.set(2, -1, 1);
+ scene.add(secondLight);
+
+ // Animation with cleanup capability
+ let animationId = null;
+ let isAnimating = true;
+
+ function animate() {
+ if (!isAnimating) return;
+ animationId = requestAnimationFrame(animate);
+ mainMesh.rotation.x += 0.005;
+ mainMesh.rotation.y += 0.008;
+ wireframeMesh.rotation.x += 0.005;
+ wireframeMesh.rotation.y += 0.008;
+ renderer.render(scene, camera);
+ }
+ animate();
+
+ // Cleanup function to stop animation and dispose resources
+ function cleanup() {
+ isAnimating = false;
+ if (animationId !== null) {
+ cancelAnimationFrame(animationId);
+ }
+ geometry.dispose();
+ mainMaterial.dispose();
+ wireframeMaterial.dispose();
+ renderer.dispose();
+ thumbnailDataMap.delete(container);
+ }
+
+ // Store reference in Map for resize handling
+ const thumbData = { camera, renderer, scene, mainMesh, wireframeMesh, cleanup };
+ thumbnailDataMap.set(container, thumbData);
+
+ return thumbData;
+ }
+
+ // --- Initialize all 3D Thumbnails ---
+ function initThumbnails() {
+ const thumbContainers = document.querySelectorAll('.threejs-thumb');
+ thumbContainers.forEach(container => {
+ const shape = container.dataset.shape || 'icosahedron';
+ const accent = container.dataset.accent || 'blue';
+ createThumb3D(container, shape, accent);
+ });
+
+ // Debounced resize handler for performance
+ let resizeTimeout;
+ function handleResize() {
+ thumbContainers.forEach(container => {
+ const thumbData = thumbnailDataMap.get(container);
+ if (thumbData) {
+ const { camera, renderer } = thumbData;
+ const width = container.clientWidth;
+ const height = container.clientHeight;
+ camera.aspect = width / height;
+ camera.updateProjectionMatrix();
+ renderer.setSize(width, height);
+ }
+ });
+ }
+
+ window.addEventListener('resize', () => {
+ clearTimeout(resizeTimeout);
+ resizeTimeout = setTimeout(handleResize, 150);
+ });
+ }
+
// Start everything
initAboutCanvas(); // Initialize the new canvas
initTypingAnimation(); // Start the typing effect
initMobileMenu(); // Initialize the mobile menu
+ initThumbnails(); // Initialize 3D thumbnails
});