CoolFace
Apppublic

r2d2starwars/cosmic-vortex-simulator

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
script.js167 linesDownload Raw Back to root
1document.addEventListener('DOMContentLoaded', () => {2    // Scene setup3    const scene = new THREE.Scene();4    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);5    const renderer = new THREE.WebGLRenderer({ canvas: document.getElementById('spaceCanvas'), antialias: true });6    renderer.setSize(window.innerWidth, window.innerHeight);7    renderer.setClearColor(0x000000);8    9    // Black hole parameters10    const blackHole = {11        radius: 1,12        position: new THREE.Vector3(0, 0, 0),13        gravity: 0.514    };15    16    // Create black hole17    const blackHoleGeometry = new THREE.SphereGeometry(blackHole.radius, 32, 32);18    const blackHoleMaterial = new THREE.MeshBasicMaterial({ 19        color: 0x000000,20        transparent: true,21        opacity: 0.922    });23    const blackHoleMesh = new THREE.Mesh(blackHoleGeometry, blackHoleMaterial);24    scene.add(blackHoleMesh);25    26    // Create accretion disk27    const diskGeometry = new THREE.RingGeometry(blackHole.radius * 1.5, blackHole.radius * 3, 64);28    const diskMaterial = new THREE.MeshBasicMaterial({ 29        color: 0x9933ff,30        side: THREE.DoubleSide,31        transparent: true,32        opacity: 0.833    });34    const diskMesh = new THREE.Mesh(diskGeometry, diskMaterial);35    diskMesh.rotation.x = Math.PI / 2;36    scene.add(diskMesh);37    38    // Create lensing effect39    const lensingGeometry = new THREE.SphereGeometry(blackHole.radius * 2, 32, 32);40    const lensingMaterial = new THREE.ShaderMaterial({41        uniforms: {42            time: { value: 0 }43        },44        vertexShader: `45            varying vec2 vUv;46            void main() {47                vUv = uv;48                gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);49            }50        `,51        fragmentShader: `52            uniform float time;53            varying vec2 vUv;54            void main() {55                vec2 p = vUv * 2.0 - 1.0;56                float len = length(p);57                vec2 distorted = p;58                distorted *= len;59                float a = atan(0.0, 1.0) + time * 0.2;60                distorted = vec2(distorted.x * cos(a) - distorted.y * sin(a), 61                                distorted.x * sin(a) + distorted.y * cos(a));62                vec3 color = mix(vec3(0.2, 0.2, 0.4), vec3(0.4, 0.2, 0.6), 0.5 + 0.5 * sin(len + time));63                color = mix(color, vec3(0.8, 0.4, 0.9), 0.5 + 0.5 * sin(time * 0.5));64                gl_FragColor = vec4(color, 0.2 * (1.0 - len));65            }66        `,67        transparent: true,68        side: THREE.BackSide69    });70    const lensingMesh = new THREE.Mesh(lensingGeometry, lensingMaterial);71    scene.add(lensingMesh);72    73    // Create stars and particles74    const particlesGeometry = new THREE.BufferGeometry();75    const particlesCount = 1000;76    const particlesPositions = new Float32Array(particlesCount * 3);77    const particlesSizes = new Float32Array(particlesCount);78    79    for (let i = 0; i < particlesCount; i++) {80        const theta = Math.random() * Math.PI * 2;81        const phi = Math.random() * Math.PI;82        const radius = 5 + Math.random() * 15;83        84        particlesPositions[i * 3] = radius * Math.sin(phi) * Math.cos(theta);85        particlesPositions[i * 3 + 1] = radius * Math.sin(phi) * Math.sin(theta);86        particlesPositions[i * 3 + 2] = radius * Math.cos(phi);87        88        particlesSizes[i] = 0.05 + Math.random() * 0.2;89    }90    91    particlesGeometry.setAttribute('position', new THREE.BufferAttribute(particlesPositions, 3));92    particlesGeometry.setAttribute('size', new THREE.BufferAttribute(particlesSizes, 1));93    94    const particlesMaterial = new THREE.PointsMaterial({95        color: 0xffffff,96        size: 0.1,97        sizeAttenuation: true,98        transparent: true,99        opacity: 0.8100    });101    102    const particles = new THREE.Points(particlesGeometry, particlesMaterial);103    scene.add(particles);104    105    // Camera position106    camera.position.z = 10;107    108    // Controls109    const controls = new THREE.OrbitControls(camera, renderer.domElement);110    controls.enablePan = false;111    controls.minDistance = 5;112    controls.maxDistance = 30;113    114    // Animation loop115    function animate() {116        requestAnimationFrame(animate);117        118        // Rotate black hole and disk119        blackHoleMesh.rotation.y += 0.005;120        diskMesh.rotation.y += 0.002;121        lensingMaterial.uniforms.time.value += 0.01;122        123        // Animate particles towards black hole124        const positions = particlesGeometry.attributes.position.array;125        126        for (let i = 0; i < particlesCount; i++) {127            const x = positions[i * 3];128            const y = positions[i * 3 + 1];129            const z = positions[i * 3 + 2];130            131            const distance = Math.sqrt(x * x + y * y + z * z);132            133            if (distance < blackHole.radius * 1.2) {134                // Reset particle position when it gets too close135                const theta = Math.random() * Math.PI * 2;136                const phi = Math.random() * Math.PI;137                const radius = 10 + Math.random() * 10;138                139                positions[i * 3] = radius * Math.sin(phi) * Math.cos(theta);140                positions[i * 3 + 1] = radius * Math.sin(phi) * Math.sin(theta);141                positions[i * 3 + 2] = radius * Math.cos(phi);142            } else {143                // Pull particle towards black hole144                const dx = -x * blackHole.gravity * 0.01;145                const dy = -y * blackHole.gravity * 0.01;146                const dz = -z * blackHole.gravity * 0.01;147                148                positions[i * 3] += dx;149                positions[i * 3 + 1] += dy;150                positions[i * 3 + 2] += dz;151            }152        }153        154        particlesGeometry.attributes.position.needsUpdate = true;155        156        renderer.render(scene, camera);157    }158    159    // Handle window resize160    window.addEventListener('resize', () => {161        camera.aspect = window.innerWidth / window.innerHeight;162        camera.updateProjectionMatrix();163        renderer.setSize(window.innerWidth, window.innerHeight);164    });165    166    animate();167});