CSS+JS实现融球+跟随鼠标效果

效果如图 可以实现大球固定不动,另一个小球跟随鼠标平滑移动,当两者靠近时发生融球效果

正文

原理非常简单,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的大一学生,第一次写技术文章,如果有哪里写得不清楚、有问题,请提出来给我机会提升自己~~

希望未来能写出更多更好的技术博客,感谢学习路上我们一路作伴。

相关推荐
小小小小宇19 分钟前
前端小tips
前端
小小小小宇28 分钟前
二维数组按顺时针螺旋顺序
前端
安木夕1 小时前
C#-Visual Studio宇宙第一IDE使用实践
前端·c#·.net
努力敲代码呀~1 小时前
前端高频面试题2:浏览器/计算机网络
前端·计算机网络·html
高山我梦口香糖1 小时前
[electron]预脚本不显示内联script
前端·javascript·electron
神探小白牙1 小时前
vue-video-player视频保活成功确无法推送问题
前端·vue.js·音视频
Angel_girl3192 小时前
vue项目使用svg图标
前端·vue.js
難釋懷2 小时前
vue 项目中常用的 2 个 Ajax 库
前端·vue.js·ajax
Qian Xiaoo2 小时前
Ajax入门
前端·ajax·okhttp
爱生活的苏苏2 小时前
vue生成二维码图片+文字说明
前端·vue.js