← back to Model Arena
data/artifacts/0cb3fc06b069/qwen3-14b.html
143 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Particle Word</title>
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
background: #000;
height: 100%;
width: 100%;
font-family: 'Arial', sans-serif;
}
#word {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #fff;
font-size: 48px;
pointer-events: none;
text-transform: uppercase;
text-align: center;
}
#controls {
position: absolute;
top: 20px;
left: 50%;
transform: translateX(-50%);
color: #fff;
font-size: 18px;
}
</style>
</head>
<body>
<div id="word">TYPE HERE</div>
<div id="controls">Type a word to see particles form it</div>
<canvas id="canvas"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let width, height;
let particles = [];
let targetWord = 'TYPE HERE';
let isHovering = false;
function resize() {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
}
window.addEventListener('resize', resize);
resize();
function createParticles(word, count = 2000) {
particles = [];
const chars = word.split('');
const totalChars = chars.length;
for (let i = 0; i < count; i++) {
const charIndex = Math.floor(i / (count / totalChars));
const char = chars[charIndex % totalChars];
const angle = (Math.random() * Math.PI * 2);
const radius = Math.random() * 150 + 100;
const x = width / 2 + Math.cos(angle) * radius;
const y = height / 2 + Math.sin(angle) * radius;
const size = Math.random() * 2 + 1;
const speed = Math.random() * 0.5 + 0.2;
particles.push({
x,
y,
targetX: width / 2 + (char.charCodeAt(0) - 65) * 30,
targetY: height / 2 + (Math.floor(i / totalChars)) * 30,
size,
speed,
vx: (Math.random() - 0.5) * 2,
vy: (Math.random() - 0.5) * 2,
char: char
});
}
}
function updateParticles() {
for (let p of particles) {
const dx = p.targetX - p.x;
const dy = p.targetY - p.y;
const dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 2) {
p.x = p.targetX;
p.y = p.targetY;
} else {
const angle = Math.atan2(dy, dx);
p.x += Math.cos(angle) * p.speed;
p.y += Math.sin(angle) * p.speed;
}
if (isHovering) {
const nx = (Math.random() - 0.5) * 10;
const ny = (Math.random() - 0.5) * 10;
p.x += nx;
p.y += ny;
}
}
}
function drawParticles() {
ctx.clearRect(0, 0, width, height);
ctx.fillStyle = '#00ffcc';
for (let p of particles) {
ctx.beginPath();
ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
ctx.fill();
}
}
function animate() {
updateParticles();
drawParticles();
requestAnimationFrame(animate);
}
function resetParticles() {
createParticles(targetWord);
}
window.addEventListener('mousemove', () => {
isHovering = true;
setTimeout(() => {
isHovering = false;
}, 500);
});
window.addEventListener('keydown', (e) => {
if (e.key.length === 1 && e.key.match(/[a-zA-Z]/)) {
targetWord = e.key.toUpperCase();
resetParticles();
}
});
createParticles(targetWord);
animate();
</script>
</body>
</html>