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

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

相关推荐
anOnion29 分钟前
构建无障碍组件之Carousel Pattern
前端·html·交互设计
ssshooter38 分钟前
Tauri 2 iOS 开发避坑指南:文件保存、Dialog 和 Documents 目录的那些坑
前端·后端·ios
Можно1 小时前
深入理解 ES6 Proxy:与 Object.defineProperty 的全面对比
前端·javascript·vue.js
Birdy_x2 小时前
接口自动化项目实战(1):requests请求封装
开发语言·前端·python
天天向上10243 小时前
vue el-table实现拖拽排序
前端·javascript·vue.js
柳杉4 小时前
Three.js × Blender:从建模到 Web 3D 的完整工作流深度解析
前端·javascript·数据可视化
reembarkation5 小时前
vue3中使用howler播放音频列表
前端·vue.js·音视频
手握风云-5 小时前
基于 Java 的网页聊天室(三)
服务器·前端·数据库
weixin199701080165 小时前
《识货商品详情页前端性能优化实战》
前端·性能优化
Forever7_5 小时前
重磅!Vue3 手势工具正式发布!免费使用!
前端·前端框架·前端工程化