其实整个鱼眼蜂窝,主要就是由 arctan 向心压缩 + 大小二维表这两层叠出来的。
1. 底层是规整的蜂窝,没有鱼眼效果
可见 icon 按蜂窝交错排,相邻行错开半格。这一层是无限长的内容网格,圆心还没往屏幕中心挤。
2. 滚动只会平移内容网格
滚动只作用在原始的内容网格上,此时 icon 还没有任何变形。
3. arctan 桶形压缩位置
把圆心相对屏幕中点的向量往里收,方向不变,只改变长度。
这一步同时做两件事:
- 边缘挤压:越靠边缘的 icon,往中心收得越多。
- 行变成鱼眼弧:同一行的两端离中心更远,被压得更狠,行会自然弯成弧,不用另外再做一层圆弧。

为什么选 arctan:它中心几乎是直线 y = x,越靠边才往下弯,并且弯完就停住,不会越压越狠直到叠成一坨。

这条曲线也不是从「撞到边再往回推」推出来的。arctan 刚好就是这种先直、再弯、然后停住的形状。
它还有几个好用的特性:
- 中心附近接近 1:1,中间那颗几乎不用压。
- 越远压得越多,但有上限。
- 曲线光滑。
4. 最后计算大小
大小是一张二维表,用 icon 最终落在屏幕上的位置,查出缩放比例。中间大、边上小,由这张表决定,和上面的 arctan 无关——arctan 只搬圆心,不管直径。