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

如何实现Smooth tracking mouse moves平滑鼠标移动跟踪效果

平滑鼠标移动跟踪效果实现方案

你之前尝试搭配right/bottom属性做延迟导致效果变差的核心原因很明确:left/top和right/bottom属于同一定位体系下的互斥属性,同时赋值会让浏览器在两套定位规则之间做计算拉扯,不仅会触发额外重排,还很容易出现位置偏移、抖动问题,这个实现思路从根上就错了。

目前主流站点(包括你提到的参考站)用的都是逐帧线性插值(Lerp)+ GPU加速渲染的方案,实现出来的平滑效果自然不生硬,性能也足够好,具体实现步骤如下:

核心实现步骤

  • 基础样式配置
    给跟随鼠标的元素设置固定定位,只保留left: 0; top: 0初始值,完全移除right/bottom相关属性,额外加pointer-events: none避免元素挡住页面交互,建议给元素设置固定宽高方便居中对齐。
  • 坐标变量初始化
    定义两组坐标,一组存实时鼠标真实位置,一组存跟随元素当前的渲染位置,再配置一个缓动系数控制平滑度:
    // 鼠标真实坐标
    let mouseX = 0, mouseY = 0;
    // 跟随元素当前渲染坐标
    let currentX = 0, currentY = 0;
    // 缓动系数,取值0-1,数值越小跟手速度越慢、拖影感越强,参考站效果大概在0.15左右
    const ease = 0.15;
    const cursorEl = document.querySelector('.custom-cursor');
    
  • 鼠标位置监听
    给window绑定mousemove事件,事件触发时只更新真实鼠标坐标即可,不要在事件回调里直接修改元素位置:
    window.addEventListener('mousemove', (e) => {
      // 坐标值减去元素自身宽高的一半,实现元素中心对准鼠标,而不是元素左上角对准鼠标
      mouseX = e.clientX - cursorEl.offsetWidth / 2;
      mouseY = e.clientY - cursorEl.offsetHeight / 2;
    });
    
  • 逐帧缓动渲染
    用requestAnimationFrame绑定浏览器渲染帧率做动画循环,每帧通过线性插值计算元素当前应该移动到的位置,用transform3d赋值触发GPU加速,避免重排卡顿:
    function rafLoop() {
      // 每帧让元素向鼠标位置移动剩余距离的ease比例,实现连续平滑的跟手效果
      currentX += (mouseX - currentX) * ease;
      currentY += (mouseY - currentY) * ease;
      // 用translate3d走合成层渲染,比修改    修改left/top性能高3-5倍
      cursorEl.style.transform = `translate3d(${currentX}px, ${currentY}px, 0)`;
      requestAnimationFrame(rafLoop);
    }
    // 启动动画循环
    rafLoop();
    

常见踩坑避坑

  • 不要用CSS transition做平滑效果:快速甩动鼠标时transition会出现明显的拖影断层,手感僵硬,完全不如逐帧插值的连续感
  • 不要用left/top更新元素位置:这两个属性修改会触发整个文档的重排计算,页面元素多的时候很容易掉帧
  • 如果要做多图层级的跟随效果(比如外层弱光晕、内层实心点的双层光标),只需要多定义几组current坐标,给不同图层设置不同的ease值即可,比如外层光晕设0.08,内层圆点设0.2,就能做出自然的层次延迟感

调试的时候可以先把ease值调到1,这时候元素会完全跟手无延迟,确认坐标对齐没有偏移之后,再慢慢把ease值往小调找合适的手感,能省很多调试时间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:01:20