// 爆花确认(pop-burst-confirm)——确认时刻的三连爆 // 半屏大对勾 icon(圆底+勾):先缩 0.6x 蓄力 3f → 弹 1.35x 过冲 → 落回 1x, // 释放帧同帧中心射出 10 根短线粒子(径向飞出后消失)+ 一圈描边圆环从 // icon 边缘扩到 2.5 倍直径淡出;随后 "Deployed" 小标签弹出。 // 节拍:0–20 静置(空心圆待确认)→ 20–23 缩 0.6x → 23–27 蓄力 3f → // 27 释放(勾画出+粒子+圆环)→ 27–44 过冲落回 → 40–50 标签弹出 → 55 后真静止 65f。 // 帧确定,无随机源(粒子角度抖动用 sin 散列)。 import React from 'react'; import { useCurrentFrame, interpolate, Easing } from 'remotion'; import { G } from '../../_fixtures/Fixtures'; const AMBER = '#b45309'; const POP = 27; // 释放帧 const DUR = 120; export const PopBurstConfirm: React.FC = () => { const f = useCurrentFrame(); // icon 缩放:蓄力→过冲→落回 const scale = (() => { if (f <= 20) return 1; if (f <= 23) return interpolate(f, [20, 23], [1, 0.6], { easing: Easing.in(Easing.quad) }); if (f <= POP) return 0.6; if (f <= 33) return interpolate(f, [POP, 33], [0.6, 1.35], { easing: Easing.out(Easing.cubic) }); return interpolate(f, [33, 44], [1.35, 1], { extrapolateRight: 'clamp', easing: Easing.out(Easing.back(2)), }); })(); // 对勾:释放帧起 8f 内画出(dashoffset 滑窗) const checkT = interpolate(f, [POP, POP + 8], [0, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.out(Easing.cubic), }); // 粒子:释放帧起 14f 径向飞出(幅度加码到 190px 保半屏可感) const pt = interpolate(f, [POP, POP + 14], [0, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', }); const pDist = 210 + 190 * Easing.out(Easing.cubic)(pt); const pLen = 46 * (1 - pt); // 圆环:释放帧起 20f 从 icon 边缘扩到 2.5 倍直径淡出 const rt = interpolate(f, [POP, POP + 20], [0, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', }); const ringR = 200 + 300 * Easing.out(Easing.cubic)(rt); const ringO = 0.85 * (1 - rt); const ringW = 16 - 12 * rt; // 标签:40f 弹出(back 超调) const tagT = interpolate(f, [40, 50], [0, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.out(Easing.back(2.6)), }); const CX = 960; const CY = 470; return (