// command-palette-summon —— 命令面板降临 // FakeDashboard 静置 → 整屏压暗+blur → ⌘K 面板从中心上方 20px 带 overshoot 弹落 // → 5 条候选行错峰浮现 → 模拟输入 2 字母(灰块当字符)候选 5→3→2 收窄 // → 高亮首条。f=110 后全静止(40f)。光标 f<104 闪烁、之后常亮。 import React from 'react'; import { useCurrentFrame, interpolate, Easing } from 'remotion'; import { G, FakeDashboard } from '../../_fixtures/Fixtures'; const CL = { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } as const; // 时间轴 const DIM0 = 12; // 压暗开始(前 12f 初始静置) const DIM1 = 22; const PANEL_IN = 18; // 面板开始弹落 const ROWS_START = 32; // 候选行开始错峰浮现 const KEY1 = 62; // 第一个字母 const KEY2 = 78; // 第二个字母 const HL = 94; // 高亮首条 const BLINK_END = 104; // 光标停止闪烁(常亮) const PANEL_W = 780; const PANEL_X = (1920 - PANEL_W) / 2; const PANEL_Y = 290; const ROW_H = 72; const ROW_GAP = 8; const EXIT_DUR = 10; // exitAt: 0=留到最后,1=第一次按键后退出,2=第二次按键后退出 const ROWS = [ { titleW: 52, exitAt: 0 }, { titleW: 38, exitAt: 0 }, { titleW: 61, exitAt: 2 }, { titleW: 45, exitAt: 1 }, { titleW: 56, exitAt: 1 }, ]; const PaletteRow: React.FC<{ i: number; frame: number }> = ({ i, frame }) => { const { titleW, exitAt } = ROWS[i]; const inStart = ROWS_START + i * 4; const exitStart = exitAt === 1 ? KEY1 + 3 : exitAt === 2 ? KEY2 + 3 : null; if (exitStart !== null && frame >= exitStart + EXIT_DUR) return null; // 条件卸载,非 opacity 0 const inOp = interpolate(frame, [inStart, inStart + 8], [0, 1], CL); const inY = interpolate(frame, [inStart, inStart + 8], [12, 0], { easing: Easing.out(Easing.cubic), ...CL, }); const exitT = exitStart === null ? 1 : interpolate(frame, [exitStart, exitStart + EXIT_DUR], [1, 0], { easing: Easing.inOut(Easing.cubic), ...CL, }); // 高亮首条 const hl = i === 0 ? interpolate(frame, [HL, HL + 10], [0, 1], CL) : 0; return (