Пример:
Курсором мышки можно
расталкивать частицы
расталкивать частицы
HTML:
1 2 3 4 |
<div class="particles"> <canvas></canvas> <div>Текст в центре блока</div> </div> |
CSS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
.particles { position: relative; display: flex; justify-content: center; align-items: center; } .particles div { position: absolute; text-align: center; font-size: 30px; font-weight: bold; line-height: 40px; color: #FFF; font-family: 'Roboto', sans-serif; text-transform: uppercase; animation: neon-1 .1s ease-in-out infinite alternate; } @keyframes neon-1 { from { text-shadow: 0 0 6px rgba(202, 228, 225, 0.92), 0 0 30px rgba(202, 228, 225, 0.34), 0 0 12px rgba(191, 226, 255, 0.52), 0 0 21px rgba(191, 226, 255, 0.92), 0 0 34px rgba(191, 226, 255, 0.78), 0 0 54px rgba(191, 226, 255, 0.92); } to { text-shadow: 0 0 6px rgba(202, 228, 225, 0.98), 0 0 30px rgba(202, 228, 225, 0.42), 0 0 12px rgba(191, 226, 255, 0.58), 0 0 22px rgba(191, 226, 255, 0.84), 0 0 38px rgba(191, 226, 255, 0.88), 0 0 60px #FFF; } } .particles canvas { width: 100%; height: 500px; background-image: url('background.jpg'); background-position: center center; background-size: cover; } |
JS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
const canvas = document.querySelector('canvas'); const ctx = canvas.getContext('2d'); const RESOLUTION = 1; let w = canvas.width = canvas.offsetWidth * RESOLUTION; let h = canvas.height = canvas.offsetHeight * RESOLUTION; const PARTICLE_COUNT = 400; const CONNECT_DISTANCE = w * 0.06; const FORCE_DISTANCE = w * 0.2; const r = (n = 1) => Math.random() * n; const PI = Math.PI; const TAU = PI * 2; let time = new Date; const lerp = (start, end, amt) => { return (1-amt)*start+amt*end }; const distance = (x1, y1, x2, y2) => { const a = x1 - x2; const b = y1 - y2; return Math.sqrt( a*a + b*b ); }; const angle = (cx, cy, ex, ey) => { return Math.atan2(ey - cy, ex - cx); }; const particlePrototype = () => ({ x: w * 0.5 + (Math.cos(r(TAU)) * r(w* 0.5)), y: h * 0.5 + (Math.sin(r(TAU)) * r(h* 0.5)), angle: r(TAU), speed: r(0.15), normalSpeed: r(0.15), oscAmplitudeX: r(2), oscSpeedX: 0.001 + r(0.008), oscAmplitudeY: r(2), oscSpeedY: 0.001 + (r(0.008)), connectDistance: r(CONNECT_DISTANCE), color: { r: Math.round(200 + r(55)), g: Math.round(150 + r(105)), b: Math.round(200 + r(55)) } }); const particles = (new Array(PARTICLE_COUNT)) .fill({}) .map(particlePrototype); const update = () => { particles.forEach(p1 => { p1.x += (Math.cos(p1.angle) + (Math.cos(time * p1.oscSpeedX) * p1.oscAmplitudeX)) * p1.speed; p1.y += (Math.sin(p1.angle) + (Math.cos(time * p1.oscSpeedY) * p1.oscAmplitudeY)) * p1.speed; p1.speed = lerp(p1.speed, p1.normalSpeed * RESOLUTION, 0.1); if (p1.x > w || p1.x < 0) { p1.angle = PI - p1.angle; } if (p1.y > h || p1.y < 0) { p1.angle = -p1.angle; } if (r() < 0.005) p1.oscAmplitudeX = r(2); if (r() < 0.005) p1.oscSpeedX = 0.001 + (r(0.008)); if (r() < 0.005) p1.oscAmplitudeY = r(2); if (r() < 0.005) p1.oscSpeedY = 0.001 + r(0.008); p1.x = Math.max(-0.01,Math.min(p1.x, w + 0.01)); p1.y = Math.max(-0.01,Math.min(p1.y, h + 0.01)); }); }; const render = () => { ctx.clearRect(0,0,w,h); particles.map(p1 => { particles .filter(p2 => { if (p1 == p2) return false; if (distance(p1.x, p1.y, p2.x, p2.y) > p1.connectDistance) return false; return true; }) .map(p2 => { const dist = distance(p1.x, p1.y, p2.x, p2.y); p1.speed = lerp(p1.speed, p1.speed + (0.05 / p1.connectDistance * dist), 0.2); return { p1, p2, color: p1.color, opacity: Math.floor(100 / p1.connectDistance * (p1.connectDistance - dist)) / 100 }; }) .forEach((line, i) => { const colorSwing = Math.sin(time * (line.p1.oscSpeedX)); ctx.beginPath(); ctx.globalAlpha = line.opacity; ctx.moveTo(line.p1.x, line.p1.y); ctx.lineTo(line.p2.x, line.p2.y); ctx.strokeStyle = `rgb( ${Math.floor(line.color.r * colorSwing)}, ${Math.floor((line.color.g * 0.5) + ((line.color.g * 0.5) * colorSwing))}, ${line.color.b} )` ctx.lineWidth = (line.opacity * 4); ctx.stroke(); ctx.closePath(); }); }); }; const loop = () => { time = new Date; update(); render(); window.requestAnimationFrame(loop); }; loop(); window.addEventListener('mousemove', e => { const mouseX = (e.clientX - canvas.getBoundingClientRect().left) * RESOLUTION; const mouseY = (e.clientY - canvas.getBoundingClientRect().top) * RESOLUTION; particles.forEach(p => { const dist = distance(mouseX, mouseY, p.x, p.y); if (dist < FORCE_DISTANCE && dist > 0) { p.angle = angle(mouseX, mouseY, p.x, p.y) const force = (FORCE_DISTANCE - dist) * 0.1; p.speed = lerp(p.speed, force, 0.2); } }); }); |
За основу взят скрипт, найденный на codepen.io у пользователя Per Byhring
Автор фотографии geralt
Вот всё хорошо, поставил и работает, как цвета менять? я выставляю цвета, но они какие хочешь, но не те))) можно как то проще сделать?)) а так спасибо, всё работает)
Спасибо бро! Сделал на своем сайте аналог!