const canvas = document.getElementById('particleCanvas'); const ctx = canvas.getContext('2d'); canvas.width = window.innerWidth; canvas.height = window.innerHeight; const particles = []; const mouse = { x: null, y: null, lastMoveTime: 0 }; const text = "SINTEZ.SPACE"; const particleSize = 2; const mouseRadius = 100; const returnSpeed = 0.01; // Скорость возврата частиц let fontSize = Math.min(canvas.width / 10, 120); // Размер шрифта зависит от ширины экрана // Функция создания частицы function createParticle(x, y, color) { return { x: Math.random() * canvas.width, y: Math.random() * canvas.height, targetX: x, targetY: y, vx: 0, vy: 0, color: color, size: particleSize }; } // Генерация частиц из текста function generateParticlesFromText() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "white"; ctx.font = `${fontSize}px 'Unbounded'`; ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.fillText(text, canvas.width / 2, canvas.height / 2); const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data; particles.length = 0; // Очищаем массив частиц for (let y = 0; y < canvas.height; y += 5) { for (let x = 0; x < canvas.width; x += 5) { const index = (y * canvas.width + x) * 4; if (imageData[index] > 128) { const color = `rgba(${imageData[index]}, ${imageData[index + 1]}, ${imageData[index + 2]}, 1)`; particles.push(createParticle(x, y, color)); } } } ctx.clearRect(0, 0, canvas.width, canvas.height); } // Обновление частиц function updateParticles() { const now = Date.now(); const mouseStill = now - mouse.lastMoveTime > 200; // Мышь не двигается более 200 мс particles.forEach(particle => { const dx = particle.x - mouse.x; const dy = particle.y - mouse.y; const distance = Math.sqrt(dx * dx + dy * dy); if (distance < mouseRadius && !mouseStill && mouse.x && mouse.y) { // Отталкиваем частицы от мыши const angle = Math.atan2(dy, dx); particle.vx += Math.cos(angle) * 3; particle.vy += Math.sin(angle) * 3; } else { // Частицы возвращаются к своим целям плавно const tx = particle.targetX - particle.x; const ty = particle.targetY - particle.y; particle.vx += tx * returnSpeed; particle.vy += ty * returnSpeed; } // Обновляем позиции particle.x += particle.vx; particle.y += particle.vy; // Плавное замедление частиц particle.vx *= 0.9; particle.vy *= 0.9; }); } // Рисование частиц function drawParticles() { ctx.clearRect(0, 0, canvas.width, canvas.height); particles.forEach(particle => { ctx.beginPath(); ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2); ctx.fillStyle = particle.color; ctx.fill(); }); } // Анимация function animate() { updateParticles(); drawParticles(); requestAnimationFrame(animate); } // Событие мыши canvas.addEventListener("mousemove", (event) => { mouse.x = event.clientX; mouse.y = event.clientY; mouse.lastMoveTime = Date.now(); // Обновляем время последнего движения мыши }); canvas.addEventListener("mouseleave", () => { mouse.x = null; mouse.y = null; }); // Адаптивность страницы window.addEventListener("resize", () => { canvas.width = window.innerWidth; canvas.height = window.innerHeight; fontSize = Math.min(canvas.width / 10, 120); // Обновляем размер шрифта generateParticlesFromText(); }); // Инициализация generateParticlesFromText(); animate();