Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Interactive Particle Playground</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <style> | |
| body { | |
| margin: 0; | |
| padding: 0; | |
| overflow: hidden; | |
| background-color: #0f172a; | |
| cursor: none; | |
| touch-action: none; | |
| } | |
| .particle { | |
| position: absolute; | |
| border-radius: 50%; | |
| pointer-events: none; | |
| transform: translate(-50%, -50%); | |
| } | |
| .character { | |
| position: absolute; | |
| font-weight: bold; | |
| pointer-events: none; | |
| transform: translate(-50%, -50%); | |
| font-family: 'Arial', sans-serif; | |
| text-shadow: 0 0 5px rgba(255,255,255,0.7); | |
| } | |
| .explosion { | |
| position: absolute; | |
| pointer-events: none; | |
| transform: translate(-50%, -50%); | |
| } | |
| .star { | |
| position: absolute; | |
| width: 0; | |
| height: 0; | |
| border-left: 5px solid transparent; | |
| border-right: 5px solid transparent; | |
| border-bottom: 10px solid; | |
| transform-origin: 50% 0; | |
| opacity: 0.8; | |
| } | |
| </style> | |
| </head> | |
| <body class="w-full h-screen"> | |
| <div id="particles"></div> | |
| <div id="characters"></div> | |
| <div id="explosions"></div> | |
| <script> | |
| // 鼠标拖尾效果 | |
| const particlesContainer = document.getElementById('particles'); | |
| const charactersContainer = document.getElementById('characters'); | |
| const explosionsContainer = document.getElementById('explosions'); | |
| let mouseX = 0; | |
| let mouseY = 0; | |
| let particles = []; | |
| let characters = []; | |
| let explosions = []; | |
| // 可映射的按键字符 | |
| const validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}|;':\",./<>?`~"; | |
| // 颜色数组 | |
| const colors = [ | |
| '#FF5252', '#FF4081', '#E040FB', '#7C4DFF', | |
| '#536DFE', '#448AFF', '#40C4FF', '#18FFFF', | |
| '#64FFDA', '#69F0AE', '#B2FF59', '#EEFF41', | |
| '#FFFF00', '#FFD740', '#FFAB40', '#FF6E40' | |
| ]; | |
| // 跟踪鼠标位置 | |
| document.addEventListener('mousemove', (e) => { | |
| mouseX = e.clientX; | |
| mouseY = e.clientY; | |
| createParticleTrail(); | |
| }); | |
| // 鼠标左键点击 - 圆形爆炸 | |
| document.addEventListener('mousedown', (e) => { | |
| if (e.button === 0) { // 左键 | |
| createExplosion(e.clientX, e.clientY, 'circle'); | |
| } else if (e.button === 2) { // 右键 | |
| createExplosion(e.clientX, e.clientY, 'star'); | |
| } | |
| }); | |
| // 阻止右键菜单 | |
| document.addEventListener('contextmenu', (e) => { | |
| e.preventDefault(); | |
| }); | |
| // 键盘按键事件 | |
| document.addEventListener('keydown', (e) => { | |
| if (validChars.includes(e.key)) { | |
| createCharacter(e.key); | |
| } | |
| }); | |
| // 创建拖尾粒子 | |
| function createParticleTrail() { | |
| const particle = document.createElement('div'); | |
| particle.className = 'particle'; | |
| const size = Math.random() * 5 + 2; | |
| const color = colors[Math.floor(Math.random() * colors.length)]; | |
| particle.style.width = `${size}px`; | |
| particle.style.height = `${size}px`; | |
| particle.style.backgroundColor = color; | |
| particle.style.left = `${mouseX}px`; | |
| particle.style.top = `${mouseY}px`; | |
| particlesContainer.appendChild(particle); | |
| particles.push({ | |
| element: particle, | |
| x: mouseX, | |
| y: mouseY, | |
| size: size, | |
| color: color, | |
| life: 100, | |
| speedX: Math.random() * 4 - 2, | |
| speedY: Math.random() * 4 - 2 | |
| }); | |
| } | |
| // 创建字符抛射 | |
| function createCharacter(char) { | |
| const character = document.createElement('div'); | |
| character.className = 'character'; | |
| character.textContent = char; | |
| const startX = Math.random() * window.innerWidth; | |
| const color = colors[Math.floor(Math.random() * colors.length)]; | |
| const size = Math.random() * 20 + 20; | |
| character.style.color = color; | |
| character.style.fontSize = `${size}px`; | |
| character.style.left = `${startX}px`; | |
| character.style.top = `${window.innerHeight}px`; | |
| charactersContainer.appendChild(character); | |
| // 抛物线参数 | |
| const gravity = 0.2; | |
| const initialSpeed = -10 - Math.random() * 10; | |
| const horizontalSpeed = Math.random() * 4 - 2; | |
| characters.push({ | |
| element: character, | |
| x: startX, | |
| y: window.innerHeight, | |
| speedX: horizontalSpeed, | |
| speedY: initialSpeed, | |
| gravity: gravity, | |
| rotation: 0, | |
| rotationSpeed: Math.random() * 4 - 2, | |
| opacity: 1, | |
| life: 100 | |
| }); | |
| } | |
| // 创建爆炸效果 | |
| function createExplosion(x, y, type) { | |
| const explosion = document.createElement('div'); | |
| explosion.className = 'explosion'; | |
| explosion.style.left = `${x}px`; | |
| explosion.style.top = `${y}px`; | |
| explosionsContainer.appendChild(explosion); | |
| const particleCount = type === 'circle' ? 30 : 10; | |
| const explosionParticles = []; | |
| for (let i = 0; i < particleCount; i++) { | |
| if (type === 'circle') { | |
| const particle = document.createElement('div'); | |
| particle.className = 'particle'; | |
| const size = Math.random() * 8 + 2; | |
| const color = colors[Math.floor(Math.random() * colors.length)]; | |
| particle.style.width = `${size}px`; | |
| particle.style.height = `${size}px`; | |
| particle.style.backgroundColor = color; | |
| explosion.appendChild(particle); | |
| explosionParticles.push({ | |
| element: particle, | |
| x: 0, | |
| y: 0, | |
| size: size, | |
| color: color, | |
| speedX: Math.random() * 10 - 5, | |
| speedY: Math.random() * 10 - 5, | |
| life: 50 + Math.random() * 50 | |
| }); | |
| } else { // star | |
| const star = document.createElement('div'); | |
| star.className = 'star'; | |
| const color = colors[Math.floor(Math.random() * colors.length)]; | |
| const points = 5; | |
| const rotation = (360 / points) * i; | |
| star.style.borderBottomColor = color; | |
| star.style.transform = `translate(-50%, -50%) rotate(${rotation}deg)`; | |
| explosion.appendChild(star); | |
| explosionParticles.push({ | |
| element: star, | |
| x: 0, | |
| y: 0, | |
| speedX: Math.cos(rotation * Math.PI / 180) * (3 + Math.random() * 3), | |
| speedY: Math.sin(rotation * Math.PI / 180) * (3 + Math.random() * 3), | |
| life: 70 + Math.random() * 30, | |
| rotation: rotation | |
| }); | |
| } | |
| } | |
| explosions.push({ | |
| element: explosion, | |
| particles: explosionParticles, | |
| x: x, | |
| y: y, | |
| life: 100 | |
| }); | |
| } | |
| // 动画循环 | |
| function animate() { | |
| // 更新拖尾粒子 | |
| for (let i = particles.length - 1; i >= 0; i--) { | |
| const p = particles[i]; | |
| p.life--; | |
| p.x += p.speedX; | |
| p.y += p.speedY; | |
| p.element.style.left = `${p.x}px`; | |
| p.element.style.top = `${p.y}px`; | |
| p.element.style.opacity = p.life / 100; | |
| if (p.life <= 0) { | |
| p.element.remove(); | |
| particles.splice(i, 1); | |
| } | |
| } | |
| // 更新字符抛射 | |
| for (let i = characters.length - 1; i >= 0; i--) { | |
| const c = characters[i]; | |
| c.life--; | |
| c.speedY += c.gravity; | |
| c.x += c.speedX; | |
| c.y += c.speedY; | |
| c.rotation += c.rotationSpeed; | |
| c.opacity = c.life / 100; | |
| c.element.style.left = `${c.x}px`; | |
| c.element.style.top = `${c.y}px`; | |
| c.element.style.transform = `translate(-50%, -50%) rotate(${c.rotation}deg)`; | |
| c.element.style.opacity = c.opacity; | |
| if (c.y > window.innerHeight + 100 || c.life <= 0) { | |
| c.element.remove(); | |
| characters.splice(i, 1); | |
| } | |
| } | |
| // 更新爆炸效果 | |
| for (let i = explosions.length - 1; i >= 0; i--) { | |
| const e = explosions[i]; | |
| e.life--; | |
| for (let j = e.particles.length - 1; j >= 0; j--) { | |
| const p = e.particles[j]; | |
| p.x += p.speedX; | |
| p.y += p.speedY; | |
| p.element.style.left = `${p.x}px`; | |
| p.element.style.top = `${p.y}px`; | |
| p.element.style.opacity = e.life / 100; | |
| } | |
| if (e.life <= 0) { | |
| e.element.remove(); | |
| explosions.splice(i, 1); | |
| } | |
| } | |
| requestAnimationFrame(animate); | |
| } | |
| animate(); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=KuRRe8/mouseanimation-deepsite" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |