You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

技术咨询:如何复刻谷歌Antigravity页面的鼠标悬停粒子动画效果

嘿,我正好研究过谷歌Antigravity那个粒子交互效果,核心是Canvas粒子系统加上鼠标力场模拟,我来一步步拆解给你看:

1. 粒子系统的结构设计

一个稳定的粒子系统得包含这几个核心部分:

  • 粒子类(Particle):每个粒子要存储自身的运动状态——位置(x,y)、速度(vx,vy)、加速度(ax,ay),再加上半径、颜色这些视觉属性。核心逻辑是每一帧用物理公式更新状态:速度 = 速度 + 加速度,位置 = 位置 + 速度,更新后要重置加速度,避免粒子持续受力失控。
  • 渲染循环(Render Loop):用requestAnimationFrame驱动每一帧的更新与渲染,先以半透明色清屏(能留下粒子拖影,更有动感),再遍历所有粒子,先更新运动状态再绘制(用Canvas的arc方法画圆形粒子)。
  • 边界处理:粒子碰到画布边缘时要反弹,比如x坐标超出画布宽度时反转vx方向,同时加一点摩擦系数(比如0.8)让速度衰减,模拟真实世界的碰撞损耗,效果更自然。
2. 鼠标交互的处理逻辑

鼠标对粒子的影响本质是力场模拟,关键步骤如下:

  • 鼠标状态追踪:监听mousemove事件记录鼠标实时坐标(mouseX, mouseY),用mouseenter/mouseleave标记鼠标是否在画布范围内,避免鼠标移出后粒子还受影响。
  • 引力/斥力计算:对每个粒子,先计算它与鼠标的直线距离。如果距离小于设定的影响半径,就用向量计算力的方向:
    • 若要实现粒子远离鼠标(像Antigravity的效果),就取粒子指向鼠标的反方向作为力的方向;
    • 力的大小和距离成反比——距离越近,力越大,比如用(影响半径 - 距离) / 影响半径作为力的系数,让效果更平滑。
  • 悬停增强效果:如果需要在鼠标悬停特定元素(比如按钮)时让粒子反应更强烈,可以临时增大影响半径或力的系数,强化交互反馈。
实现示例代码

下面是一个简化版的复刻代码,直接运行就能看到类似效果:

<canvas id="particleCanvas"></canvas>

<style>
  body { margin: 0; overflow: hidden; }
  #particleCanvas { background: #fff; }
</style>

<script>
const canvas = document.getElementById('particleCanvas');
const ctx = canvas.getContext('2d');

// 适配窗口大小
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

// 鼠标状态管理
let mouse = {
  x: null,
  y: null,
  isActive: false,
  influenceRadius: 180 // 鼠标影响范围
};

// 粒子类
class Particle {
  constructor() {
    this.reset();
    this.radius = Math.random() * 3 + 0.5;
    this.color = '#1a73e8'; // 谷歌主题蓝
  }

  reset() {
    // 随机初始位置
    this.x = Math.random() * canvas.width;
    this.y = Math.random() * canvas.height;
    // 小范围随机初始速度
    this.vx = (Math.random() - 0.5) * 0.6;
    this.vy = (Math.random() - 0.5) * 0.6;
    this.ax = 0;
    this.ay = 0;
  }

  update() {
    // 应用加速度到速度
    this.vx += this.ax;
    this.vy += this.ay;
    // 应用速度到位置
    this.x += this.vx;
    this.y += this.vy;
    // 重置加速度
    this.ax = 0;
    this.ay = 0;

    // 边界反弹+摩擦
    if (this.x < 0 || this.x > canvas.width) {
      this.vx *= -0.8;
      this.x = Math.max(0, Math.min(canvas.width, this.x));
    }
    if (this.y < 0 || this.y > canvas.height) {
      this.vy *= -0.8;
      this.y = Math.max(0, Math.min(canvas.height, this.y));
    }

    // 鼠标斥力逻辑
    if (mouse.isActive) {
      const dx = this.x - mouse.x;
      const dy = this.y - mouse.y;
      const distance = Math.sqrt(dx * dx + dy * dy);

      if (distance < mouse.influenceRadius && distance > 0) {
        const force = (mouse.influenceRadius - distance) / mouse.influenceRadius;
        const dirX = dx / distance;
        const dirY = dy / distance;

        // 给粒子添加加速度
        this.ax += dirX * force * 0.6;
        this.ay += dirY * force * 0.6;
      }
    }

    // 速度衰减,防止无限加速
    this.vx *= 0.985;
    this.vy *= 0.985;
  }

  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
    ctx.fillStyle = this.color;
    ctx.fill();
  }
}

// 创建粒子群
const particles = [];
const particleCount = 300;
for (let i = 0; i < particleCount; i++) {
  particles.push(new Particle());
}

// 渲染循环
function animate() {
  // 半透明清屏,保留拖影
  ctx.fillStyle = 'rgba(255,255,255,0.08)';
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  particles.forEach(particle => {
    particle.update();
    particle.draw();
  });

  requestAnimationFrame(animate);
}

// 绑定鼠标事件
canvas.addEventListener('mousemove', (e) => {
  mouse.x = e.clientX;
  mouse.y = e.clientY;
});
canvas.addEventListener('mouseenter', () => mouse.isActive = true);
canvas.addEventListener('mouseleave', () => mouse.isActive = false);

// 窗口 resize 适配
window.addEventListener('resize', () => {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  particles.forEach(p => p.reset());
});

// 启动动画
animate();
</script>
额外优化建议
  • 可以给近距离的粒子添加连线效果,当粒子间距小于某个值时用lineTo画线段,更贴近谷歌Antigravity的视觉感;
  • 调整粒子数量、力的系数、摩擦系数来平衡性能与效果,一般200-500个粒子在普通设备上都能流畅运行;
  • 可以给鼠标悬停时添加粒子颜色变化、影响半径渐变的效果,增强交互的层次感。

内容的提问来源于stack exchange,提问作者Durkshaw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 10:07:32