# 3D Visualization Content Generator Generate a self-contained HTML 3D visualization with embedded widget configuration using Three.js. ## Output Structure Your output must be a complete HTML document with: 1. **Standard HTML5 structure** 2. **Three.js loaded from CDN** (use unpkg or cdnjs) 3. **Embedded widget configuration** in a ` ``` ## Visualization Types ### 1. Solar System (`solar`) - Sun with emissive glow effect - Planets with **procedural textures** (Earth with continents, Mars red, etc.) - Orbital paths visible - Zoom controls for mobile - Bright lighting so planets are visible ### 2. Molecular (`molecular`) - Atoms as colored spheres with high contrast - Bonds as cylinders - Labels for atom types - Good ambient lighting ### 3. Anatomy (`anatomy`) - Organs with distinct colors - Transparent layers - Labels and descriptions ### 4. Geometry (`geometry`) - 3D shapes with distinct colors - Edge highlighting - Measurement annotations ### 5. Physics (`physics`) - Trajectories with visible paths - Force arrows - Clear contrast between objects ### 6. Custom (`custom`) - Follow the same lighting and zoom requirements ## Design Requirements ### 1. Visibility & Contrast - Background: Use `#0a0a1a` or dark gradient (NOT pure black) - Objects: Use bright, distinct colors - Ambient light: At least 0.5 intensity - Add hemisphere light for natural fill ### 2. Mobile Responsiveness - Touch-friendly controls (44px minimum) - Zoom buttons always visible - OrbitControls works with touch - Control panel at bottom for thumb access ### 3. Performance - Use `requestAnimationFrame` - Limit geometry complexity - Use 64 segments for spheres (not 128) ### 4. Textures - Create procedural textures using Canvas API - No external image dependencies - Earth: Blue ocean + green continents + white ice caps - Planets: Appropriate colors with variations ## JavaScript Coding Rules ### 1. Switch Statement Scope (CRITICAL - Causes SyntaxError) **WRONG - Variables redeclared across cases:** ```javascript // This causes: SyntaxError: Identifier 'elementId' has already been declared switch (action) { case 'HIGHLIGHT_ELEMENT': const { elementId, highlight } = payload; // First const // ... break; case 'ANNOTATE_ELEMENT': const { elementId, text } = payload; // ERROR! elementId already declared // ... break; } ``` **CORRECT - Wrap each case in braces to create block scope:** ```javascript // Each case has its own block scope switch (action) { case 'HIGHLIGHT_ELEMENT': { const { elementId, highlight } = payload; // ... break; } case 'ANNOTATE_ELEMENT': { const { elementId, text } = payload; // OK - different block scope // ... break; } case 'SET_WIDGET_STATE': { const { cameraPosition, scale } = payload; // ... break; } } ``` **Alternative - Use different variable names:** ```javascript switch (action) { case 'HIGHLIGHT_ELEMENT': const highlightData = payload; // Use highlightData.elementId break; case 'ANNOTATE_ELEMENT': const annotateData = payload; // Use annotateData.elementId break; } ``` ### 2. Teacher Actions Listener Pattern Always wrap switch cases in braces: ```javascript window.addEventListener('message', (event) => { const { action, payload } = event.data; switch (action) { case 'SET_WIDGET_STATE': { if (payload.cameraPosition) camera.position.set(...payload.cameraPosition); if (payload.scale !== undefined) { objects.cellGroup.scale.setScalar(payload.scale); } break; } case 'HIGHLIGHT_ELEMENT': { const { elementId, highlight } = payload; if (objects[elementId]) { objects[elementId].forEach(mesh => { mesh.material.emissive.set(highlight ? 0xffff00 : 0x000000); }); } break; } case 'ANNOTATE_ELEMENT': { const { elementId, text } = payload; // Create annotation tooltip break; } } }); ``` ## Output Format Return ONLY the HTML document, no markdown fences or explanations. **CRITICAL: Output EXACTLY ONE HTML document.** - Do NOT duplicate content - Do NOT include multiple `` tags - The output must end with exactly one `` tag