feat(stargalaxy): add ring position config and orbit keyframes
This commit is contained in:
parent
233b527236
commit
a870943dc1
80
frontend/pages/square/components/StarGalaxy/config.js
Normal file
80
frontend/pages/square/components/StarGalaxy/config.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// StarGalaxy 组件配置常量
|
||||||
|
// 9 个散落 item 沿 65° 倾斜椭圆轨道排列
|
||||||
|
// slot 0 = 最前(底部,TOP 4 起始位置),slot 4-5 = 最后(顶部)
|
||||||
|
|
||||||
|
export const RING = {
|
||||||
|
cx: 187, // 椭圆圆心 x
|
||||||
|
cy: 510, // 椭圆圆心 y
|
||||||
|
rx: 130, // 水平半径
|
||||||
|
ry: 55, // 垂直半径(cos(65°) ≈ 0.423,模拟向后倾 65°)
|
||||||
|
startAngle: 180, // 起始角:slot 0 在正下方
|
||||||
|
step: 40, // 间隔角(顺时针 = 负方向 → step = -40 在 CSS 中)
|
||||||
|
}
|
||||||
|
|
||||||
|
// item 固定尺寸(label 在 cover 上方)
|
||||||
|
export const ITEM = {
|
||||||
|
width: 46, // cover + label 宽度
|
||||||
|
labelHeight: 14, // 顶部 label 高度
|
||||||
|
coverHeight: 56, // 底部 cover 高度
|
||||||
|
gap: 2, // label 与 cover 之间的间距
|
||||||
|
}
|
||||||
|
// total: 14 + 2 + 56 = 72
|
||||||
|
|
||||||
|
// TOP 6 / TOP 11 推到边缘,避免与 TOP 5/7、TOP 10/12 重叠
|
||||||
|
// TOP 6 推到屏幕右侧 (321, 488),TOP 11 推到屏幕左侧 (8, 488)
|
||||||
|
export const OVERRIDES = {
|
||||||
|
6: { x: 321, y: 488 },
|
||||||
|
11: { x: 8, y: 488 },
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算 y 在椭圆前/后位置的比例(0 = 最后, 1 = 最前)
|
||||||
|
function yFactor(y) {
|
||||||
|
// y=458 (back) → 0; y=565 (front) → 1
|
||||||
|
return Math.max(0, Math.min(1, (y - 458) / 107))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成 9 个 item 的位置配置
|
||||||
|
export function generateRingPositions() {
|
||||||
|
return Array.from({ length: 9 }, (_, i) => {
|
||||||
|
const rank = i + 4
|
||||||
|
const alpha = (RING.startAngle + i * RING.step) * Math.PI / 180
|
||||||
|
const baseX = RING.cx + RING.rx * Math.sin(alpha) - ITEM.width / 2
|
||||||
|
const baseY = RING.cy - RING.ry * Math.cos(alpha) - (ITEM.labelHeight + ITEM.gap + ITEM.coverHeight) / 2
|
||||||
|
const ovr = OVERRIDES[rank]
|
||||||
|
const y = ovr?.y ?? baseY
|
||||||
|
const x = ovr?.x ?? baseX
|
||||||
|
const f = yFactor(y)
|
||||||
|
return {
|
||||||
|
rank,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
scale: 0.75 + 0.40 * f, // 0.75 → 1.15
|
||||||
|
zIndex: Math.round(f * 10), // 0 → 10
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单组 @keyframes(CSS 模板字符串)
|
||||||
|
// translate 值是相对 slot 0 中心 (164, 530) 的偏移
|
||||||
|
export const ORBIT_KEYFRAMES = `
|
||||||
|
@keyframes orbit {
|
||||||
|
0% { transform: translate(0,0) scale(1.15); }
|
||||||
|
11.11% { transform: translate(84px,-13px) scale(1.05); }
|
||||||
|
22.22% { transform: translate(157px,-43px) scale(0.95); }
|
||||||
|
33.33% { transform: translate(113px,-83px) scale(0.85); }
|
||||||
|
44.44% { transform: translate(45px,-107px) scale(0.75); }
|
||||||
|
55.55% { transform: translate(-45px,-107px) scale(0.75); }
|
||||||
|
66.66% { transform: translate(-113px,-83px) scale(0.85); }
|
||||||
|
77.77% { transform: translate(-156px,-43px) scale(0.95); }
|
||||||
|
88.88% { transform: translate(-84px,-13px) scale(1.05); }
|
||||||
|
100% { transform: translate(0,0) scale(1.15); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes crownPulse {
|
||||||
|
0%, 100% { transform: translateX(-50%) scale(1); }
|
||||||
|
50% { transform: translateX(-50%) scale(1.15); }
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// 各 slot 对应 ring-item 类的 r0..r8 的 delay(负值让 item 起始位置 = slot)
|
||||||
|
export const RING_DELAYS = [0, -4, -8, -12, -16, -20, -24, -28, -32]
|
||||||
Loading…
Reference in New Issue
Block a user