// ===== demos/camera/overhead-camera-moves/OverheadTabletopDrop.tsx ===== // overhead-tabletop-drop|上帝视角桌面滑降 // perspective(1600px) 内三张"页面卡"rotateX(62°) 平躺成桌面卡阵。 // 0–55f 相机横向滑过(只动 translateX,缓入缓出);55–85f 骤降扎入: // rotateX 62→0 + 世界 scale 1→2.0(2% 过冲)+ translateX -650→0 三者同跑, // 中间卡对位落成正视满屏 dashboard。全部动画 f=93 结束,收尾真静止 52f。 // 卡片 996×560(spec 900→996,使 FakeDashboard 0.5185 缩放严丝合缝、 // 落版 16:9 精确对位),间距 140px。 import React from 'react'; import { AbsoluteFill, interpolate, useCurrentFrame, Easing } from 'remotion'; import { FakeDashboard, Card, G } from '../../_fixtures/Fixtures'; const CARD_W = 996; const CARD_H = 560; const GAP = 140; const PITCH = CARD_W + GAP; // 1136 const INNER = CARD_H / 1080; // 0.5185:FakeDashboard 缩到卡内正好铺满 const PAN_END = 55; const DROP_END = 85; // 单张"页面卡":白底圆角卡,内容按 INNER 缩放塞满 const PageCard: React.FC<{ x: number; children: React.ReactNode }> = ({ x, children }) => (
{children}
); export const OverheadTabletopDrop: React.FC = () => { const f = useCurrentFrame(); // 0–55f 横滑:只动 translateX,缓入缓出 const panX = interpolate(f, [0, PAN_END], [700, -650], { easing: Easing.inOut(Easing.cubic), extrapolateLeft: 'clamp', extrapolateRight: 'clamp', }); // 55–85f 骤降:角度 / 缩放 / 位移三者同跑,out-cubic + 2% 过冲 const drop = interpolate(f, [PAN_END, DROP_END], [0, 1], { easing: Easing.out(Easing.cubic), extrapolateLeft: 'clamp', extrapolateRight: 'clamp', }); const rotX = interpolate(f, [PAN_END, DROP_END, DROP_END + 4, DROP_END + 8], [62, -1.8, 0.6, 0], { easing: Easing.out(Easing.cubic), extrapolateLeft: 'clamp', extrapolateRight: 'clamp', }); const scale = interpolate(f, [PAN_END, DROP_END, DROP_END + 7], [1, 2.04, 2.0], { easing: Easing.out(Easing.cubic), extrapolateLeft: 'clamp', extrapolateRight: 'clamp', }); const dropX = interpolate(drop, [0, 1], [panX, 0]); // drop 段把 -650 收回 0 const tx = f <= PAN_END ? panX : dropX; return (
{/* 世界原点 = 屏心;先 in-plane scale,再 rotateX,最后 translateX */}
{/* 桌面:浅灰底 + 网格线,给横滑段提供运动参照 */}
{/* 目标页:落版满屏 */}
); }; // ===== demos/camera/overhead-camera-moves/TiltReveal.tsx ===== // tilt-reveal|俯仰揭示 // 开场俯视 dashboard 顶部(rotateX 平躺、只露顶栏),~43f 机位抬头回正, // 内容一排排涌入视野。out-cubic + 末端轻微过冲回正,落定真静止 ≥35f。 import React from 'react'; import { AbsoluteFill, interpolate, useCurrentFrame, Easing } from 'remotion'; import { FakeDashboard, G } from '../../_fixtures/Fixtures'; const HOLD = 25; // 俯角定格 const MOVE = 43; // 主抬升 // 过冲:-55° → +2.6° → -0.9° → 0°,全部动画在 f=76 结束(145-76=69f 真静止) export const TiltReveal: React.FC = () => { const f = useCurrentFrame(); const rotX = interpolate( f, [HOLD, HOLD + MOVE, HOLD + MOVE + 4, HOLD + MOVE + 8], [-80, 2.6, -0.9, 0], { easing: Easing.out(Easing.cubic), extrapolateLeft: 'clamp', extrapolateRight: 'clamp' }, ); const p = interpolate(f, [HOLD, HOLD + MOVE], [0, 1], { easing: Easing.out(Easing.cubic), extrapolateLeft: 'clamp', extrapolateRight: 'clamp', }); const scale = interpolate(p, [0, 1], [3.2, 1]); const ty = interpolate(p, [0, 1], [200, 0]); const persp = interpolate(p, [0, 1], [600, 1200]); const perspY = interpolate(p, [0, 1], [5, 40]); return (
); };