A Pen by Hasan ALDOY on CodePen.
Totally inspired by https://codepen.io/lekzd
A Pen by Hasan ALDOY on CodePen.
Totally inspired by https://codepen.io/lekzd
<canvas id="c"> |
const c = document.querySelector('#c'); | |
const ctx = c.getContext('2d'); | |
const dpr = Math.min(2, window.devicePixelRatio); | |
c.width = window.innerWidth * dpr; | |
c.height = window.innerHeight * dpr; | |
c.style.imageRendering = 'pixelated'; | |
c.style.width = '100vw'; | |
c.style.height = '100vh'; | |
const palette = [ | |
'#f72585', | |
'#b5179e', | |
'#7209b7', | |
'#560bad', | |
'#480ca8', | |
'#3a0ca3', | |
'#3f37c9', | |
'#4361ee', | |
'#4895ef', | |
'#4cc9f0', | |
'#ffffff80', | |
] | |
const points = [] | |
const createPoint = (x, y, color) => ({ | |
x, y, color | |
}) | |
for (let i = 0; i < 250; i++) { | |
points.push(createPoint( | |
Math.random() * c.width, | |
Math.random() * c.height, | |
Math.floor(Math.random() * palette.length) % palette.length | |
)) | |
} | |
const mouse = { x: c.width / 2, y: c.height / 2 }; | |
window.addEventListener("mousemove", (e) => { | |
mouse.x = e.clientX; | |
mouse.y = e.clientY; | |
}); | |
function getAngle(cx, cy, ex, ey) { | |
const dy = ey - cy; | |
const dx = ex - cx; | |
const theta = Math.atan2(dy, dx); | |
return theta; | |
} | |
ctx.filter = 'blur(1px)'; | |
ctx.fillStyle = 'black'; | |
ctx.fillRect(0, 0, c.width, c.height); | |
const drawWind = (time) => { | |
ctx.fillStyle = 'rgba(0, 0, 0, 0.2)'; | |
ctx.fillRect(0, 0, c.width, c.height); | |
const cx = c.width / 2; | |
const cy = c.height / 2; | |
for (let i = 0; i < points.length; i++) { | |
const point = points[i]; | |
const p = i / points.length; | |
const mx = (mouse.x * dpr) + Math.cos(p * Math.PI * 2) * 25; | |
const my = (mouse.y * dpr) + Math.sin(p * Math.PI * 2) * 25; | |
const mouseAngle = getAngle(point.x, point.y, mx, my) - Math.PI / 2; | |
// Increased animation speed by 20% | |
const angle = mouseAngle + (Math.sin((i * 50 + time) / 1600) * i / 500); | |
ctx.fillStyle = palette[point.color]; | |
ctx.fillStyle = palette[Math.floor((angle * 2) + (i / 15)) % palette.length] + '40'; | |
for (let p = 4; p > 0; p-=0.75) { | |
ctx.beginPath(); | |
ctx.arc(point.x, point.y, p, 0, Math.PI * 2); | |
ctx.fill(); | |
// Increased movement speed by 20% | |
point.x = (point.x + Math.cos(angle) * 1.8); | |
if (point.x > c.width) { | |
point.x = 0; | |
} else if (point.x < 0) { | |
point.x = c.width; | |
} | |
point.y = (point.y + Math.sin(angle) * 1.8); | |
if (point.y > c.height) { | |
point.y = 0; | |
} else if (point.y < 0) { | |
point.y = c.height; | |
} | |
} | |
// Adjusted bounce back speed | |
point.x = (point.x - Math.cos(angle) * 12); | |
if (point.x > c.width) { | |
point.x = 0; | |
} else if (point.x < 0) { | |
point.x = c.width; | |
} | |
point.y = (point.y - Math.sin(angle) * 12); | |
if (point.y > c.height) { | |
point.y = 0; | |
} else if (point.y < 0) { | |
point.y = c.height; | |
} | |
} | |
} | |
const animate = (time) => { | |
requestAnimationFrame(animate); | |
drawWind(time); | |
} | |
window.addEventListener('resize', () => { | |
c.width = window.innerWidth * dpr; | |
c.height = window.innerHeight * dpr; | |
ctx.filter = 'blur(1px)'; | |
}) | |
animate(0); |
html, body { | |
margin: 0; | |
padding: 0; | |
overflow: hidden; | |
} |