178 lines
6.4 KiB
HTML
178 lines
6.4 KiB
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 Geometries</title>
|
|
<style>
|
|
body { margin: 0; overflow: hidden; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; }
|
|
canvas { display: block; width: 100vw; height: 100vh; }
|
|
#info {
|
|
position: absolute; top: 10px; left: 10px; color: white;
|
|
background: rgba(0, 0, 0, 0.7); padding: 15px; border-radius: 8px;
|
|
font-size: 14px; max-width: 400px; z-index: 100;
|
|
}
|
|
#info h2 { margin: 0 0 10px 0; font-size: 18px; }
|
|
#info .web-source {
|
|
margin-top: 10px; padding-top: 10px;
|
|
border-top: 1px solid rgba(255,255,255,0.3);
|
|
font-size: 12px; opacity: 0.8;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="info">
|
|
<h2>Rotating Geometries</h2>
|
|
<p><strong>Technique:</strong> Basic scene setup with animated rotation</p>
|
|
<p><strong>Learning:</strong> Scene, camera, renderer initialization and requestAnimationFrame loop</p>
|
|
<div class="web-source">
|
|
<strong>Web Source:</strong><br>
|
|
<a href="https://threejs.org/docs/" target="_blank" style="color: #4fc3f7;">Three.js Documentation</a><br>
|
|
<em>Applied: Basic scene creation, PerspectiveCamera, WebGLRenderer, rotation animation</em>
|
|
</div>
|
|
</div>
|
|
|
|
<script type="importmap">
|
|
{
|
|
"imports": {
|
|
"three": "https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js",
|
|
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/"
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<script type="module">
|
|
import * as THREE from 'three';
|
|
|
|
// Scene Setup
|
|
const scene = new THREE.Scene();
|
|
scene.background = new THREE.Color(0x1a1a2e);
|
|
|
|
// Camera Setup - PerspectiveCamera(fov, aspect, near, far)
|
|
const camera = new THREE.PerspectiveCamera(
|
|
75, // Field of view
|
|
window.innerWidth / window.innerHeight, // Aspect ratio
|
|
0.1, // Near clipping plane
|
|
1000 // Far clipping plane
|
|
);
|
|
camera.position.z = 8;
|
|
|
|
// Renderer Setup
|
|
const renderer = new THREE.WebGLRenderer({ antialias: true });
|
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
renderer.setPixelRatio(window.devicePixelRatio);
|
|
document.body.appendChild(renderer.domElement);
|
|
|
|
// Geometry 1: Rotating Cube (center)
|
|
const cubeGeometry = new THREE.BoxGeometry(1.5, 1.5, 1.5);
|
|
const cubeMaterial = new THREE.MeshStandardMaterial({
|
|
color: 0xff6b6b,
|
|
metalness: 0.3,
|
|
roughness: 0.4
|
|
});
|
|
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
|
|
cube.position.set(0, 0, 0);
|
|
scene.add(cube);
|
|
|
|
// Geometry 2: Sphere (top left)
|
|
const sphereGeometry = new THREE.SphereGeometry(0.8, 32, 32);
|
|
const sphereMaterial = new THREE.MeshStandardMaterial({
|
|
color: 0x4ecdc4,
|
|
metalness: 0.5,
|
|
roughness: 0.2
|
|
});
|
|
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
|
|
sphere.position.set(-3, 2, 0);
|
|
scene.add(sphere);
|
|
|
|
// Geometry 3: Torus (top right)
|
|
const torusGeometry = new THREE.TorusGeometry(0.7, 0.3, 16, 100);
|
|
const torusMaterial = new THREE.MeshStandardMaterial({
|
|
color: 0xffe66d,
|
|
metalness: 0.4,
|
|
roughness: 0.3
|
|
});
|
|
const torus = new THREE.Mesh(torusGeometry, torusMaterial);
|
|
torus.position.set(3, 2, 0);
|
|
scene.add(torus);
|
|
|
|
// Geometry 4: Octahedron (bottom left)
|
|
const octaGeometry = new THREE.OctahedronGeometry(0.9);
|
|
const octaMaterial = new THREE.MeshStandardMaterial({
|
|
color: 0xa8e6cf,
|
|
metalness: 0.6,
|
|
roughness: 0.2
|
|
});
|
|
const octahedron = new THREE.Mesh(octaGeometry, octaMaterial);
|
|
octahedron.position.set(-3, -2, 0);
|
|
scene.add(octahedron);
|
|
|
|
// Geometry 5: Torus Knot (bottom right)
|
|
const knotGeometry = new THREE.TorusKnotGeometry(0.6, 0.2, 100, 16);
|
|
const knotMaterial = new THREE.MeshStandardMaterial({
|
|
color: 0xc77dff,
|
|
metalness: 0.5,
|
|
roughness: 0.3
|
|
});
|
|
const torusKnot = new THREE.Mesh(knotGeometry, knotMaterial);
|
|
torusKnot.position.set(3, -2, 0);
|
|
scene.add(torusKnot);
|
|
|
|
// Lighting Setup
|
|
// Ambient light provides overall scene illumination
|
|
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
|
|
scene.add(ambientLight);
|
|
|
|
// Point light adds directional highlights
|
|
const pointLight = new THREE.PointLight(0xffffff, 1);
|
|
pointLight.position.set(5, 5, 5);
|
|
scene.add(pointLight);
|
|
|
|
// Additional point light for balanced illumination
|
|
const pointLight2 = new THREE.PointLight(0xffffff, 0.5);
|
|
pointLight2.position.set(-5, -5, 5);
|
|
scene.add(pointLight2);
|
|
|
|
// Handle Window Resize
|
|
window.addEventListener('resize', () => {
|
|
camera.aspect = window.innerWidth / window.innerHeight;
|
|
camera.updateProjectionMatrix();
|
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
});
|
|
|
|
// Animation Loop
|
|
function animate() {
|
|
requestAnimationFrame(animate);
|
|
|
|
// Rotate each geometry at different speeds for visual variety
|
|
// Cube: moderate rotation on X and Y axes
|
|
cube.rotation.x += 0.01;
|
|
cube.rotation.y += 0.01;
|
|
|
|
// Sphere: slow rotation on Y axis
|
|
sphere.rotation.y += 0.005;
|
|
sphere.rotation.z += 0.003;
|
|
|
|
// Torus: fast rotation on X axis
|
|
torus.rotation.x += 0.02;
|
|
torus.rotation.y += 0.01;
|
|
|
|
// Octahedron: moderate rotation on all axes
|
|
octahedron.rotation.x += 0.008;
|
|
octahedron.rotation.y += 0.012;
|
|
octahedron.rotation.z += 0.005;
|
|
|
|
// Torus Knot: complex rotation pattern
|
|
torusKnot.rotation.x += 0.015;
|
|
torusKnot.rotation.y += 0.008;
|
|
|
|
// Render the scene from the perspective of the camera
|
|
renderer.render(scene, camera);
|
|
}
|
|
|
|
// Start the animation loop
|
|
animate();
|
|
</script>
|
|
</body>
|
|
</html>
|