// theme-sweep-toggle —— 深浅模式扫场 // 同一 dashboard 深浅两版叠放(深版手工映射 G 色板),上层深版用 clip-path // polygon 15° 斜边从左上扫到右下(先快后缓),边界带 2px 亮线; // 扫完深版整体 scale 0.995→1 "坐实"。f=70 后全静止(70f)。 import React from 'react'; import { useCurrentFrame, interpolate, Easing } from 'remotion'; const CL = { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } as const; // 浅色板 = Fixtures G;深色板手工反转映射 type Pal = { bg: string; panel: string; line: string; bar: string; mid: string; card: string; border: string; side: string; sideBar: string; }; const LIGHT: Pal = { bg: '#ececea', panel: '#f7f7f6', line: '#dcdcda', bar: '#c2c2c0', mid: '#8f8f8d', card: '#ffffff', border: '#d8d8d6', side: '#3a3a3a', sideBar: '#5a5a58', }; const DARK: Pal = { bg: '#1c1c1b', panel: '#242423', line: '#3a3a38', bar: '#6e6e6c', mid: '#8f8f8d', card: '#2c2c2b', border: '#454543', side: '#0f0f0e', sideBar: '#6a6a68', }; // 带色板参数的 dashboard(结构同 Fixtures.FakeDashboard variant A) const Dash: React.FC<{ p: Pal }> = ({ p }) => (
{Array.from({ length: 7 }).map((_, i) => (
))}
{Array.from({ length: 6 }).map((_, i) => { const titleW = 45 + (((i + 1) * 37) % 40); const lines = 2 + ((i + 1) % 3); return (
{Array.from({ length: lines }).map((_, j) => (
))}
); })}
); // 时间轴 const SWEEP0 = 14; // 扫场开始(前 14f 初始静置) const SWEEP1 = 52; // 扫场结束 const SETTLE0 = 52; const SETTLE1 = 64; // 坐实结束 → 之后全静止 const SLANT = 1080 * Math.tan((15 * Math.PI) / 180); // ≈ 289px,15° 斜边 export const ThemeSweepToggle: React.FC = () => { const frame = useCurrentFrame(); // 边界顶端 x:先快后缓(poly(3) out);从左外扫到右外+SLANT 保证底边也扫尽 const p = interpolate(frame, [SWEEP0, SWEEP1], [-20, 1920 + SLANT + 40], { easing: Easing.out(Easing.poly(3)), ...CL, }); // 坐实:0.995 → 1 const settle = interpolate(frame, [SETTLE0, SETTLE0 + 1, SETTLE1], [1, 0.995, 1], { easing: Easing.out(Easing.cubic), ...CL, }); // 亮线透明度:扫场期间可见,扫完 6f 内淡出 const lineOp = interpolate(frame, [SWEEP0, SWEEP0 + 4, SWEEP1 - 4, SWEEP1 + 2], [0, 1, 1, 0], CL); const sweeping = frame >= SWEEP0 && frame < SWEEP1 + 2; return (
{/* 底层浅色版 */} {/* 上层深色版,clip-path 斜切揭出 */}
{/* 2px 亮线边界(条件卸载) */} {sweeping && (
)}
); };