Last active
May 30, 2025 08:54
-
-
Save ShaneBrumback/54c3b1a3d588050c9e37d0abb14125f3 to your computer and use it in GitHub Desktop.
Threejs Examples Enhancing Your Website With Threejs Star Field Particle System
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!--//////////////////////////////////////////////////////////////////////////////////////// | |
| /// /// | |
| /// Example Using Three.js Library, HTML, CSS & JavaScript /// | |
| // 3D Interactive Web Apps & Games 2021-2024 /// | |
| /// Contact Shane Brumback https://www.shanebrumback.com /// | |
| /// Send a message if you have questions about this code /// | |
| /// I am a freelance developer. I develop any and all web. /// | |
| /// Apps Websites 3D 2D CMS Systems etc. Contact me anytime :) /// | |
| /// /// | |
| ////////////////////////////////////////////////////////////////////////////////////////////--> | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Threejs Examples - Enhancing Your Website With Threejs Star Field Particle Systems</title> | |
| <style> | |
| body { | |
| color: white; | |
| text-align: center; | |
| margin: 0; | |
| background-color: black | |
| } | |
| a { | |
| text-decoration: none; | |
| color: white; | |
| } | |
| h1 { | |
| padding: 10px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <a href="http://www.shanebrumback.com/blog/enhancing-your-website-with-threejs-star-field-particle-systems.html"> | |
| <h1>Threejs Examples - Enhancing Your Website With Three.js Star Field Particle Systems</h1> | |
| </a> | |
| <!--Load the latest version of Three.js from CDN--> | |
| <script src="https://cdn.jsdelivr.net/npm/three@latest/build/three.min.js"></script> | |
| <script> | |
| // Variables for Three.js components | |
| let scene, camera, renderer; | |
| let mouseX = 0, mouseY = 0; | |
| let targetX = 0, targetY = 0; | |
| let particleSystem; | |
| let planes = [] | |
| // Function to set up the scene, camera, and renderer | |
| function init() { | |
| // Create the scene | |
| scene = new THREE.Scene(); | |
| // Create the camera | |
| camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 100, 1000); | |
| camera.position.z = 100; | |
| // Create the renderer | |
| renderer = new THREE.WebGLRenderer(); | |
| renderer.setPixelRatio(window.devicePixelRatio); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| renderer.toneMapping = THREE.ReinhardToneMapping; | |
| renderer.setClearColor(0x000000); // Set background color to black | |
| renderer.domElement.style.position = 'fixed'; | |
| renderer.domElement.style.zIndex = '-3'; | |
| renderer.domElement.style.left = '0'; | |
| renderer.domElement.style.top = '0'; | |
| document.body.appendChild(renderer.domElement);; | |
| // Call the function to load the star area | |
| loadStars(); | |
| // Function to handle window resizing | |
| window.addEventListener('resize', onWindowResize, false); | |
| // Function to handle mouse movement | |
| window.addEventListener('mousemove', onMouseMove, false); | |
| // Load the smoke texture | |
| const textureLoader = new THREE.TextureLoader(); | |
| const smokeTexture = textureLoader.load('images/smoke.png'); | |
| // Create 50 planes with smoke texture | |
| const planes = []; | |
| for (let i = 0; i < 50; i++) { | |
| const planeGeometry = new THREE.PlaneGeometry(500, 500); | |
| const planeMaterial = new THREE.MeshBasicMaterial({ | |
| map: smokeTexture, | |
| transparent: true, | |
| depthTest: false, // Disable depth testing for transparency | |
| }); | |
| const planeMesh = new THREE.Mesh(planeGeometry, planeMaterial); | |
| scene.add(planeMesh); | |
| // Set random initial positions | |
| planeMesh.position.set( | |
| Math.random() * 1000 - 500, | |
| Math.random() * 1000 - 500, | |
| Math.random() * 1000 - 500, | |
| ); | |
| // Face the camera | |
| const lookAtVector = new THREE.Vector3(); | |
| lookAtVector.subVectors(camera.position, planeMesh.position); | |
| planeMesh.quaternion.setFromUnitVectors(new THREE.Vector3(0, 0, 1), lookAtVector.normalize()); | |
| // Set random rotation speed | |
| const speed = Math.random() * 0.005; | |
| planeMesh.userData.speed = speed; | |
| planes.push(planeMesh); | |
| } | |
| } | |
| // Function to load the cube with particle system | |
| function loadStars() { | |
| const triangles = 10000; | |
| const positions = new Float32Array(triangles * 9); // 3 vertices per triangle, 3 coordinates per vertex | |
| const colors = new Float32Array(triangles * 12); // 4 color values per vertex | |
| const n = 800, n2 = n / 2; // cube size | |
| const d = 200, d2 = d / 2; // triangle size | |
| for (let i = 0; i < triangles; i++) { | |
| const vertexIndex = i * 9; // vertex index in the positions array | |
| const colorIndex = i * 12; // color index in the colors array | |
| // Generate random positions for the triangle vertices within the cube | |
| const x = Math.random() * n - n2; | |
| const y = Math.random() * n - n2; | |
| const z = Math.random() * n - n2; | |
| const ax = x + Math.random() * d - d2; | |
| const ay = y + Math.random() * d - d2; | |
| const az = z + Math.random() * d - d2; | |
| const bx = x + Math.random() * d - d2; | |
| const by = y + Math.random() * d - d2; | |
| const bz = z + Math.random() * d - d2; | |
| const cx = x + Math.random() * d - d2; | |
| const cy = y + Math.random() * d - d2; | |
| const cz = z + Math.random() * d - d2; | |
| // Set positions for the triangle vertices | |
| positions[vertexIndex] = ax; | |
| positions[vertexIndex + 1] = ay; | |
| positions[vertexIndex + 2] = az; | |
| positions[vertexIndex + 3] = bx; | |
| positions[vertexIndex + 4] = by; | |
| positions[vertexIndex + 5] = bz; | |
| positions[vertexIndex + 6] = cx; | |
| positions[vertexIndex + 7] = cy; | |
| positions[vertexIndex + 8] = cz; | |
| // Generate random bright colors for each vertex | |
| const r = Math.random(); | |
| const g = Math.random(); | |
| const b = Math.random(); | |
| // Set colors for the triangle vertices | |
| colors[colorIndex] = r; | |
| colors[colorIndex + 1] = g; | |
| colors[colorIndex + 2] = b; | |
| colors[colorIndex + 3] = 1.0; | |
| colors[colorIndex + 4] = r; | |
| colors[colorIndex + 5] = g; | |
| colors[colorIndex + 6] = b; | |
| colors[colorIndex + 7] = 1.0; | |
| colors[colorIndex + 8] = r; | |
| colors[colorIndex + 9] = g; | |
| colors[colorIndex + 10] = b; | |
| colors[colorIndex + 11] = 1.0; | |
| } | |
| const geometry = new THREE.BufferGeometry(); | |
| geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); | |
| geometry.setAttribute('color', new THREE.BufferAttribute(colors, 4)); | |
| const material = new THREE.PointsMaterial({ size: 0.05, vertexColors: true }); | |
| particleSystem = new THREE.Points(geometry, material); | |
| scene.add(particleSystem); | |
| } | |
| // Function to handle window resizing | |
| function onWindowResize() { | |
| camera.aspect = window.innerWidth / window.innerHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| } | |
| // Function to handle mouse movement | |
| function onMouseMove(event) { | |
| mouseX = (event.clientX - window.innerWidth / 2) / 100; | |
| mouseY = (event.clientY - window.innerHeight / 2) / 100; | |
| } | |
| // Function to update the scene's rotation based on mouse movement | |
| function updateSceneRotation() { | |
| targetX = mouseX * 0.01; | |
| targetY = mouseY * 0.01; | |
| particleSystem.rotation.y += .5 * (targetX - scene.rotation.y); | |
| particleSystem.rotation.x += .5 * (targetY - scene.rotation.x); | |
| } | |
| // Function to render the scene | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| updateSceneRotation() | |
| // Rotate the planes | |
| for (const plane of planes) { | |
| // Rotate the plane | |
| plane.rotateOnAxis(new THREE.Vector3(0, 0, 1), plane.userData.speed); | |
| } | |
| renderer.render(scene, camera); | |
| } | |
| // Call the init function to set up the scene, camera, and renderer | |
| init(); | |
| // Start the animation loop | |
| animate(); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment