333просмотров
13.5%от подписчиков
28 февраля 2026 г.
Score: 366
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Gesture Controlled 3D Particle System</title>
<style>
body { margin: 0; overflow: hidden; background: black; }
video { display: none; }
</style>
</head>
<body> <video id="video" autoplay playsinline></video> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r152/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/hands/hands.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js"></script> <script>
let scene, camera, renderer, particles;
let particleGeometry, particleMaterial;
let currentShapeIndex = 0;
let shapes = ["sphere", "heart", "flower", "saturn", "fireworks"];
let scaleFactor = 1;
let hue = 0; init();
animate(); function init() { scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000); camera.position.z = 5; renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); createParticles("sphere"); window.addEventListener('resize', () => { camera.aspect = window.innerWidth/window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); initHandTracking();
} function createParticles(type) { if (particles) scene.remove(particles); const count = 3000; particleGeometry = new THREE.BufferGeometry(); const positions = new Float32Array(count 3); for (let i = 0; i < count; i++) { let x, y, z; if (type === "sphere") { const radius = 1.5; const theta = Math.random() Math.PI 2; const phi = Math.acos(2Math.random()-1); x = radius Math.sin(phi) Math.cos(theta); y = radius Math.sin(phi) Math.sin(theta); z = radius Math.cos(phi); } else if (type === "heart") { const t = Math.random() Math.PI 2; x = 16 Math.pow(Math.sin(t),3)/16; y = (13Math.cos(t) - 5Math.cos(2t) - 2Math.cos(3t) - Math.cos(4t))/16; z = (Math.random()-0.5)0.5; } else if (type === "flower") { const t = Math.random() Math.PI 2; const r = Math.sin(6t); x = r Math.cos(t); y = r Math.sin(t); z = (Math.random()-0.5)0.3; } else if (type === "saturn") { const angle = Math.random() Math.PI 2; const radius = 1 + Math.random()0.3; x = radius Math.cos(angle); y = (Math.random()-0.5)0.2; z = radius Math.sin(angle); } else if (type === "fireworks") { const r = Math.random()1.5; const theta = Math.random()Math.PI2; const phi = Math.random()Math.PI; x = r Math.sin(phi)Math.cos(theta); y = r Math.sin(phi)Math.sin(theta); z = r Math.cos(phi); } positions[i3] = x; positions[i3+1] = y; positions[i*3+2] = z; } particleGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); particleMaterial = new THREE.PointsMaterial({ size: 0.03, color: new THREE.Color(hsl(${hue},100%,50%)) }); particles = new THREE.Points(particleGeometry, particleMaterial); scene.add(particles);
} function animate() { requestAnimationFrame(animate); particles.rotation.y += 0.003; particles.scale.set(scaleFactor, scaleFactor, scaleFactor); renderer.render(scene, camera);
} function initHandTracking() { const video = document.getElementById('video'); const hands = new Hands({ locateFile: file => https://cdn.jsdelivr.net/npm/@mediapipe/hands/${file} }); hands.s