磁吸按钮特效(鼠标吸附跟随 JS 源码,零依赖)
磁吸按钮源码:按钮跟随鼠标轻微吸附移动、文字反向漂移、松手回弹,原生 JS 实现零依赖,适合 CTA 按钮与导航入口。
效果演示(真实可交互)
把鼠标移到下方按钮附近,按钮会被”吸”向光标;移出区域后按钮平滑回弹。按钮文字还会反向漂移,产生立体景深感。
磁吸按钮,把鼠标放上来
完整代码
HTML 结构:外层 .mag-wrap 是感应区域,.mag-btn 是被吸附的按钮:
<div class="mag-wrap" id="magWrap">
<div class="mag-btn" id="magBtn">
<span id="magText">磁吸按钮,把鼠标放上来</span>
</div>
</div>
CSS:按钮使用过渡让回弹更平滑:
.mag-wrap { perspective: 600px; }
.mag-btn {
display: inline-block;
padding: 14px 34px;
border-radius: 10px;
background: linear-gradient(135deg, #6c8cff, #b388ff);
color: #fff;
cursor: pointer;
transition: transform .3s cubic-bezier(.22, .61, .36, 1), box-shadow .3s ease;
will-change: transform;
}
.mag-btn span { display: inline-block; transition: transform .3s cubic-bezier(.22,.61,.36,1); }
原生 JS 核心逻辑(零依赖):
const wrap = document.getElementById('magWrap');
const btn = document.getElementById('magBtn');
const text = document.getElementById('magText');
let raf = null;
wrap.addEventListener('mousemove', (e) => {
const br = btn.getBoundingClientRect();
const cx = br.left + br.width / 2;
const cy = br.top + br.height / 2;
let dx = e.clientX - cx;
let dy = e.clientY - cy;
// 距离超过 80px 后按比例压缩,避免按钮飞得太远
const dist = Math.hypot(dx, dy);
const max = 80;
if (dist > max) { const k = max / dist; dx *= k; dy *= k; }
const moveX = dx * 0.35;
const moveY = dy * 0.35;
if (raf) cancelAnimationFrame(raf);
raf = requestAnimationFrame(() => {
btn.style.transform = `translate(${moveX}px, ${moveY}px)`;
text.style.transform = `translate(${moveX * 0.4}px, ${moveY * 0.4}px)`;
});
});
wrap.addEventListener('mouseleave', () => {
if (raf) cancelAnimationFrame(raf);
btn.style.transform = 'translate(0, 0)';
text.style.transform = 'translate(0, 0)';
});
参数说明
| 参数 | 默认值 | 说明 |
|---|---|---|
位移系数 0.35 | — | 按钮跟随光标的最大位移比例,越大吸力越强 |
感应半径 max: 80 | 80px | 超过该距离位移被压缩,防止按钮脱离区域 |
文字反向系数 0.4 | — | 文字与按钮反向漂移的幅度,制造景深 |
| 回弹时长 | .3s | 移出后按钮回弹的过渡时间 |
requestAnimationFrame | — | 逐帧渲染,避免 mousemove 高频触发卡顿 |
兼容性与性能
- 原生 JS + requestAnimationFrame,无任何依赖库,移动端与桌面端通用
- 触屏设备没有 hover 概念,建议通过
pointermove事件或直接隐藏该效果 - 动画只操作
transform,走 GPU 合成,性能开销极小 - 注意鼠标事件需绑定在感应区域
.mag-wrap上,若绑定按钮本身,移出按钮即触发回弹,体验会跳变
常见问题
Q: 按钮被吸走太远,怎么限制? 调小位移系数 0.35,比如 0.2,并把感应半径 max 从 80 降到 50。
Q: 想整组导航按钮一起磁吸? 给每个按钮单独创建磁吸逻辑,或者把位移应用到容器上统一计算,注意各按钮的感应区域不要重叠。
Q: 移动端有效果吗? 触屏无 hover 无 mousemove,磁吸效果默认不触发;如需触摸版本可监听 touchmove 并把坐标换算为触摸点。
Q: 可以商用吗? 可以,粤喵自研原创组件,免费商用无需署名。
常见问题
这个组件可以商用吗?
可以。本组件为粤喵自研原创,可免费用于个人和商业项目,无需署名。
浏览器兼容性如何?
支持所有现代浏览器(Chrome / Firefox / Safari / Edge 最新版本)。旧版 IE 不支持 CSS 动画相关特性。
怎么修改动画参数?
直接调整 CSS 中的 animation-duration(时长)、animation-timing-function(缓动曲线)等属性即可,代码中有注释说明。