import React from 'react'; import { AbsoluteFill, Easing, interpolate, useCurrentFrame } from 'remotion'; import { FakeDashboard, Card, TitleBlock, G } from '../../_fixtures/Fixtures'; // portal-wipe 穿窗入景·改〔批次 1 重做〕 // 批次 1 弱点:3 层 7 卡散开幅度大(0.85)+blur,穿窗后画面碎读不清。 // 本版:窗放大 bezier(0.7,0,0.3,1) 40f 先慢后快;窗内只 2 层 // (远景整页 dashboard 缩略 + 近景 2 张卡),散开系数近 0.3 / 远 0.08, // 不加 blur;穿窗完成(f65)后所有层 8f 内缓停(f73),之后静止 hold 77f 读清新场景。 // // 节拍(150f @30fps): // 0–25 hold:旧 dashboard 建立,目标卡原位可见 // 25–65 窗放大 40f:卡放大成全屏窗,窗内新场景随之显形 // 65–73 缓停 8f:近/远两层视差余势收干(Easing.out 自然归零) // 73–150 静止 hold:新场景完整可读 export const PortalWipeV2: React.FC = () => { const frame = useCurrentFrame(); // ── 窗放大:40f,先慢后快再缓收 ── const t = interpolate(frame, [25, 65], [0, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.bezier(0.7, 0, 0.3, 1), }); const c0 = { x: 1180, y: 620, w: 480, h: 320, r: 14 }; const x = interpolate(t, [0, 1], [c0.x, 0]); const y = interpolate(t, [0, 1], [c0.y, 0]); const w = interpolate(t, [0, 1], [c0.w, 1920]); const h = interpolate(t, [0, 1], [c0.h, 1080]); const r = interpolate(t, [0, 1], [c0.r, 0]); // ── 窗内视差散开:40→73f,Easing.out 保证 f65 穿窗完成后 8f 内速度归零 ── const spread = interpolate(frame, [40, 73], [0, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.out(Easing.cubic), }); // 窗内整体从缩略推到满幅 const innerScale = interpolate(t, [0, 1], [0.42, 1]); return ( {/* 旧场景:dashboard A */} {/* 窗(放大的卡)——内藏新场景 */}
{/* 窗内 1920×1080 舞台,随穿窗从 0.42 推到 1 */}
{/* 远景层(系数 0.08,不加 blur):新场景整页 dashboard 缩略 */}
{/* 近景层(系数 0.3,不加 blur):只 2 张卡,向边缘让位 */}
{/* 卡正面:放大初期渐隐,露出窗内新场景 */}
); };