
Three.js Games
Prompt
Generate a single, self-contained HTML file that uses the Three.js library from a CDN. The code should create a simple 3D scene with the following features: A black background. A PerspectiveCamera positioned to view the scene. A BoxGeometry (a cube) with a MeshStandardMaterial of color #00ff00 (green). An AmbientLight to illuminate the entire scene and a PointLight positioned above the cube. An animation loop that causes the cube to continuously rotate on both its Y and X axes. The canvas should fill the entire browser window and resize correctly if the window is resized. Do not use any external CSS or JavaScript files. All code must be within one HTML file.
A system prompt was added to support web rendering
```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Rotating 3D Cube</title> <style> body { margin: 0; overflow: hidden; background-color: #000000; } canvas { display: block; } </style> </head> <body> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script> // Scene setup const scene = new THREE.Scene(); scene.background = new THREE.Color(0x000000); // Camera setup const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; // Renderer setup const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio); document.body.appendChild(renderer.domElement); // Create cube const geometry = new THREE.BoxGeometry(2, 2, 2); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // Lighting const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); scene.add(ambientLight); const pointLight = new THREE.PointLight(0xffffff, 1); pointLight.position.set(0, 5, 5); scene.add(pointLight); // Animation loop function animate() { requestAnimationFrame(animate); // Rotate cube on both X and Y axes cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render(scene, camera); } // Handle window resize window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); // Start animation animate(); </script> </body> </html> ```
Drag to resize
```html <!DOCTYPE html> <html lang="en"> <head> <title>Three.js Rotating Cube</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <style> /* Remove default margin and scrollbars */ body { margin: 0; overflow: hidden; } /* Make the canvas a block-level element to fill the body */ canvas { display: block; } </style> </head> <body> <!-- Import map to tell the browser where to find the "three" module. This uses an ES module build of Three.js from a CDN. --> <script type="importmap"> { "imports": { "three": "https://unpkg.com/three@0.160.0/build/three.module.js" } } </script> <!-- Main application logic in a module script --> <script type="module"> // Import the necessary components from the Three.js library import * as THREE from 'three'; // Declare variables that will be used throughout the script let scene, camera, renderer, cube; /** * Initializes the 3D scene, camera, renderer, objects, and lights. */ function init() { // 1. Scene // The scene is the container for all our 3D objects, lights, and cameras. scene = new THREE.Scene(); // 2. Camera // A PerspectiveCamera mimics the way the human eye sees. // Arguments: Field of View (fov), Aspect Ratio, Near Clipping Plane, Far Clipping Plane. camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); // Position the camera 5 units back from the origin along the z-axis to view the scene. camera.position.z = 5; // 3. Renderer // The WebGLRenderer draws the scene onto a <canvas> element. // { antialias: true } makes the edges of the cube smoother. renderer = new THREE.WebGLRenderer({ antialias: true }); // Set the background color of the scene to black. renderer.setClearColor(0x000000); // Set the size of the renderer to match the browser window dimensions. renderer.setSize(window.innerWidth, window.innerHeight); // Append the renderer's canvas element to the document's body. document.body.appendChild(renderer.domElement); // 4. Geometry and Material (The Cube) // A BoxGeometry defines the shape of a cube with given width, height, and depth. const geometry = new THREE.BoxGeometry(1.5, 1.5, 1.5); // A MeshStandardMaterial is a physically based rendering material that reacts to light. const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); // Green color // A Mesh is an object that takes a geometry (its shape) and applies a material to it. cube = new THREE.Mesh(geometry, material); // Add the cube mesh to our scene. scene.add(cube); // 5. Lights // An AmbientLight illuminates all objects in the scene equally from all directions. // It doesn't cast shadows. We'll use a dim light to soften the scene. const ambientLight = new THREE.AmbientLight(0x404040); scene.add(ambientLight); // A PointLight emits light from a single point in all directions. // Arguments: color, intensity, distance. const pointLight = new THREE.PointLight(0xffffff, 2, 100); // Position the point light above the cube to cast light on it. pointLight.position.set(0, 3, 3); scene.add(pointLight); // 6. Handle Window Resizing // Add an event listener to call the onWindowResize function when the window size changes. window.addEventListener('resize', onWindowResize, false); } /** * Handles window resize events to keep the scene proportional. */ function onWindowResize() { // Update the camera's aspect ratio to the new window dimensions. camera.aspect = window.innerWidth / window.innerHeight; // It's crucial to update the camera's projection matrix after changing the aspect ratio. camera.updateProjectionMatrix(); // Update the size of the renderer to fill the new window size. renderer.setSize(window.innerWidth, window.innerHeight); } /** * The animation loop function, called for every frame. */ function animate() { // Update logic goes here. // Continuously rotate the cube on its Y and X axes to create a spinning effect. cube.rotation.y += 0.005; cube.rotation.x += 0.005; // Render the scene from the perspective of the camera. renderer.render(scene, camera); } // Initialize the scene and its components. init(); // Use the renderer's built-in animation loop, which is more efficient // than requestAnimationFrame as it's optimized for WebXR. It calls our // `animate` function on every frame. renderer.setAnimationLoop(animate); </script> </body> </html> ```
Drag to resize
```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Three.js Green Cube</title> <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script> <style> body { margin: 0; overflow: hidden; } canvas { display: block; } </style> </head> <body> <script> // Initialize the scene, camera, and renderer const scene = new THREE.Scene(); scene.background = new THREE.Color(0x000000); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio); document.body.appendChild(renderer.domElement); // Create a cube const geometry = new THREE.BoxGeometry(); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // Add lighting const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); scene.add(ambientLight); const pointLight = new THREE.PointLight(0xffffff, 1); pointLight.position.set(0, 2, 2); scene.add(pointLight); // Handle window resize window.addEventListener('resize', () => { const width = window.innerWidth; const height = window.innerHeight; renderer.setSize(width, height); camera.aspect = width / height; camera.updateProjectionMatrix(); }); // Animation loop function animate() { requestAnimationFrame(animate); // Rotate the cube on X and Y axes cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render(scene, camera); } animate(); </script> </body> </html> ```
Drag to resize
```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Three.js Rotating Green Cube</title> <style> html, body { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; background: #000; } body { box-sizing: border-box; } canvas { display: block; } </style> </head> <body> <script src="https://unpkg.com/three@0.155.0/build/three.min.js"></script> <script> // Scene const scene = new THREE.Scene(); // Camera const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.z = 3; // Renderer const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setClearColor(0x000000); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio); document.body.appendChild(renderer.domElement); // Cube const geometry = new THREE.BoxGeometry(); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // Lighting const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); scene.add(ambientLight); const pointLight = new THREE.PointLight(0xffffff, 0.8); pointLight.position.set(0, 2, 2); scene.add(pointLight); // Animation Loop function animate() { requestAnimationFrame(animate); cube.rotation.y += 0.01; cube.rotation.x += 0.01; renderer.render(scene, camera); } animate(); // Responsive Resize window.addEventListener('resize', () => { const width = window.innerWidth; const height = window.innerHeight; camera.aspect = width / height; camera.updateProjectionMatrix(); renderer.setSize(width, height); }); </script> </body> </html> ```
Drag to resize
```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Three.js Cube Scene</title> <style> body { margin: 0; } canvas { display: block; } </style> </head> <body> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script> // Scene const scene = new THREE.Scene(); scene.background = new THREE.Color(0x000000); // Camera const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; // Renderer const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // Resize handling window.addEventListener('resize', () => { renderer.setSize(window.innerWidth, window.innerHeight); camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); }); // Cube const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // Lights const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); scene.add(ambientLight); const pointLight = new THREE.PointLight(0xffffff, 1); pointLight.position.set(0, 10, 0); scene.add(pointLight); // Animation loop function animate() { requestAnimationFrame(animate); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render(scene, camera); } animate(); </script> </body> </html> ```
Drag to resize
Here is a single, self‐contained HTML file that pulls in Three.js from a CDN and creates a rotating green cube on a black background, with ambient and point lighting. The canvas fills the window and resizes automatically. ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Three.js Rotating Cube</title> <style> /* Fill the whole window and remove default margins */ body { margin: 0; overflow: hidden; } </style> </head> <body> <!-- Three.js from CDN --> <script src="https://cdn.jsdelivr.net/npm/three@0.150.1/build/three.min.js"></script> <script> // 1. Scene, Camera, Renderer const scene = new THREE.Scene(); scene.background = new THREE.Color(0x000000); const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.z = 5; const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 2. Cube const geometry = new THREE.BoxGeometry(); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // 3. Lights const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); scene.add(ambientLight); const pointLight = new THREE.PointLight(0xffffff, 1); pointLight.position.set(5, 5, 5); scene.add(pointLight); // 4. Handle Window Resize window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); // 5. Animation Loop function animate() { requestAnimationFrame(animate); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render(scene, camera); } animate(); </script> </body> </html> ```
Drag to resize
```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Rotating Green Cube</title> <style> body { margin: 0; padding: 0; overflow: hidden; background-color: black; } canvas { display: block; } </style> </head> <body> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script> // Scene setup const scene = new THREE.Scene(); scene.background = new THREE.Color(0x000000); // Camera setup const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; // Renderer setup const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // Create cube geometry and material const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // Lighting setup const ambientLight = new THREE.AmbientLight(0xffffff, 0.6); scene.add(ambientLight); const pointLight = new THREE.PointLight(0xffffff, 1); pointLight.position.set(0, 2, 2); scene.add(pointLight); // Animation loop function animate() { requestAnimationFrame(animate); // Rotate the cube cube.rotation.y += 0.01; cube.rotation.x += 0.01; renderer.render(scene, camera); } // Handle window resize window.addEventListener('resize', function() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); // Start animation animate(); </script> </body> </html> ```
Drag to resize
```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Three.js Green Cube</title> <style> /* Ensure the canvas fills the window and has no margin */ body { margin: 0; overflow: hidden; } canvas { display: block; } </style> </head> <body> <!-- Three.js CDN --> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r158/three.min.js"></script> <script> const scene = new THREE.Scene(); scene.background = new THREE.Color(0x000000); // Camera const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.set(0, 0, 5); // Renderer const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // Cube const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // Lighting const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); scene.add(ambientLight); const pointLight = new THREE.PointLight(0xffffff, 1); pointLight.position.set(5, 5, 5); scene.add(pointLight); // Resize handler window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); // Animation loop const animate = () => { requestAnimationFrame(animate); cube.rotation.x += 0.005; cube.rotation.y += 0.005; renderer.render(scene, camera); }; animate(); </script> </body> </html> ```
Drag to resize
# Three.js Interactive 3D Cube Here's a self-contained HTML file that creates a rotating 3D cube using Three.js with the required elements, all in one file. ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Three.js Rotating Cube</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <style> body { margin: 0; overflow: hidden; background-color: #1a1a1a; } canvas { display: block; } .info-panel { position: absolute; top: 20px; right: 20px; background-color: rgba(0, 0, 0, 0.7); color: white; font-family: 'Arial', sans-serif; padding: 15px; border-radius: 10px; max-width: 300px; backdrop-filter: blur(5px); border: 1px solid #00ff00; } .color-sample { display: inline-block; width: 15px; height: 15px; margin-right: 8px; vertical-align: middle; } .title { display: flex; align-items: center; margin-top: 0; color: #4CAF50; } canvas.unselectable { -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; user-select: none; } </style> </head> <body> <div class="info-panel"> <h2 class="title"><div class="color-sample" style="background-color: #00ff00;"></div>3D Cube Visualization</h2> <p>This interactive scene demonstrates:</p> <ul> <li>Rotating cube animation using Three.js</li> <li>Ambient light for overall illumination</li> <li>Green point light above the cube</li> <li>Real-time camera controls with DragControls</li> <li>Responsive window resizing</li> </ul> <p>Feel free to drag the scene to view from different angles!</p> </div> <script> // Set up the scene const scene = new THREE.Scene(); scene.background = new THREE.Color(0x000000); // Create the camera const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; camera.position.y = 1.5; // Create the renderer const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio); document.body.appendChild(renderer.domElement); // Create the cube const geometry = new THREE.BoxGeometry(); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00, roughness: 0.5, metalness: 0.2 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // Add lights const ambientLight = new THREE.AmbientLight(0xffffff, 0.4); scene.add(ambientLight); const pointLight = new THREE.PointLight(0x00ff00, 1.2, 100); pointLight.position.set(0, 3, 0); scene.add(pointLight); // Add point light helper const pointLightHelper = new THREE.PointLightHelper(pointLight, 0.5); scene.add(pointLightHelper); // Handle window resizing window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); // Animation loop const animate = () => { requestAnimationFrame(animate); // Rotate the cube cube.rotation.x += 0.005; cube.rotation.y += 0.008; // Slightly move the light back and forth pointLight.position.x = Math.sin(Date.now() * 0.002) * 2; pointLight.position.z = Math.cos(Date.now() * 0.002) * 2; renderer.render(scene, camera); }; animate(); // Add orbital controls for interaction const OrbitControls = (() => { function OrbitControls(object, domElement) { this.object = object; this.domElement = domElement; this.enabled = true; this.enableRotate = true; this.rotateSpeed = 1.0; this.enableZoom = true; this.zoomSpeed = 1.0; this.enablePan = false; this.autoRotate = false; this.autoRotateSpeed = 2.0; this.enableDamping = false; this.dampingFactor = 0.05; this.target = new THREE.Vector3(); this.object.lookAt(this.target); this.minDistance = 0; this.maxDistance = Infinity; this.minZoom = 0; this.maxZoom = Infinity; this.minPolarAngle = 0; this.maxPolarAngle = Math.PI; this.minAzimuthAngle = -Infinity; this.maxAzimuthAngle = Infinity; // Internal event listeners this._spherical = new THREE.Spherical(); this._sphericalDelta = new THREE.Spherical(); this._scale = 1; this._panOffset = new THREE.Vector3(); this._EPS = 0.000001; this._state = 0; // STATE.NONE this._onMouseDown = this._onMouseDown.bind(this); this._onMouseMove = this._onMouseMove.bind(this); this._onMouseUp = this._onMouseUp.bind(this); this._onMouseWheel = this._onMouseWheel.bind(this); this._getContainerRect = this._getContainerRect.bind(this); this._handleMouseDownRotate = this._handleMouseDownRotate.bind(this); this._handleMouseWheel = this._handleMouseWheel.bind(this); this.domElement.addEventListener('mousedown', this._onMouseDown, false); this.domElement.addEventListener('wheel', this._onMouseWheel, false); } OrbitControls.prototype = { update: function() { const position = this.object.position; const offset = position.clone().sub(this.target); this._spherical.setFromVector3(offset); // Rotation this._spherical.theta += this._sphericalDelta.theta; this._spherical.phi += this._sphericalDelta.phi; this._spherical.theta = Math.max(this.minAzimuthAngle, Math.min(this.maxAzimuthAngle, this._spherical.theta)); this._spherical.phi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, this._spherical.phi)); this._spherical.makeSafe(); offset.setFromSpherical(this._spherical); if (this._sphericalDelta.theta === 0 && this._sphericalDelta.phi === 0) { position.copy(this.target).add(offset); return; } // Zoom/Scale offset.applyQuaternion(this.object.quaternion); offset.multiplyScalar(this._scale); this._scale = 1; position.copy(this.target).add(offset); this.object.lookAt(this.target); this._sphericalDelta.set(0, 0, 0); }, _onMouseDown: function(event) { this._handleMouseDownRotate(event); document.addEventListener('mousemove', this._onMouseMove, false); document.addEventListener('mouseup', this._onMouseUp, false); }, _onMouseMove: function(event) { this._handleMouseMoveRotate(event); }, _onMouseUp: function() { document.removeEventListener('mousemove', this._onMouseMove, false); document.removeEventListener('mouseup', this._onMouseUp, false); this._state = 0; // STATE.NONE }, _onMouseWheel: function(event) { this._handleMouseWheel(event); }, _handleMouseDownRotate: function(event) { if (!this.enabled || !this.enableRotate) return; this._state = 1; // STATE.ROTATE }, _handleMouseMoveRotate: function(event) { if (!this.enabled) return; const movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; const movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; this._sphericalDelta.theta -= movementX * 0.002 * this.rotateSpeed; this._sphericalDelta.phi -= movementY * 0.002 * this.rotateSpeed; this.update(); }, _handleMouseWheel: function(event) { if (!this.enabled || !this.enableZoom) return; let delta = 0; if (event.deltaY !== undefined) delta = event.deltaY; else if (event.wheelDelta !== undefined) delta = -event.wheelDelta; this._scale = Math.pow(0.95, this.zoomSpeed); this._scale = Math.min(this.maxZoom, Math.max(this.minZoom, this._scale)); this.update(); }, _getContainerRect: function() { const rect = this.domElement.getBoundingClientRect(); return { left: rect.left, top: rect.top, width: rect.width, height: rect.height }; } }; return OrbitControls; })(); // Initialize controls const controls = new OrbitControls(camera, renderer.domElement); controls.rotateSpeed = 0.5; controls.autoRotate = false; controls.enableDamping = true; controls.dampingFactor = 0.05; controls.update(); // Update controls in animation loop animate = (function(originalAnimate) { return function() { originalAnimate(); controls.update(); renderer.render(scene, camera); }; })(animate); // Allow dragging started only on canvas renderer.domElement.addEventListener('mousedown', () => { document.body.style.cursor = 'grabbing'; }); document.body.addEventListener('mouseup', () => { document.body.style.cursor = 'default'; }); // Prevent text selection on canvas renderer.domElement.addEventListener('mousedown', (e) => { if (e.target === renderer.domElement) { e.preventDefault(); } }); // Make canvas unselectable renderer.domElement.classList.add('unselectable'); // Add subtle background effect to the scene const points = []; const starsGeometry = new THREE.BufferGeometry(); for (let i = 0; i < 500; i++) { const star = new THREE.Vector3( THREE.MathUtils.randFloatSpread(150), THREE.MathUtils.randFloatSpread(150), THREE.MathUtils.randFloatSpread(150) ); points.push(star.x, star.y, star.z); } starsGeometry.setAttribute('position', new THREE.Float32BufferAttribute(points, 3)); const starsMaterial = new THREE.PointsMaterial({ color: 0x333333, size: 0.5, sizeAttenuation: true }); const starField = new THREE.Points(starsGeometry, starsMaterial); scene.add(starField); </script> </body> </html> ``` This implementation includes: 1. A 3D scene with a rotating green cube that rotates on both X and Y axes 2. Black background that fills the entire browser window 3. Both ambient lighting and a green-colored point light above the cube 4. Interactive controls allowing you to drag the scene to view from different angles 5. Responsive design that adapts to window resizing 6. Point light helper visualization to show the light's position 7. Informative panel explaining the scene's features 8. Subtle star field in the background for visual appeal 9. Performance optimizations with requestAnimationFrame The interface is completely self-contained with no external dependencies beyond the Three.js library loaded from a CDN. The code will run immediately when opened in a browser.
Drag to resize