把鼠标划进来
HTML
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>鼠标坐标水波纹</title>
<style>
/* 卡片基本样式 */
.ripple-card{
position:relative;
overflow:hidden; /* 关键:裁剪波纹 */
width:240px;
height:120px;
line-height:120px;
text-align:center;
background:#49B1F5;
color:#fff;
font-size:18px;
border-radius:12px;
cursor:pointer;
user-select:none;
}
/* 波纹本体 */
.ripple-wave{
position:absolute;
border-radius:50%;
background:rgba(255,255,255,.4);
transform:scale(0);
animation:ripple .6s linear;
pointer-events:none;
}
@keyframes ripple{
to{
transform:scale(4); /* 足够大即可覆盖 */
opacity:0;
}
}
</style>
</head>
<body style="display:flex;align-items:center;justify-content:center;height:100vh;background:#f2f4f8;">
<div class="ripple-card">把鼠标划进来</div>
<script>
// 统一处理 .ripple-card 内的鼠标事件
document.querySelectorAll('.ripple-card').forEach(card=>{
card.addEventListener('mousemove', createRipple);
});
function createRipple(e){
// 避免连续触发
if(this.dataset.rippling) return;
this.dataset.rippling = '1';
const rect = this.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// 计算最大半径(确保能覆盖整个卡片)
const maxR = Math.hypot(
Math.max(x, rect.width - x),
Math.max(y, rect.height - y)
);
const wave = document.createElement('span');
wave.className = 'ripple-wave';
wave.style.left = x + 'px';
wave.style.top = y + 'px';
wave.style.width = wave.style.height = maxR * 2 + 'px';
wave.style.marginLeft = wave.style.marginTop = -maxR + 'px';
this.appendChild(wave);
// 动画结束后清理
wave.addEventListener('animationend', ()=>{
wave.remove();
delete this.dataset.rippling;
});
}
</script>
</body>
</html>
如果你只希望划入/划出时触发动画,则可以:
划入 & 划出
HTML
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>划入 / 划出 一次波纹</title>
<style>
.card{
position:relative;
overflow:hidden;
width:240px;
height:120px;
line-height:120px;
text-align:center;
background:#49B1F5;
color:#fff;
border-radius:12px;
cursor:pointer;
user-select:none;
}
/* 划入波纹 */
.wave-in,
.wave-out{
position:absolute;
border-radius:50%;
transform:scale(0);
pointer-events:none;
}
.wave-in{
background:rgba(255,255,255,.4);
animation:ripple-in .6s forwards;
}
.wave-out{
background:rgba(0,0,0,.15); /* 暗色回弹 */
animation:ripple-out .4s forwards;
}
@keyframes ripple-in{
to{ transform:scale(4); opacity:0; }
}
@keyframes ripple-out{
to{ transform:scale(3); opacity:0; }
}
</style>
</head>
<body style="display:flex;align-items:center;justify-content:center;height:100vh;background:#f2f4f8;">
<div class="card">划入 & 划出</div>
<script>
const card = document.querySelector('.card');
function addWave(cls, x, y){
const rect = card.getBoundingClientRect();
const maxR = Math.hypot(
Math.max(x, rect.width - x),
Math.max(y, rect.height - y)
);
const wave = document.createElement('span');
wave.className = cls;
wave.style.left = x + 'px';
wave.style.top = y + 'px';
wave.style.width = wave.style.height = maxR * 2 + 'px';
wave.style.marginLeft = wave.style.marginTop = -maxR + 'px';
card.appendChild(wave);
wave.addEventListener('animationend', ()=> wave.remove());
}
card.addEventListener('mouseenter', e => {
const rect = card.getBoundingClientRect();
addWave('wave-in', e.clientX - rect.left, e.clientY - rect.top);
});
card.addEventListener('mouseleave', e => {
const rect = card.getBoundingClientRect();
addWave('wave-out', e.clientX - rect.left, e.clientY - rect.top);
});
</script>
</body>
</html>
还有鼠标移入使图片模糊的(不知道为什么这里显示不了。。。把代码复制一份在自己浏览器上看)
把鼠标放上来
HTML
<style>
/* 卡片外壳 */
.card3{
position:relative;
width:300px;
height:200px;
border-radius:16px;
overflow:hidden;
cursor:pointer;
box-shadow:0 8px 24px rgba(0,0,0,.15);
}
/* 背景层 */
.bg{
width:100%;
height:100%;
background:url('https://picsum.photos/600/400?random=3') center/cover;
}
/* 模糊遮罩层(默认看不见) */
.blur-mask{
position:absolute;
inset:0;
background:url('https://picsum.photos/600/400?random=3') center/cover;
filter:blur(12px);
/* 通过 mask 裁剪为圆形,径向渐变中心由 JS 实时更新 */
mask-image:radial-gradient(circle at 50% 50%, #000 0%, transparent 0%);
-webkit-mask-image:radial-gradient(circle at 50% 50%, #000 0%, transparent 0%);
mask-size:100% 100%;
-webkit-mask-size:100% 100%;
transition:mask-position 0s, -webkit-mask-position 0s; /* 位置立即生效 */
}
/* 文字 */
.txt{
position:absolute;
inset:0;
display:flex;
align-items:center;
justify-content:center;
color:#fff;
font-size:20px;
font-weight:600;
text-shadow:0 1px 4px rgba(0,0,0,.4);
pointer-events:none;
}
</style>
<div class="card3">
<div class="bg"></div>
<div class="blur-mask"></div>
<div class="txt">把鼠标放上来</div>
</div>
<script>
const card = document.querySelector('.card3');
const blurM = document.querySelector('.blur-mask');
/* 圆形半径动画帧 */
let animId = null;
/* 统一更新 mask 中心与半径 */
function updateMask(x, y, radius){
const mask = `radial-gradient(circle at ${x}px ${y}px, #000 ${radius}%, transparent ${radius}%)`;
blurM.style.maskImage = mask;
blurM.style.webkitMaskImage = mask;
}
/* mouseenter:0 → 100 半径 */
card.addEventListener('mouseenter', e=>{
const rect = card.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
let r = 0;
const step = ()=>{
r += 2; // 每帧增长 2 %
updateMask(x, y, r);
if(r < 100) animId = requestAnimationFrame(step);
};
step();
});
/* mouseleave:100 → 0 半径 */
card.addEventListener('mouseleave', e=>{
const rect = card.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
cancelAnimationFrame(animId);
let r = 100;
const step = ()=>{
r -= 3;
updateMask(x, y, Math.max(r,0));
if(r > 0) animId = requestAnimationFrame(step);
};
step();
});
</script>
发表回复