import { Node, UITransform, view } from 'cc'; import { PopCenterPreset } from './PopAnimTypes'; /** 按 center 占屏比例自适应的入场参数 */ export interface AdaptivePopParams { peak: number; undershoot: number; lift: number; launchDur: number; recoilDur: number; lockDur: number; jellyDur: number; jellyAmp: number; opacityStart: number; } function clamp01(t: number): number { if (t <= 0) return 0; if (t >= 1) return 1; return t; } function lerp(a: number, b: number, t: number): number { return a + (b - a) * t; } /** 0=小面板有力,1=大面板克制 */ function measurePanelFill(center: Node): number { const ui = center.getComponent(UITransform); if (!ui) return 0.5; const { width, height } = ui.contentSize; if (width <= 0 || height <= 0) return 0.5; const panelMax = Math.max(width, height); const screenMin = Math.min(view.getVisibleSize().width, view.getVisibleSize().height); return clamp01((panelMax / screenMin - 0.2) / 0.72); } export function computeAdaptivePopParams(center: Node, preset: PopCenterPreset): AdaptivePopParams | null { if (preset !== 'scale' && preset !== 'bounce') return null; const fill = measurePanelFill(center); const punch = 1 - fill; const jelly = preset === 'bounce'; if (preset === 'scale') { return { peak: lerp(1.05, 1.09, punch), undershoot: lerp(0.988, 0.978, punch), lift: lerp(6, 12, punch), launchDur: lerp(0.09, 0.11, punch), recoilDur: 0.04, lockDur: lerp(0.05, 0.065, fill), jellyDur: 0, jellyAmp: 0, opacityStart: 200, }; } return { peak: lerp(1.06, 1.12, punch), undershoot: lerp(0.985, 0.968, punch), lift: lerp(8, 18, punch), launchDur: lerp(0.10, 0.13, punch), recoilDur: 0.045, lockDur: lerp(0.055, 0.075, fill), jellyDur: lerp(0.12, 0.15, punch), jellyAmp: lerp(0.85, 1.15, punch), opacityStart: 160, }; } export function adaptivePopDuration(p: AdaptivePopParams): number { return p.launchDur + p.recoilDur + p.lockDur + p.jellyDur; }