About this snippet

Create a complex interactive physics node graph. We built this using HTML5 Canvas, so the nodes bounce and react to your mouse, which gives you an incredibly stunning visualization.

Size
3.5 KB
Uses
HTML, CSS, JavaScript
Loads
Nothing external
Views
181
<div class="graph-wrapper">
  <canvas id="node-canvas"></canvas>
  <div class="graph-overlay">
    <h2>Neural Network</h2>
    <p>Move your mouse to interact with the physics engine.</p>
  </div>
</div>
*, *::before, *::after {
  box-sizing: border-box;
}

body {
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  margin: 0;
  background: #020617;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

.graph-wrapper {
  position: relative;
  width: 100%;
  max-width: 1000px;
  height: 600px;
  border-radius: 24px;
  overflow: hidden;
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
  background: linear-gradient(135deg, #0f172a, #1e1b4b);
  border: 1px solid rgba(255, 255, 255, 0.1);
}

#node-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
}

.graph-overlay {
  position: absolute;
  bottom: 40px;
  left: 40px;
  z-index: 2;
  pointer-events: none;
  background: rgba(15, 23, 42, 0.6);
  backdrop-filter: blur(12px);
  padding: 24px 30px;
  border-radius: 16px;
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.graph-overlay h2 {
  color: #f8fafc;
  margin: 0 0 8px 0;
  font-size: 2rem;
  letter-spacing: -0.5px;
}

.graph-overlay p {
  color: #94a3b8;
  margin: 0;
  font-size: 1.125rem;
}
const canvas = document.getElementById("node-canvas");
const ctx = canvas.getContext("2d");

const width = 1000;
const height = 600;
canvas.width = width;
canvas.height = height;

const nodes = new Array();
const numNodes = 60;

for (let i = 0; i < numNodes; i++) {
  const node = new Object();
  node.x = Math.random() * width;
  node.y = Math.random() * height;
  node.vx = (Math.random() - 0.5) * 1.5;
  node.vy = (Math.random() - 0.5) * 1.5;
  node.radius = Math.random() * 2 + 2;
  nodes.push(node);
}

const mouse = new Object();
mouse.x = width / 2;
mouse.y = height / 2;
mouse.radius = 120;

canvas.addEventListener("mousemove", function(e) {
  const rect = canvas.getBoundingClientRect();
  mouse.x = (e.clientX - rect.left) * (width / rect.width);
  mouse.y = (e.clientY - rect.top) * (height / rect.height);
});

function animate() {
  ctx.clearRect(0, 0, width, height);
  
  nodes.forEach(function(node) {
    node.x += node.vx;
    node.y += node.vy;
    
    if (node.x < 0 || node.x > width) node.vx *= -1;
    if (node.y < 0 || node.y > height) node.vy *= -1;
    
    const dxMouse = mouse.x - node.x;
    const dyMouse = mouse.y - node.y;
    const distanceMouse = Math.sqrt(dxMouse * dxMouse + dyMouse * dyMouse);
    
    if (distanceMouse < mouse.radius) {
      const force = (mouse.radius - distanceMouse) / mouse.radius;
      node.vx -= (dxMouse / distanceMouse) * force * 0.5;
      node.vy -= (dyMouse / distanceMouse) * force * 0.5;
    }
    
    node.vx *= 0.99;
    node.vy *= 0.99;
    
    ctx.beginPath();
    ctx.arc(node.x, node.y, node.radius, 0, Math.PI * 2);
    ctx.fillStyle = "#3b82f6";
    ctx.fill();
  });
  
  nodes.forEach(function(nodeA) {
    nodes.forEach(function(nodeB) {
      const dx = nodeA.x - nodeB.x;
      const dy = nodeA.y - nodeB.y;
      const dist = Math.sqrt(dx * dx + dy * dy);
      
      if (dist > 0 && dist < 120) {
        ctx.beginPath();
        ctx.moveTo(nodeA.x, nodeA.y);
        ctx.lineTo(nodeB.x, nodeB.y);
        const opacity = 1 - (dist / 120);
        ctx.strokeStyle = "rgba(139, 92, 246, " + opacity + ")";
        ctx.lineWidth = 1;
        ctx.stroke();
      }
    });
  });
  
  window.requestAnimationFrame(animate);
}

animate();
Esc
↑↓ moveEnter select

Start from a template

Open an .html file, or HTML, CSS, JS, Markdown, Less or TypeScript files. You can also drop them here. Styles and scripts go into their panes.

Share

Source

Keyboard shortcuts

Save