跳到正文

粒子连线背景

Particle Network Background

中级网页

首屏背后一片缓缓漂浮的光点,离得近的光点之间连着淡淡的线,像星座或神经网络;鼠标移过去,附近的光点会连向鼠标。科技、AI 类产品的首屏常用,标题和按钮叠在上面照常可点。

你可能会说:「首页背景能不能做成那种光点慢慢飘、离得近就连线的科技感效果,鼠标靠近还会连过来?」

效果预览

正在加载演示…

怎么做

  1. 1

    画布垫在内容下面

    光点画在 canvas 上,绝对定位铺满首屏;标题和按钮仍然是普通 HTML,叠在画布上面,这样能正常点击、被读屏读到。画布本身是装饰,加 aria-hidden。

    查看代码html
    <section class="hero">
      <canvas class="hero__particles" aria-hidden="true"></canvas>
      <div class="hero__content">
        <h1>连接每一个想法</h1>
        <a class="hero__cta" href="/start">开始探索</a>
      </div>
    </section>
    
    <style>
      .hero { position: relative; min-height: 70vh; background: #020617; }
      .hero__particles { position: absolute; inset: 0; width: 100%; height: 100%; }
      .hero__content { position: relative; }
    </style>
  2. 2

    按设备像素比设置画布,生成光点

    画布的实际像素要乘上 devicePixelRatio,否则高分屏上发糊。光点数量按面积算,屏幕越大点越多,密度保持一致;窗口大小变化时重新设置。

    查看代码js
    const canvas = document.querySelector('.hero__particles');
    const ctx = canvas.getContext('2d');
    const LINK = 110;      // 连线距离
    const DENSITY = 2;     // 每 1 万平方像素几个点
    let width, height, dots = [];
    let mouse = null;
    
    function resize() {
      const dpr = window.devicePixelRatio || 1;
      width = canvas.clientWidth;
      height = canvas.clientHeight;
      canvas.width = width * dpr;
      canvas.height = height * dpr;
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
      const count = Math.round((width * height) / 10000 * DENSITY);
      dots = Array.from({ length: count }, () => ({
        x: Math.random() * width, y: Math.random() * height,
        vx: (Math.random() - 0.5) * 0.4, vy: (Math.random() - 0.5) * 0.4,
      }));
    }
    new ResizeObserver(resize).observe(canvas);
    canvas.parentElement.addEventListener('pointermove', (e) => {
      const box = canvas.getBoundingClientRect();
      mouse = { x: e.clientX - box.left, y: e.clientY - box.top };
    });
    canvas.parentElement.addEventListener('pointerleave', () => { mouse = null; });
  3. 3

    每帧移动、连线、画点

    每一帧:光点按速度移动,碰到边缘反弹;两两算距离,近的连一条线,越近越不透明;鼠标当成一个不动的点参与连线。页面切到后台时浏览器会自动暂停 requestAnimationFrame。点多了两两比较会变慢,手机上要把密度调低。开启减少动效时只画一帧静止画面。

    查看代码js
    function draw() {
      ctx.clearRect(0, 0, width, height);
      const points = mouse ? [...dots, mouse] : dots;
      for (let i = 0; i < points.length; i++) {
        for (let j = i + 1; j < points.length; j++) {
          const d = Math.hypot(points[i].x - points[j].x, points[i].y - points[j].y);
          if (d > LINK) continue;
          ctx.strokeStyle = `rgba(165, 180, 252, ${(1 - d / LINK) * 0.5})`;
          ctx.beginPath();
          ctx.moveTo(points[i].x, points[i].y);
          ctx.lineTo(points[j].x, points[j].y);
          ctx.stroke();
        }
      }
      ctx.fillStyle = 'rgba(224, 231, 255, 0.9)';
      dots.forEach((p) => { ctx.beginPath(); ctx.arc(p.x, p.y, 1.6, 0, Math.PI * 2); ctx.fill(); });
    }
    
    function tick() {
      dots.forEach((p) => {
        p.x += p.vx; p.y += p.vy;
        if (p.x < 0 || p.x > width) p.vx *= -1;
        if (p.y < 0 || p.y > height) p.vy *= -1;
      });
      draw();
      requestAnimationFrame(tick);
    }
    
    resize();
    if (matchMedia('(prefers-reduced-motion: reduce)').matches) draw();
    else requestAnimationFrame(tick);

适合放在哪

适合用

  • AI、科技、数据类产品的官网首屏背景。
  • 活动页、发布会页面的开场背景。
  • 登录页的左侧装饰区。

不适合用

  • 正文阅读区域别放粒子背景;动的东西会一直拉走注意力。
  • 低端手机为主的用户群,别铺满全屏高密度粒子;先降密度或只在桌面显示。
  • 背景已经是复杂图片时,别再叠粒子;画面太乱,标题看不清。

让 AI 帮你做

请给【需要科技感背景的区域,如:首页 Hero 首屏】加上粒子连线背景。先阅读这个区域的组件结构和样式,确认标题、按钮的位置以及现有背景色。要求:用一个绝对定位、aria-hidden 的 canvas 铺在内容下方,内容仍是 HTML;画布尺寸乘以 devicePixelRatio,用 ResizeObserver 跟随大小变化;光点数量按面积计算,窄屏手机降低密度;每帧移动光点、距离小于约 110px 的两点连线(越近越不透明),鼠标位置参与连线;区域离开视野时暂停动画,组件卸载时停止循环并移除监听;开启减少动效时只画静止的一帧。不新增依赖,不改无关代码。最后说明怎样在手机和桌面上验证帧率和清晰度。

用到的知识