diff --git a/frontend/pages/square/components/StarGalaxy/config.js b/frontend/pages/square/components/StarGalaxy/config.js new file mode 100644 index 0000000..40e227f --- /dev/null +++ b/frontend/pages/square/components/StarGalaxy/config.js @@ -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]