Vibe Coding 一把 Dia 的背景动画
上周在 X 上看到一条推文在说好奇 Dia 首页的背景动画是怎么实现的,这里提到的动画你可以在打开 Dia 浏览器时或者切换用户时看到。如果你没有 Dia 浏览器,你可以在这里看到动画的浅色版本、深色版本和我做的版本,其中以上的深色版本视频是放慢了速度的。
这确实是一个优雅的动画,看起来也不难实现,我就兴起花了一点时间简单 Vibe Coding 了一把。
基础布局
使用 Vite 新建项目后,我开始搭建输入框的静态设计,我使用了 Gemini CLI 来协助我完成这一步,但是折腾了一阵子后,还提供了参考图,它也无法完成基础的布局搭建,或者说,不美观,需要我人工去修改的地方非常多。
后来想起朋友曾经推荐的另一个工具 Argument ,我就试着换成用它来搭建,这也是我在使用 Cursor 许久之后重新回到 VS Code 上。和 Gemini 类似,我只描述了参照 Google 搜索的界面来进行基础的布局搭建,结果挺让我惊喜,除了一些样式上的细节,其余和 Google 首页的设计很接近。
基础布局剩下的部分就没有太多好讲了,后面就是和我的 AI 助理一起调整界面细节,使用下来我对 Argument 很满意,但文章的重点还是来讲讲动画的实现吧。
基础动画
了解清楚这是一个怎样运动的动画是这次 Coding 的关键点,在 3 个地方可以了解这个动画的一些细节。
第一个当然最开始提到的是浏览器内,我录制了视频来多次观看这个动画。
第二是在 Dia 官网上,在 Hero 区域的输入框背后也有一个类似的效果,能看到页面代码的好处是,你可以看到这里使用了一个视频来显示动画。
第三处是在官网的页脚,这里也有一个特别的效果,初看和之前提到的背景动画差别很大,但是我们依然能在这里获取到一些端倪。
- 这是一个 Scroll-driven 的效果,整个图形会跟随滚动拉伸,这其实已经接近最先我们提到的动画的本质了;
- 从代码里可以看到,这是一个 SVG,这应该也是最开始的动画的源素材之一,我将这个 SVG 拿下来了,这省去了实现这个静态设计的时间;
- 这个 SVG 放到 Figma 或者用 VS Code 打开可以看到,结构也很简单,是一个带有 9 个矩形渐变的编组;

看完这几个地方,我猜测这个动画主要的运动是高度缩放的动画,从动画里可以看到,不同的矩形像是有错落的运动时间,但是到达终点的时间点一样,这个实际上是高度不一样而运动时间一样形成的,有了实现的思路后,就可以动手了。
因为每个矩形是单独的动画,所以我把动画写在 SVG 里了,刚好这又是我相对熟悉的领域。我先将 SVG 添加到网页背景中,简单调整了一下透明度,位置和旋转角度,然后给每个矩形添加统一的以顶部为变换点,从 3x 缩放到 1x 的动画,这样就完成了一个基础的缩放动画。
10s 和无限循环是我为了方便调试临时写的参数,以及调整了缩放后也要把 View box 的尺寸一并调整。
<style>.scale-animation { animation: scaleDown 10s ease-in-out infinite; transform-origin: center top;}
@keyframes scaleDown { 0% { transform: scaleY(3)} 100% { transform: scaleY(0)}}</style>

加点细节
上面是最基本的动画,应该 Vibe Coding 几句就能完成,但是要做到原本动画里的那么优雅,还需要更多的细节,接下来做的微调都是基于个人直觉。
素材调整
在目前的版本里,你可以看到原始的 SVG 文件里有一个 clip-path 裁切,素材调整的第一步就是先去除这个蒙版,在代码里去除或者 Figma 里去除都可以,另一点是我纯粹凭借个人眼神目测,这个动画里的渐变没有 SVG 里最边缘的深蓝色,我需要去除这个颜色,我选择在 Figma 里一并处理这两件事情。
打开 Figma 后我发现顶部边缘的不是深蓝色,而是深棕色。
优化动画的出现和结束
在这一步我要优化动画的出现和消失的过渡。在动画开始时,动画是在一瞬间出现的——其实官方的动画看起来也是这样——而结束时,虽然我们已经去除了 clip-path,但是因为最终都是在同一时间点在同一 Y 坐标上缩放到 0,最终导致了还是会像在一条线上消失的错觉。基于这两个问题,我尝试给动画的开始和结束添加了两个简单的透明度变化过渡现在至少看起来不那么突兀了。
@keyframes scaleDown { 0% { transform: scaleY(3); opacity: 0; } 25% { opacity: 1; } 75% { opacity: 1; } 100% { transform: scaleY(0); opacity: 0; }}
运动曲线调整
在最开始我们选用了ease-in-out
这个常用的预设曲线,但是实际上,我认为这应该是一个更接近于 easeOutExpo 或者 easeOutQuart 的曲线,我选择了前者。
同时因为运动曲线的调整,你可以看到,在 75% 处已经很接近速度为 0,因此「像在一条线上消失」的问题又再次出现了,在这里我们再一次微调透明度变化的位置。
<style>.scale-animation { animation: scaleDown 1.3s cubic-bezier(0.16, 1, 0.3, 1) infinite; transform-origin: center top; transform: scaleY(2);}
@keyframes scaleDown { 0% { transform: scaleY(3); opacity: 0; } 25% { opacity: 1; } 50% { opacity: 0; } 100% { transform: scaleY(0); opacity: 0;}}}</style>
不同的缩放倍数
用下面这张图的渐变对比我们原始的 SVG 可以看到,如果在我们的基础上要实现这个效果,不同矩形的起始缩放要设置成不一样的倍数。

如果从左到右称之为 1~9 号矩形,我给 1/9 号,2/3/7/8 号,和 4/5/6 号分别添加了不同的起始缩放倍数,如style="--scaleY: 5;"
来达到这个效果,然后在动画参数中使用这个不同的起始量。
这一点其实也可以一开始在 Figma 里预先处理好。
@keyframes scaleDown { 0% { transform: translateY(800px) scaleY(var(--scaleY, 2)); opacity: 0;} 25% { opacity: 1;} 50% { opacity: 0;} 100% { transform: translateY(120px) scaleY(0); opacity: 0;}}
在这一步我还顺带调节了 blur 的强度、处理了 view box 的裁切,增加了一个位移动画等等这些细节,又是一次不停的「加点细节」。
输入框的高亮
继续观察官方的动画,在渐变背景经过输入框时,输入框边缘的阴影的颜色会变成高亮,我直接在最底层加了一个绝对定位的矩形配合mix-blend-overlay
来快速模拟这个效果。
我最开始的想法是在输入框背后增加几个伪元素再调整各个元素的层级来实现,但为了快速验证用 Blend 效果是否可行,就用了比较偷懒的方式。

到这里这个动画的 Demo 基本就完成了,你可以访问这个地址来预览,点击 Logo 可以重复播放动画。代码我也已经公开到 GitHub 上了,有兴趣的可以去看看。
如果还要继续优化,依然有很多可以「加点细节」的地方。比如最后提到的高亮效果,虽然我轻描淡写地带过,但这里其实还有很多值得探索的细节:比如发光效果并非每边均匀,比如背景的光效在接近时就已经开始产生高光,而不是我实现的那样元素重叠时才会有 Blend 效果。
在一边实现的过程中,我一边反复观察这个动画,发现它比最初想象的要复杂一些,这给我最大的感受是,尽管 Vibe Coding 让我们能够快速实现想法,但要打造出优秀的设计或者产品,依然需要投入时间去思考,这是 AI 无法替代的一部分。