Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div>
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><g fill="none" fill-rule="evenodd" stroke="#666" stroke-linecap="round" stroke-linejoin="round" transform="translate(1 1)"><circle cx="5" cy="5" r="5"/><path d="M5 2v3l2 1"/></g></svg>
<canvas id="particles" width="100" height="100"></canvas>
</div>
<script src="script.js" type="module"></script>
</body>
</html>
const canvas = document.getElementById('particles')
const ctx = canvas.getContext('2d')
const w = canvas.width
const h = canvas.height
const cX = w / 2
const cY = h / 2
const dur = 500
const dis = 30
const colors = ['red', 'blue', 'green', 'yellow', 'orange']
const count = 50
const max_radius = 2
let t = undefined
let start = undefined
const circles = []
for (let i = 0; i < 50; i++) {
circles.push({angle: Math.random() * Math.PI * 2, r: Math.random() * max_radius, d: Math.random() * dis, c: colors[Math.floor(Math.random() * colors.length)]})
}
const loop = (stamp) => {
if (start === undefined) start = stamp
if (t === undefined) t = start
const e = stamp - t
t = stamp - start
ctx.clearRect(0, 0, w, h)
ctx.globalAlpha = 1 - (t / dur)
for (const circle of circles) {
ctx.fillStyle = circle.c
ctx.beginPath()
ctx.arc(cX + Math.cos(circle.angle) * (10 + (t / dur) * circle.d), cY + Math.sin(circle.angle) * (10 + (t / dur) * circle.d), circle.r, 0, 2 * Math.PI)
ctx.fill()
}
if (stamp - start < dur) {
requestAnimationFrame(loop)
} else {
ctx.clearRect(0, 0, w, h)
}
}
requestAnimationFrame(loop)
div {
margin: 100px;
position: relative;
}
svg {
left: 0;
top: 0;
z-index: 2;
position: absolute;
}
canvas {
left: 0;
position: absolute;
transform: translate(calc(-50% + 6px), calc(-50% + 6px));
top: 0;
z-index: 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment