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();
});