StarGalaxy 组件
square 页「星河」tab 的排行榜组件,渲染 TOP 1-12 的 3D 倾斜椭圆轨道 + 顺时针旋转动画。
视觉特征
- 65° 倾斜椭圆轨道(rx=130, ry=55)
- TOP 1-3 颁奖台(cover + 下方标签 + 钻石外框 + 金/银/铜渐变)
- TOP 4-12 9 个散落 item(cover + 上方标签 + 蓝白钻石渐变)
- 9 item 顺时针 36s 旋转一圈(单组 @keyframes + 9 个不同 animation-delay 错开)
- 近大远小(scale 0.75→1.15,TOP 4 最大,TOP 8/9 最小)
- 装饰层:粉红渐变 overlay + 樱花粉/暖黄双光晕
- 标题「★ 星河 ★」+ 底部提示「每日 0:00 更新榜单」
数据来源
复用现有 getHotRankingApi("displaying", null, 1, 12) — 与「星榜」共用 API,取前 12 条。
文件
| 文件 |
职责 |
index.vue |
容器:数据加载、装饰层、4 状态分支、子组件编排 |
PodiumCard.vue |
TOP 1-3 大卡(cover + 下方 TOP N 标签 + 可选皇冠) |
ScatteredRanks.vue |
TOP 4-12 9 散落 item(共享 36s 旋转动画) |
config.js |
9 slot 位置/translate/scale 公式 + RING_DELAYS |
可调参数
| 参数 |
位置 |
默认值 |
说明 |
| 椭圆倾斜度 |
config.js: RING.ry |
55 (cos⁻¹ 65°) |
改 ry 调整倾斜度(越小越斜) |
| 旋转周期 |
ScatteredRanks.vue: animation |
36s |
改秒数调整速度 |
| 近大远小范围 |
config.js: yFactor + 0.40 * yFactor |
0.75→1.15 |
改 0.75/1.15 调整 |
| TOP 6/11 位置 |
config.js: OVERRIDES |
x:321 / x:8 |
边缘推拉 |
| Podium 位置/尺寸 |
index.vue: PODIUM_SIZES/POSITIONS |
240×260 等 |
调整 1-3 大卡 |
跨端兼容性
| CSS 特性 |
H5 |
APP |
微信小程序 |
备注 |
transform: scale/translate |
✅ |
✅ |
✅ |
全支持 |
filter: blur(Nrpx) |
✅ |
✅ |
⚠️ 部分 |
光晕效果用,MP 可能降级 |
radial-gradient |
✅ |
✅ |
⚠️ 有限 |
渐变背景,部分 MP 降级为线性 |
@keyframes + animation |
✅ |
✅ |
✅ |
全支持 |
mask-composite: exclude |
✅ |
⚠️ |
❌ |
仅 WebKit;MP 需 border-image 替代 |
backdrop-filter |
✅ |
⚠️ |
❌ |
仅 H5;装饰层用 opacity 兜底 |
降级策略:
- 微信小程序:如
mask-composite 不渲染,钻石边框会变成无边框(不致命,cover 仍可见)
- 微信小程序:如
radial-gradient 降级为 linear,标签渐变变为纯色(视觉略降级)
可访问性
prefers-reduced-motion: reduce 媒体查询关闭 .ring-item 和 .crown 的动画
- 标签文字使用高对比度的
#FFFABD + 红色 text-shadow
- TOP 1 卡片有皇冠装饰作为「第一名」视觉提示
状态管理
| 状态 |
触发条件 |
表现 |
| Loading |
初次加载 |
12 个骨架占位(3 大 + 9 小)+ shimmer 动画 |
| Error |
API 失败 |
「加载失败,点击重试」+ 重试按钮 |
| Empty |
API 返回空数组 |
「暂无星河数据」 |
| Success |
12 条数据加载完成 |
完整布局 |
已知限制
prefers-reduced-motion 触发时 9 个 item 会堆叠在 slot 0 位置(spec §6.4 已说明)
ORBIT_KEYFRAMES 模板字符串无法在 Vue <style> 块中通过 JS 变量注入(已在 ScatteredRanks.vue 内联关键帧)
- 跨端兼容性问题主要在微信小程序端,已在风险表中说明
后续改进 (v2)
- 缩略图懒加载优化(
<image lazy-load>)
- 9 item 悬停暂停动画
- 微信小程序钻石边框降级方案(用
border-image 替代 mask-composite)
- 骨架屏精细化(与 square 风格统一)