图片涟漪悬停特效(鼠标跟随波纹 + 中心扩散双层波纹 CSS JS 源码)
图片涟漪悬停 3 种玩法:纯 CSS 中心涟漪扩散、JS 鼠标跟随圆环涟漪、双层波纹交错扩散,附带性能优化技巧,适合活动 Banner 与作品展示。
效果演示(真实可交互)
把鼠标移到图片上:第一种从中心扩散涟漪,第二种涟漪会跟随你的鼠标位置出现,第三种双层波纹交错循环。移动鼠标观察第二种的跟随细节。
🌊
💧
🫧
完整代码
HTML 结构:三种玩法共用 .rp-img 容器,第一种与第三种纯 CSS 实现,第二种需要给图片加 id 供 JS 定位:
<figure class="rp-card">
<div class="rp-img rp-center"><span>🌊</span></div>
<figcaption>① 中心涟漪(纯 CSS)</figcaption>
</figure>
<figure class="rp-card">
<div class="rp-img rp-follow" id="rpFollow"><span>💧</span></div>
<figcaption>② 鼠标跟随涟漪(JS)</figcaption>
</figure>
核心 CSS(以中心涟漪为例):
.rp-center::after {
content: '';
position: absolute;
top: 50%; left: 50%;
width: 40px; height: 40px;
margin: -20px 0 0 -20px; /* 负外边距让圆居中 */
border-radius: 50%;
border: 3px solid rgba(255, 255, 255, .9);
opacity: 0;
transform: scale(0);
}
.rp-card:hover .rp-center::after {
animation: rp-ring 1.1s ease-out 2; /* 播放 2 次 */
}
@keyframes rp-ring {
0% { opacity: .9; transform: scale(0); }
100% { opacity: 0; transform: scale(5.2); }
}
鼠标跟随涟漪的 JS(核心逻辑):
const follow = document.getElementById('rpFollow');
follow.addEventListener('mousemove', (e) => {
const r = follow.getBoundingClientRect();
const x = e.clientX - r.left; // 相对图片的坐标
const y = e.clientY - r.top;
const ring = document.createElement('span');
ring.className = 'rp-follow-ring';
ring.style.left = x + 'px';
ring.style.top = y + 'px';
follow.appendChild(ring);
ring.addEventListener('animationend', () => ring.remove()); // 动画完即清理
});
参数说明
| 参数 | 默认值 | 说明 |
|---|---|---|
| 涟漪初始尺寸 | 40px | 圆环起始直径,配合负外边距居中 |
| 边框粗细 | 2-3px | 圆环描边宽度 |
| 扩散倍率 | 5.2 | scale() 的最终倍数 |
| 动画时长 | 1.1s | 单次涟漪扩散的时间 |
| 播放次数 | 2 / infinite | 中心涟漪播 2 次,双层波纹无限循环 |
| 同屏上限 | 8 | JS 玩法限制涟漪最大数量 |
兼容性与性能
- 玩法①③纯 CSS,玩法②仅需 20 行原生 JS,无任何第三方依赖
- 动画属性为
transform / opacity,由合成器处理,不触发布局重排 - 玩法②用
animationend及时移除 DOM 节点,并限制同屏涟漪上限为 8 个,长时间悬停不会造成节点堆积与内存增长 - 移动端
mousemove不触发,玩法②在触屏上无反馈,建议移动端使用纯 CSS 玩法
常见问题
Q: 鼠标快速移动时涟漪会连成一条线? 这是正常表现,mousemove 事件频率高,圆环密集排布形成拖尾;若想稀疏些,可在 JS 中做节流(如每 30ms 只创建一次)。
Q: 涟漪跑到图片外面去了? 检查 .rp-img 是否有 overflow: hidden,圆环是绝对定位子元素,没有裁剪就会溢出容器。
Q: 双层波纹想一快一慢怎么调? 两个伪元素分别使用不同时长与延迟:animation-delay: .3s 让第二个晚 0.3 秒出发,扩散节奏错开更有层次。
Q: 可以商用吗? 可以,本组件为粤喵自研原创,免费商用无需署名;玩法②的 JS 依赖原生 DOM API,在任何前端框架里都可以用 ref 复刻。
许可与来源
- 许可证:自研原创 —— 粤喵自研原创,可免费用于个人与商业项目,无需署名。查看来源公示与许可清单
- 来源:粤喵团队原创自研(从效果思路到代码实现均为独立完成,未直接复制第三方代码)
- 首次发布:2026-09-01 · 最近更新:2026-09-01
- 修改日志:2026-09-01 首次发布;2026-09-13 补充许可证与来源标注、复制按钮说明与法务页入口
- 纠错:联系页面 / min@cactus.asia,2 个工作日内核实处理
常见问题
这个组件可以商用吗?
可以。本组件为粤喵自研原创,可免费用于个人和商业项目,无需署名。
浏览器兼容性如何?
支持所有现代浏览器(Chrome / Firefox / Safari / Edge 最新版本)。旧版 IE 不支持 CSS 动画相关特性。
怎么修改动画参数?
直接调整 CSS 中的 animation-duration(时长)、animation-timing-function(缓动曲线)等属性即可,代码中有注释说明。