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

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

相关推荐
百万蹄蹄向前冲30 分钟前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
朝阳5811 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路1 小时前
GeoTools 读取影像元数据
前端
ssshooter2 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
Jerry2 小时前
Jetpack Compose 中的状态
前端
dae bal3 小时前
关于RSA和AES加密
前端·vue.js
柳杉3 小时前
使用three.js搭建3d隧道监测-2
前端·javascript·数据可视化
lynn8570_blog4 小时前
低端设备加载webp ANR
前端·算法
LKAI.4 小时前
传统方式部署(RuoYi-Cloud)微服务
java·linux·前端·后端·微服务·node.js·ruoyi
刺客-Andy4 小时前
React 第七十节 Router中matchRoutes的使用详解及注意事项
前端·javascript·react.js