3D Interactive Learning Models
Model Controls
${info.description}
`; } // --- Model Creation Functions --- function createSolarSystem() { const group = new THREE.Group(); // Sun const sunGeo = new THREE.SphereGeometry(5, 32, 32); const sunMat = new THREE.MeshBasicMaterial({ color: 0xfdb813 }); const sun = new THREE.Mesh(sunGeo, sunMat); group.add(sun); // Planets const planetsData = [ { name: 'Mercury', size: 0.5, color: 0x9e9e9e, distance: 8 }, { name: 'Venus', size: 0.8, color: 0xffa500, distance: 12 }, { name: 'Earth', size: 1, color: 0x4d91ff, distance: 16 }, { name: 'Mars', size: 0.7, color: 0xff4500, distance: 20 }, ]; planetsData.forEach(p => { const planetGeo = new THREE.SphereGeometry(p.size, 16, 16); const planetMat = new THREE.MeshStandardMaterial({ color: p.color }); const planet = new THREE.Mesh(planetGeo, planetMat); const pivot = new THREE.Object3D(); pivot.add(planet); planet.position.x = p.distance; group.add(pivot); // Orbit path const orbitGeo = new THREE.TorusGeometry(p.distance, 0.05, 8, 100); const orbitMat = new THREE.MeshBasicMaterial({ color: 0xaaaaaa }); const orbit = new THREE.Mesh(orbitGeo, orbitMat); orbit.rotation.x = Math.PI / 2; group.add(orbit); pivot.userData.speed = 1 / p.distance; }); group.userData.animate = () => { group.children.forEach(child => { if (child.isObject3D && child.children.length > 0) { // is a pivot child.rotation.y += child.userData.speed * 0.1; } }); }; return group; } function createAtom() { const group = new THREE.Group(); // Nucleus const protonGeo = new THREE.SphereGeometry(0.5, 16, 16); const neutronGeo = new THREE.SphereGeometry(0.5, 16, 16); const protonMat = new THREE.MeshStandardMaterial({ color: 0xff0000 }); const neutronMat = new THREE.MeshStandardMaterial({ color: 0x0000ff }); for(let i=0; i<6; i++) { const proton = new THREE.Mesh(protonGeo, protonMat); proton.position.set(Math.random()-0.5, Math.random()-0.5, Math.random()-0.5).normalize().multiplyScalar(0.5); group.add(proton); const neutron = new THREE.Mesh(neutronGeo, neutronMat); neutron.position.set(Math.random()-0.5, Math.random()-0.5, Math.random()-0.5).normalize().multiplyScalar(0.5); group.add(neutron); } // Electrons and Orbits const electronGeo = new THREE.SphereGeometry(0.2, 16, 16); const electronMat = new THREE.MeshBasicMaterial({ color: 0xffff00 }); const shell1 = createElectronShell(2, 5, electronGeo, electronMat); const shell2 = createElectronShell(4, 10, electronGeo, electronMat); shell2.rotation.x = Math.PI / 3; shell2.rotation.y = Math.PI / 4; group.add(shell1, shell2); group.userData.animate = () => { shell1.rotation.z += 0.01; shell2.rotation.z -= 0.005; }; return group; } function createElectronShell(count, radius, geo, mat) { const shell = new THREE.Group(); for (let i = 0; i < count; i++) { const electron = new THREE.Mesh(geo, mat); const angle = (i / count) * Math.PI * 2; electron.position.set(Math.cos(angle) * radius, Math.sin(angle) * radius, 0); shell.add(electron); } // Orbit path const orbitGeo = new THREE.TorusGeometry(radius, 0.05, 8, 100); const orbitMat = new THREE.MeshBasicMaterial({ color: 0xaaaaaa, side: THREE.DoubleSide }); const orbit = new THREE.Mesh(orbitGeo, orbitMat); orbit.rotation.x = Math.PI / 2; shell.add(orbit); return shell; } function createHeart() { const group = new THREE.Group(); const box = new THREE.BoxGeometry(5, 6, 4); const ra = new THREE.Mesh(box, new THREE.MeshStandardMaterial({ color: 0x60a5fa })); // blue-400 ra.position.set(-2.5, 3, 0); const rv = new THREE.Mesh(box, new THREE.MeshStandardMaterial({ color: 0x2563eb })); // blue-600 rv.position.set(-2.5, -3, 0); const la = new THREE.Mesh(box, new THREE.MeshStandardMaterial({ color: 0xf87171 })); // red-400 la.position.set(2.5, 3, 0); const lv = new THREE.Mesh(box, new THREE.MeshStandardMaterial({ color: 0xdc2626 })); // red-600 lv.position.set(2.5, -3, 0); group.scale.set(0.8, 0.8, 0.8); group.add(ra, rv, la, lv); return group; } // --- PDF Generation --- function downloadPDF() { const modelName = document.getElementById('modelSelector').value; const info = modelInfo[modelName]; const { jsPDF } = window.jspdf; const doc = new jsPDF(); doc.setFont('helvetica', 'bold'); doc.setFontSize(18); doc.text(info.title, 14, 22); doc.setFont('helvetica', 'normal'); doc.setFontSize(12); const descriptionLines = doc.splitTextToSize(info.description, 180); doc.text(descriptionLines, 14, 32); doc.save(`${modelName}_Info.pdf`); } init();