<!DOCTYPE html>
<html>
<head>
<title>Kinetic Typography Swarm</title>
<style>
body {
background-color: #1a1a1a;
color: white;
margin: 0;
overflow: hidden;
font-family: 'Courier New', Courier, monospace;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
height: 100vh;
}
canvas {
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
h1 {
z-index: 2;
font-size: 4rem;
color: #fff;
}
</style>
</head>
<body>
<h1>KINETIC</h1>
<canvas id="swarmCanvas"></canvas>
<script>
const canvas = document.getElementById('swarmCanvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let particles = [];
const chars = ['$', '#', '@', '&', '%', '}', '{', ']', '['];
const mouse = {
x: undefined,
y: undefined,
};
window.addEventListener('mousemove', (event) => {
mouse.x = event.clientX;
mouse.y = event.clientY;
});
class Particle {
constructor(x, y, char, color, size) {
this.x = x;
this.y = y;
this.char = char;
this.color = color;
this.size = size;
this.baseX = this.x;
this.baseY = this.y;
this.density = (Math.random() * 30) + 1;
}
draw() {
ctx.fillStyle = this.color;
ctx.font = this.size + 'px Courier New';
ctx.fillText(this.char, this.x, this.y);
}
update() {
let dx = mouse.x - this.x;
let dy = mouse.y - this.y;
let distance = Math.sqrt(dx * dx + dy * dy);
let forceDirectionX = dx / distance;
let forceDirectionY = dy / distance;
let maxDistance = 200;
let force = (maxDistance - distance) / maxDistance;
if (distance < maxDistance) {
this.x -= forceDirectionX * this.density * 0.5;
this.y -= forceDirectionY * this.density * 0.5;
} else {
if (this.x !== this.baseX) {
let dx = this.x - this.baseX;
this.x -= dx / 10;
}
if (this.y !== this.baseY) {
let dy = this.y - this.baseY;
this.y -= dy / 10;
}
}
}
}
function init() {
particles = [];
for (let i = 0; i < 1000; i++) {
let x = Math.random() * canvas.width;
let y = Math.random() * canvas.height;
let char = chars[Math.floor(Math.random() * chars.length)];
let color = 'white';
let size = Math.random() * 15 + 5;
particles.push(new Particle(x, y, char, color, size));
}
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < particles.length; i++) {
particles[i].update();
particles[i].draw();
}
requestAnimationFrame(animate);
}
init();
animate();
window.addEventListener('resize', function(){
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
init();
});
</script>
</body>
</html>
<h1>KINETIC</h1>
<canvas id="swarmCanvas"></canvas>
body {
background-color: #1a1a1a;
color: white;
margin: 0;
overflow: hidden;
font-family: 'Courier New', Courier, monospace;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
height: 100vh;
}
canvas {
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
h1 {
z-index: 2;
font-size: 4rem;
color: #fff;
}
const canvas = document.getElementById('swarmCanvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let particles = [];
const chars = ['$', '#', '@', '&', '%', '}', '{', ']', '['];
const mouse = {
x: undefined,
y: undefined,
};
window.addEventListener('mousemove', (event) => {
mouse.x = event.clientX;
mouse.y = event.clientY;
});
class Particle {
constructor(x, y, char, color, size) {
this.x = x;
this.y = y;
this.char = char;
this.color = color;
this.size = size;
this.baseX = this.x;
this.baseY = this.y;
this.density = (Math.random() * 30) + 1;
}
draw() {
ctx.fillStyle = this.color;
ctx.font = this.size + 'px Courier New';
ctx.fillText(this.char, this.x, this.y);
}
update() {
let dx = mouse.x - this.x;
let dy = mouse.y - this.y;
let distance = Math.sqrt(dx * dx + dy * dy);
let forceDirectionX = dx / distance;
let forceDirectionY = dy / distance;
let maxDistance = 200;
let force = (maxDistance - distance) / maxDistance;
if (distance < maxDistance) {
this.x -= forceDirectionX * this.density * 0.5;
this.y -= forceDirectionY * this.density * 0.5;
} else {
if (this.x !== this.baseX) {
let dx = this.x - this.baseX;
this.x -= dx / 10;
}
if (this.y !== this.baseY) {
let dy = this.y - this.baseY;
this.y -= dy / 10;
}
}
}
}
function init() {
particles = [];
for (let i = 0; i < 1000; i++) {
let x = Math.random() * canvas.width;
let y = Math.random() * canvas.height;
let char = chars[Math.floor(Math.random() * chars.length)];
let color = 'white';
let size = Math.random() * 15 + 5;
particles.push(new Particle(x, y, char, color, size));
}
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < particles.length; i++) {
particles[i].update();
particles[i].draw();
}
requestAnimationFrame(animate);
}
init();
animate();
window.addEventListener('resize', function(){
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
init();
});