import * as THREE from 'three'; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; // Scene setup const scene = new THREE.Scene(); 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); // Create cylindrical typography const radius = 2; const height = 2; const textCount = 20; // Number of text elements const textGroup = new THREE.Group(); const loader = new THREE.FontLoader(); loader.load('https://threejs.org/examples/fonts/helvetiker_bold.typeface.json', function (font) { const textMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff }); for (let i = 0; i < textCount; i++) { const angle = (i / textCount) * Math.PI * 2; const textGeometry = new THREE.TextGeometry('O3-MINI', { font: font, size: 0.4, height: 0.1, }); const textMesh = new THREE.Mesh(textGeometry, textMaterial); textMesh.position.set(Math.cos(angle) * radius, (Math.random() - 0.5) * height, Math.sin(angle) * radius); textMesh.lookAt(0, 0, 0); textGroup.add(textMesh); } scene.add(textGroup); }); // Add lighting const light = new THREE.AmbientLight(0xffffff, 1); scene.add(light); // Controls const controls = new OrbitControls(camera, renderer.domElement); controls.enableDamping = true; // Animation loop function animate() { requestAnimationFrame(animate); textGroup.rotation.y += 0.005; // Rotate slowly controls.update(); renderer.render(scene, camera); } animate(); // Handle window resize window.addEventListener('resize', () => { renderer.setSize(window.innerWidth, window.innerHeight); camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); });