← 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>