import { Node, Vec3 } from 'cc'; import { IPopRevealConfig } from './PopAnimTypes'; import { popStaggerNode } from './PopAnimStagger'; const ITEM_GAP = 0.04; const ITEM_DUR = 0.22; const LAST_GAP = 0.05; /** 在 root / ui_center 下查找节点 */ export function resolvePopNode(root: Node, center: Node | null, name: string): Node | null { if (!name) return null; if (center?.getChildByName(name)) return center.getChildByName(name); if (root.getChildByName(name)) return root.getChildByName(name); if (center) { for (const c of center.children) { const n = c.getChildByName(name); if (n) return n; } } return null; } function collectItemNodes(root: Node, center: Node | null, cfg: IPopRevealConfig): Node[] { const out: Node[] = []; if (cfg.itemsNode) { const container = resolvePopNode(root, center, cfg.itemsNode); if (container?.isValid) { for (const c of container.children) { if (c.active) out.push(c); } } } if (cfg.itemNodes) { for (const name of cfg.itemNodes) { const n = resolvePopNode(root, center, name); if (n?.isValid && n.active) out.push(n); } } return out; } function hideNode(node: Node): void { node.setScale(Vec3.ZERO); } /** 上屏前:列表项与尾部按钮默认隐藏 */ export function preparePopReveal(root: Node, center: Node | null, cfg: IPopRevealConfig): void { for (const n of collectItemNodes(root, center, cfg)) { hideNode(n); } for (const name of cfg.lastNodes ?? []) { const n = resolvePopNode(root, center, name); if (n?.isValid && n.active) hideNode(n); } } /** 内容区入场完成后:分帧错峰出现 */ export function runPopReveal(root: Node, center: Node | null, cfg: IPopRevealConfig): void { const itemPreset = cfg.itemsPreset ?? 'scale'; const lastPreset = cfg.lastPreset ?? 'scale'; const items = collectItemNodes(root, center, cfg); items.forEach((n, i) => { popStaggerNode(n, itemPreset, i * ITEM_GAP); }); const lastStart = items.length * ITEM_GAP + ITEM_DUR * 0.55; (cfg.lastNodes ?? []).forEach((name, i) => { const n = resolvePopNode(root, center, name); if (n?.isValid && n.active) { popStaggerNode(n, lastPreset, lastStart + i * LAST_GAP); } }); } export function estimateRevealDuration(cfg: IPopRevealConfig): number { const itemCount = (cfg.itemNodes?.length ?? 0) + (cfg.itemsNode ? 1 : 0); const lastCount = cfg.lastNodes?.length ?? 0; return itemCount * ITEM_GAP + ITEM_DUR + lastCount * LAST_GAP; }