关于这个复刻
星星先聚成一个「6」,滚动时散作星海。
整个画面是一层全屏正交相机下的 GPU 粒子场。约 5000 颗星星被分配到 5 条曲线上——
这 5 条曲线由构成数字「6」的 5 段 SVG 描边路径生成,并各自带一条正弦形的 Z 向起伏,
所以正面看是一个数字,稍微一转就散成有厚度的银河。
滚动条并不移动这些粒子,它只是把一个 0 → 1 的进度送进顶点着色器。
位置在「沿曲线」和「随机星域」两个目标之间插值,星星的亮度、尺寸包络、闪烁速度、
视差漂移全部随同一个进度衰减。
运行细节
- 粒子数5 条曲线 × (220 / 170) × 密度 4,另加 12% 常驻背景星与中心星团
- 着色器顶点端完成聚拢/散开/形变/透镜/动量,片元端画星芒与核心
- 鼠标128×N 的 ping-pong 浮点纹理保存每颗星的位移与速度,指数阻尼滑行归位
- 拖拽五层各带不同的跟随延迟(lag 0.18 → 0.86),转起来有视差
- 后期UnrealBloom(阈值 0.08 / 半径 0.72)+ ACES 色调映射
形状 cue
路过时,星海重新排列。
页面里的每个「形状锚点」都是一段隐藏的 SVG。当它靠近视口中心时,脚本用
getPointAtLength 沿全部子路径等弧长采样 1024 个点,写进一张
1024×1 的 RGBA 浮点纹理:xy 是归一化坐标,zw 是这颗星
所属子路径的起止区间。
顶点着色器据此为每颗星挑一个落点:先按种子取到所属子路径,再在该子路径内部按
密度衰减分布,加上法线方向的散布和轮廓深度。于是星星不是「贴」到轮廓上,而是
像一条有厚度的星流缠在图形上,还能整体绕 X/Y 轴慢慢转。
交互
鼠标推得动星星。
指针不是靠 CPU 逐颗算的。每颗星在一张 128×N 的半浮点纹理里占一个像素,存
(位移xy, 速度zw)。每帧把指针这一小段移动当成一条线段,离线段越近的星
受到的冲量越大;随后所有星按 drag = 2.3 / √mass 的指数阻尼自己滑回去,
大星重、小星轻,散开的节奏就自然分层。
按住拖拽则是另一路:五层曲线各有不同的跟随时间常数,松手后以更慢的弹性回正。
键盘方向键同样可用,按 R 重播开场动画。
扩展
加一个图案,只需要加一段 SVG。
形状不是写死在代码里的。页面上任何带 data-astra-shape 的元素,
只要里面有一个带 viewBox 的 <svg>,脚本就会在它靠近视口中心时
沿它所有 <path> 的描边等弧长采样 1024 个点,把星星吸过去。
没有构建步骤,也不用改一行 JS。
下面这个是按同样的原理加的第四个图案:11 条等分射线组成的星芒。
它是用代码算出来的——每条射线就是一段 M x1 y1 L x2 y2,
沿曲线的密度衰减会让星星在射线中段聚集、往两头变稀,于是看起来像真的在发光。