Last active
March 19, 2024 05:17
-
-
Save ShaneBrumback/0b4b9a06603540b1b0f8f844dfc810ad to your computer and use it in GitHub Desktop.
Threejs Examples - Particle System 3D Blast Effect
This file contains 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> | |
<head> | |
<meta charset="utf-8"> | |
<title>Three.js Examples - Particle System 3D Blast Effect</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
</head> | |
<body> | |
<script src="https://cdn.jsdelivr.net/npm/three@latest/build/three.min.js"></script> | |
<script src="https://cdn.jsdelivr.net/npm/three@latest/examples/js/controls/OrbitControls.js"></script> | |
<script type="module"> | |
// Define global variables | |
let scene, camera, renderer; | |
const shotGunSpheres = []; | |
// Set up Three.js scene | |
scene = new THREE.Scene(); | |
// Set up the camera | |
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); | |
camera.position.x = 2; | |
camera.position.z = 2; | |
camera.position.y = 1; | |
// Set up the renderer | |
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); | |
renderer.setPixelRatio(window.devicePixelRatio); | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
renderer.toneMapping = THREE.ReinhardToneMapping; | |
renderer.domElement.id = 'renderer'; | |
renderer.setClearColor(0x000000, 1); // Set background color to black | |
renderer.domElement.style.position = 'fixed'; | |
renderer.domElement.style.zIndex = '-1'; | |
renderer.domElement.style.left = '0'; | |
renderer.domElement.style.top = '0'; | |
document.body.appendChild(renderer.domElement); | |
// Set up the orbital controls | |
const controls = new THREE.OrbitControls(camera, renderer.domElement); | |
controls.dampingFactor = 0.1; | |
// Create a grid helper | |
const grid = new THREE.GridHelper(100, 150); | |
scene.add(grid); | |
document.addEventListener('mousedown', function (event) { | |
const origin = getClickedPoint(event.clientX, event.clientY); | |
fireShotGunSpheres(origin); | |
}); | |
// Function to calculate the clicked 3D point based on mouse coordinates | |
function getClickedPoint(clientX, clientY) { | |
const vector = new THREE.Vector3(); | |
const rect = renderer.domElement.getBoundingClientRect(); | |
vector.x = ((clientX - rect.left) / rect.width) * 2 - 1; | |
vector.y = -((clientY - rect.top) / rect.height) * 2 + 1; | |
vector.z = 0.5; | |
vector.unproject(camera); | |
const dir = vector.sub(camera.position).normalize(); | |
const distance = -camera.position.z / dir.z; | |
return camera.position.clone().add(dir.multiplyScalar(distance)); | |
} | |
// Function to create and add spheres to the scene when the mouse is clicked | |
function fireShotGunSpheres(origin) { | |
// Loop 20 times to create 20 spheres | |
for (let i = 0; i < 50; i++) { | |
// Create a sphere | |
const sphere = new THREE.SphereGeometry(0.05, 32, 32); | |
const material = new THREE.MeshBasicMaterial({ color: 0xffff00 }); | |
const sphereMesh = new THREE.Mesh(sphere, material); | |
// Set the sphere position to the origin | |
sphereMesh.position.copy(origin); | |
// Set the direction of the shotgun spheres based on the mouse click | |
const direction = new THREE.Vector3(); | |
direction.x = THREE.MathUtils.randFloat(-0.1, 0.1); | |
direction.y = THREE.MathUtils.randFloat(-0.1, 0.1); | |
direction.z = THREE.MathUtils.randFloat(-0.1, 0.1); | |
direction.normalize(); | |
// Set the initial velocity of the shotgun spheres | |
const velocity = direction.clone().multiplyScalar(0.2); | |
// Add the velocity to the sphere position | |
sphereMesh.position.add(velocity); | |
// Create a point light at the center | |
const pointLight = new THREE.PointLight(0xffffff, 10, 50); | |
pointLight.position.set(0, 0, 0); | |
scene.add(pointLight); | |
// Add the sphere to the scene | |
scene.add(sphereMesh); | |
// Add the sphere to the shotGunSpheres array | |
shotGunSpheres.push({ mesh: sphereMesh, velocity: velocity, light: pointLight }); | |
// Remove the sphere and point light after 2 seconds | |
setTimeout(() => { | |
scene.remove(sphereMesh); | |
scene.remove(pointLight); | |
const index = shotGunSpheres.findIndex((item) => item.mesh === sphereMesh); | |
if (index !== -1) { | |
shotGunSpheres.splice(index, 1); | |
} | |
}, 2000); | |
} | |
} | |
// Function to animate the spheres created in the fireShotGunSpheres() function | |
function animateShotGunParticles() { | |
// Loop through each sphere | |
for (let i = 0; i < shotGunSpheres.length; i++) { | |
const sphereData = shotGunSpheres[i]; | |
const sphere = sphereData.mesh; | |
const velocity = sphereData.velocity; | |
// Move the sphere according to its velocity | |
sphere.position.add(velocity); | |
// Check if the sphere is too far from the camera | |
if (sphere.position.z < camera.position.z - 10) { | |
scene.remove(sphere); | |
shotGunSpheres.splice(i, 1); | |
i--; | |
} | |
} | |
} | |
function animate() { | |
requestAnimationFrame(animate); | |
animateShotGunParticles(); | |
renderer.render(scene, camera); | |
controls.update(); | |
} | |
animate(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment