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

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

相关推荐
leeyi几秒前
微前端:14 个子应用是怎么做到不散架的——DeepFlux 前端工程拆解(第102篇)
前端·aigc·agent
天道kabuto27 分钟前
踩坑实录:JS Map迭代器为什么“用完即焚”?兼谈技术知识沉淀
前端
字节跳动开源31 分钟前
VisActor全新图可视化开源项目:VGraph
前端·设计模式·开源
打呵欠的猫32 分钟前
前端接口超时从 15s 改到动态值后,用户投诉降了 60%——AI 帮我分析出的方案
前端·ai编程
岁月宁静32 分钟前
二、《从零手撸 Agent》 — 聊聊 LLM 的失忆真相
前端·python·agent
郭邯40 分钟前
用纯前端实现一个代码压缩美化工具,我踩了这三个坑
前端
用户2832096793743 分钟前
从进程线程到 async/await:JS Event-loop事件循环机制底层解析
前端·javascript
岁月宁静1 小时前
一、《从零手撸 Agent》 我用 10 行代码跑通了第一次大模型调用(顺便踩了 4 个坑)
前端·python·agent
计算机魔术师1 小时前
Fable 5.1 来了,智能体任务成本降 45%——Anthropic 这次为何降价这么狠
前端
Csvn1 小时前
现代 CSS 新特性深度:container query、:has()、@scope 与 subgrid
前端