效果如图 可以实现大球固定不动,另一个小球跟随鼠标平滑移动,当两者靠近时发生融球效果
正文
原理非常简单,filter: blur() + contrast()
即可实现。
上代码
html
<body>
<div class="ball_filter">
<div class="big_ball"></div>
<div class="ball"></div>
</div>
<script src="move_ball.js"></script>
</body>
首先我们需要一个filter容器,里面装一个保持不动的大球和一个follower小球
接着在CSS代码里简单设置一下,需要注意的是:
- 大球和小球的positon都要设置为absolute
- filter容器的filter属性设置
contrast(任意一个比较大的值)
,这里我设置的是1500%
值越大,小球的边界越清晰
css
.ball_filter {
position: relative;
height: 100vh;
width: 100vw;
filter: contrast(1500%);
background-color: white;
}
.big_ball {
position: absolute;
height: 400px;
width: 400px;
left: 50%;
top: 50%;
}
.ball {
position: absolute;
height: 250px;
width: 250px;
}
这里再对两个球都设置一下filter: blur()
也建议选择一个比较大的值
然后通过设置transform:translate(-50%, -50%)
让球对准的位置是球心,而不是div盒子的左上角
css
.ball_filter div {
border-radius: 50%;
background-color: black;
filter: blur(3rem);
transform: translate(-50%, -50%);
}
JS部分实现小球的跟随鼠标效果
准备一个updateFollower()
函数来计算并更新小球的位置
当前坐标为cx和cy,使其按照ease的速率向着目标坐标tx和ty进行变化
其中ease越小,小球移动的速度就越慢
JavaScript
function updateFollower() {
cx += (tx - cx) * ease
cy += (ty - cy) * ease
follower.style.left = `${cx}px`
follower.style.top = `${cy}px`
requestAnimationFrame(updateFollower)
}
再给document添加一个鼠标移动的监听:
当鼠标移动时,把小球移动的目标坐标(tx和ty)设置为鼠标的坐标
JavaScript
document.addEventListener("mousemove", (e) => {
tx = e.clientX
ty = e.clientY
})
现在只要再运行updateFollower()函数就ok了
JavaScript
updateFollower()
完整代码
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="ball_filter">
<div class="big_ball"></div>
<div class="ball"></div>
</div>
<script src="move_ball.js"></script>
</body>
</html>
CSS
.html,body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
overflow: hidden;
}
.ball_filter div {
border-radius: 50%;
background-color: black;
filter: blur(3rem);
transform: translate(-50%, -50%);
}
.ball_filter {
position: relative;
height: 100vh;
width: 100vw;
filter: contrast(1500%);
background-color: white;
}
.big_ball {
position: absolute;
height: 400px;
width: 400px;
left: 50%;
top: 50%;
}
.ball {
position: absolute;
height: 250px;
width: 250px;
}
JavaScript
let follower = document.querySelector('.ball')
let tx = window.innerWidth/2, ty = window.innerHeight/2, cx = tx, cy = ty
let ease = 0.08
function updateFollower() {
cx += (tx - cx) * ease
cy += (ty - cy) * ease
follower.style.left = `${cx}px`
follower.style.top = `${cy}px`
requestAnimationFrame(updateFollower)
}
document.addEventListener("mousemove", (e) => {
tx = e.clientX
ty = e.clientY
})
updateFollower()
换个更有趣的配色
结语
通过CSS滤镜的方式实现融球效果非常简单,适合静态、少量元素的时候使用,对刚入门前端的新手非常友好!
感谢看到这里的你,本人是梦想成为前端developer的大一学生,第一次写技术文章,如果有哪里写得不清楚、有问题,请提出来给我机会提升自己~~
希望未来能写出更多更好的技术博客,感谢学习路上我们一路作伴。