* { margin: 0; padding: 0; box-sizing: border-box; cursor: none !important; } body { min-height: 100vh; overflow: hidden; background: radial-gradient(circle at 20% 20%, #1a0005 0%, #080002 50%, #020001 100%); position: relative; } #spidey-canvas { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: 1; pointer-events: none; } .spidey-cursor-dot { position: fixed; width: 6px; height: 6px; background: #ff0033; border-radius: 50%; pointer-events: none; z-index: 9999; transform: translate(-50%, -50%); box-shadow: 0 0 10px #ff0033, 0 0 20px #ff0033; } .spidey-cursor-ring { position: fixed; width: 34px; height: 34px; border: 1.5px dashed #ff0033; border-radius: 50%; pointer-events: none; z-index: 9998; transform: translate(-50%, -50%); box-shadow: 0 0 15px rgba(255, 0, 51, 0.4); transition: width 0.2s ease, height 0.2s ease; } .web-burst { position: fixed; border: 1.5px solid #ff0033; border-radius: 50%; pointer-events: none; z-index: 9997; transform: translate(-50%, -50%); animation: burst 0.45s ease-out forwards; } @keyframes burst { 0% { width: 10px; height: 10px; opacity: 1; border-color: #ff0033; } 100% { width: 90px; height: 90px; opacity: 0; border-color: #00d2ff; } } const cursorDot = document.getElementById('cursor-dot'); const cursorRing = document.getElementById('cursor-ring'); let mouseX = -1000; let mouseY = -1000; let ringX = -1000; let ringY = -1000; window.addEventListener('mousemove', (e) => { mouseX = e.clientX; mouseY = e.clientY; cursorDot.style.left = `${mouseX}px`; cursorDot.style.top = `${mouseY}px`; }); function animateCursor() { ringX += (mouseX - ringX) * 0.16; ringY += (mouseY - ringY) * 0.16; cursorRing.style.left = `${ringX}px`; cursorRing.style.top = `${ringY}px`; requestAnimationFrame(animateCursor); } animateCursor(); window.addEventListener('click', (e) => { const burst = document.createElement('div'); burst.className = 'web-burst'; burst.style.left = `${e.clientX}px`; burst.style.top = `${e.clientY}px`; document.body.appendChild(burst); setTimeout(() => { burst.remove(); }, 450); }); const canvas = document.getElementById('spidey-canvas'); const ctx = canvas.getContext('2d'); let particles = []; function resizeCanvas() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; initParticles(); } window.addEventListener('resize', resizeCanvas); class WebNode { constructor() { this.x = Math.random() * canvas.width; this.y = Math.random() * canvas.height; this.vx = (Math.random() - 0.5) * 0.6; this.vy = (Math.random() - 0.5) * 0.6; this.color = Math.random() > 0.4 ? 'rgba(255, 30, 60, ' : 'rgba(0, 150, 255, '; this.baseAlpha = Math.random() * 0.3 + 0.15; this.radius = Math.random() * 1.5 + 1; } draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2); ctx.fillStyle = this.color + this.baseAlpha + ')'; ctx.fill(); } update() { this.x += this.vx; this.y += this.vy; if (this.x < 0 || this.x > canvas.width) this.vx *= -1; if (this.y < 0 || this.y > canvas.height) this.vy *= -1; const dx = mouseX - this.x; const dy = mouseY - this.y; const dist = Math.sqrt(dx * dx + dy * dy); const maxDist = 140; if (dist < maxDist) { const force = (maxDist - dist) / maxDist; this.x -= (dx / dist) * force * 3; this.y -= (dy / dist) * force * 3; } this.draw(); } } function initParticles() { particles = []; const count = Math.floor((canvas.width * canvas.height) / 11000); for (let i = 0; i < count; i++) { particles.push(new WebNode()); } } function drawBackgroundWeb() { const centerX = canvas.width / 2; const centerY = canvas.height / 2; const maxRadius = Math.max(canvas.width, canvas.height); ctx.strokeStyle = 'rgba(255, 20, 50, 0.03)'; ctx.lineWidth = 1; for (let i = 0; i < 12; i++) { const angle = (Math.PI * 2 / 12) * i; ctx.beginPath(); ctx.moveTo(centerX, centerY); ctx.lineTo(centerX + Math.cos(angle) * maxRadius, centerY + Math.sin(angle) * maxRadius); ctx.stroke(); } for (let r = 80; r < maxRadius; r += 110) { ctx.beginPath(); ctx.arc(centerX, centerY, r, 0, Math.PI * 2); ctx.stroke(); } } function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); drawBackgroundWeb(); for (let a = 0; a < particles.length; a++) { for (let b = a + 1; b < particles.length; b++) { const dx = particles[a].x - particles[b].x; const dy = particles[a].y - particles[b].y; const dist = Math.sqrt(dx * dx + dy * dy); if (dist < 110) { ctx.beginPath(); ctx.strokeStyle = particles[a].color + (0.22 * (1 - dist / 110)) + ')'; ctx.lineWidth = 0.5; ctx.moveTo(particles[a].x, particles[a].y); ctx.lineTo(particles[b].x, particles[b].y); ctx.stroke(); } } } particles.forEach(p => p.update()); requestAnimationFrame(animate); } resizeCanvas(); animate();