|
|
<!DOCTYPE html> |
|
|
<html lang="en"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>Infinite Vortex</title> |
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> |
|
|
<style> |
|
|
body { |
|
|
margin: 0; |
|
|
overflow: hidden; |
|
|
background: #000; |
|
|
} |
|
|
canvas { |
|
|
display: block; |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body> |
|
|
<script> |
|
|
const scene = new THREE.Scene(); |
|
|
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); |
|
|
const renderer = new THREE.WebGLRenderer({ antialias: true }); |
|
|
|
|
|
renderer.setSize(window.innerWidth, window.innerHeight); |
|
|
document.body.appendChild(renderer.domElement); |
|
|
|
|
|
const geometry = new THREE.TorusKnotGeometry(10, 3, 100, 16); |
|
|
const material = new THREE.MeshBasicMaterial({ |
|
|
color: 0xffffff, |
|
|
wireframe: true |
|
|
}); |
|
|
const vortex = new THREE.Mesh(geometry, material); |
|
|
scene.add(vortex); |
|
|
|
|
|
camera.position.z = 30; |
|
|
|
|
|
function animate() { |
|
|
requestAnimationFrame(animate); |
|
|
vortex.rotation.x += 0.01; |
|
|
vortex.rotation.y += 0.01; |
|
|
vortex.scale.x *= 1.001; |
|
|
vortex.scale.y *= 1.001; |
|
|
vortex.scale.z *= 1.001; |
|
|
|
|
|
|
|
|
if(vortex.scale.x > 5) { |
|
|
vortex.scale.set(1, 1, 1); |
|
|
} |
|
|
|
|
|
renderer.render(scene, camera); |
|
|
} |
|
|
|
|
|
window.addEventListener('resize', () => { |
|
|
camera.aspect = window.innerWidth / window.innerHeight; |
|
|
camera.updateProjectionMatrix(); |
|
|
renderer.setSize(window.innerWidth, window.innerHeight); |
|
|
}); |
|
|
|
|
|
animate(); |
|
|
</script> |
|
|
</body> |
|
|
</html> |