<canvas></canvas>
body {
margin: 0;
overflow: hidden;
}
canvas {
image-rendering: pixelated;
}
const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
const size = 25;
const speed = 2;
const color = '#2e246d';
let entities = [];
const update = () => {
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = color;
context.strokeStyle = color;
for (const entity of entities) {
context.save();
context.translate(entity.position.x, entity.position.y);
context.rotate(entity.angle);
context.beginPath();
context.rect(size / -2, size / -2, size, size);
context.closePath();
if (entity.isFilled) {
context.fill();
} else {
context.stroke();
}
context.restore();
entity.position.x += entity.velocity.x;
entity.position.y += entity.velocity.y;
if (entity.position.x < size * -2) {
entity.position.x = canvas.width + size * 2;
}
if (entity.position.x > canvas.width + size * 2) {
entity.position.x = size * -2;
}
if (entity.position.y < size * -2) {
entity.position.y = canvas.height + size * 2;
}
if (entity.position.y > canvas.height + size * 2) {
entity.position.y = size * -2;
}
}
requestAnimationFrame(update);
};
const generate = () => {
const count = Math.floor((canvas.width * canvas.height) ** (1 / 3.5));
entities = [];
for (let index = 0; index < count; index++) {
entities.push({
position: {
x: Math.random() * canvas.width,
y: Math.random() * canvas.height
},
velocity: {
x: (Math.random() - 0.5) * 2 * speed,
y: (Math.random() - 0.5) * 2 * speed
},
angle: Math.random() * Math.PI * 2,
isFilled: Math.random() < 0.1
});
}
};
const resize = () => {
[canvas.width, canvas.height] = [innerWidth, innerHeight];
generate();
};
const init = () => {
resize();
requestAnimationFrame(update);
};
window.addEventListener('load', init);
window.addEventListener('resize', resize);
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.