You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.2 KiB
75 lines
2.2 KiB
|
3 weeks ago
|
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;
|
||
|
|
}
|