← back to Model Arena
data/artifacts/097db196034e/qwen3-14b.html
173 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>AI Agent Constellation</title>
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #000;
width: 100%;
height: 100%;
}
canvas {
display: block;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let width, height;
let nodes = [];
let edges = [];
let frame = 0;
let hoverNode = null;
function resize() {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
}
window.addEventListener('resize', resize);
resize();
class Node {
constructor(id) {
this.id = id;
this.x = Math.random() * width;
this.y = Math.random() * height;
this.vx = 0;
this.vy = 0;
this.radius = 10 + Math.random() * 6;
this.color = `hsl(${Math.random() * 360}, 100%, 60%)`;
this.neighbors = [];
}
update() {
this.x += this.vx;
this.y += this.vy;
this.vx *= 0.9;
this.vy *= 0.9;
if (this.x < 0) this.x = 0, this.vx *= -1;
if (this.x > width) this.x = width, this.vx *= -1;
if (this.y < 0) this.y = 0, this.vy *= -1;
if (this.y > height) this.y = height, this.vy *= -1;
}
draw(ctx, hover) {
const isHovered = hover && hover.id === this.id;
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = isHovered ? `hsl(${Math.random() * 360}, 100%, 70%)` : this.color;
ctx.fill();
ctx.strokeStyle = isHovered ? 'cyan' : 'rgba(0, 255, 255, 0.2)';
ctx.lineWidth = 2;
ctx.stroke();
}
}
class Edge {
constructor(from, to) {
this.from = from;
this.to = to;
this.pulse = 0;
this.maxPulse = 10;
this.color = `hsla(180, 100%, 60%, ${0.3 + Math.random() * 0.3})`;
}
update() {
this.pulse += 0.5;
if (this.pulse > this.maxPulse) this.pulse = 0;
}
draw(ctx) {
const dx = this.to.x - this.from.x;
const dy = this.to.y - this.from.y;
const dist = Math.sqrt(dx * dx + dy * dy);
const t = this.pulse / this.maxPulse;
const alpha = 0.3 + t * 0.7;
const opacity = alpha;
ctx.strokeStyle = `hsla(180, 100%, 60%, ${opacity})`;
ctx.lineWidth = 2 + Math.sin(t * Math.PI) * 2;
ctx.beginPath();
ctx.moveTo(this.from.x, this.from.y);
ctx.lineTo(this.to.x, this.to.y);
ctx.stroke();
}
}
function createNodes(count) {
nodes = [];
for (let i = 0; i < count; i++) {
nodes.push(new Node(i));
}
return nodes;
}
function connectNodes(nodes, connectionRate = 0.1) {
edges = [];
for (let i = 0; i < nodes.length; i++) {
for (let j = i + 1; j < nodes.length; j++) {
if (Math.random() < connectionRate) {
edges.push(new Edge(nodes[i], nodes[j]));
nodes[i].neighbors.push(nodes[j]);
nodes[j].neighbors.push(nodes[i]);
}
}
}
}
function update() {
for (let node of nodes) {
node.update();
}
for (let edge of edges) {
edge.update();
}
}
function draw() {
ctx.clearRect(0, 0, width, height);
for (let node of nodes) {
node.draw(ctx, hoverNode);
}
for (let edge of edges) {
edge.draw(ctx);
}
}
function animate() {
update();
draw();
frame++;
requestAnimationFrame(animate);
}
function handleMouseMove(e) {
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
hoverNode = null;
for (let node of nodes) {
const dx = node.x - x;
const dy = node.y - y;
const dist = Math.sqrt(dx * dx + dy * dy);
if (dist < node.radius * 2) {
hoverNode = node;
break;
}
}
}
window.addEventListener('mousemove', handleMouseMove);
createNodes(20);
connectNodes(nodes);
animate();
</script>
</body>
</html>