// 立方体空间翻转(cube-rotate)——cube transition 转场自实现。 // FakeDashboard A / B 各缩放 0.82 居中,当立方体相邻两面:perspective 1400px, // 面宽 W=1920*0.82,两面各 rotateY(面角) translateZ(W/2),场景整体先 // translateZ(-W/2) 再 rotateY(θ)(把正面拉回 z=0,保证 hold 时精确 0.82 尺度)。 // 旧面 A 转出画面 brightness 1→0.55 压暗,新面 B 从 +90° 侧转入 0.55→1 亮起; // 接缝两侧各一条竖向渐变阴影,随角度 sin(pπ) 加深再消失;转动中段叠 blur(1.5px), // 落定摘掉(filter 条件挂载,保证收尾逐帧完全相同)。 // 关键帧:0–30 静止展示 A → 30–68 θ 0→-90°(inOut cubic)翻转 → 68–140 B 真静止 72f。 import React from 'react'; import { useCurrentFrame, interpolate, Easing } from 'remotion'; import { G, FakeDashboard, TitleBlock } from '../../_fixtures/Fixtures'; const S = 0.82; const W = 1920 * S; // 面宽 = 立方体棱长 const H = 1080 * S; // 单个立方体面:W×H 视口内放缩放 0.82 的整幅 dashboard const Face: React.FC<{ variant: 'A' | 'B'; rot: number; // 面自身的 rotateY(A=0,B=90) brightness: number; seam: number; // 接缝阴影不透明度 0–1 seamSide: 'right' | 'left'; // 阴影贴在哪条竖边(即共享棱一侧) }> = ({ variant, rot, brightness, seam, seamSide }) => (
{seam > 0.01 && (
)}
); export const CubeRotate: React.FC = () => { const frame = useCurrentFrame(); // 翻转进度:30–68f,inOut cubic;两端 clamp 保证 hold 段逐帧恒定 const p = interpolate(frame, [30, 68], [0, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.inOut(Easing.cubic), }); const theta = -90 * p; const brightA = 1 - 0.45 * p; // 旧面转出压暗 1→0.55 const brightB = 0.55 + 0.45 * p; // 新面转入亮起 0.55→1 const mid = Math.sin(p * Math.PI); // 0→1→0,45° 时最深 const seam = mid * 0.9; const blur = mid * 1.5; return (
{/* blur 外包一层:>0.02 才挂 filter,落定后收尾帧完全相同 */}
0.02 ? `blur(${blur}px)` : undefined, }} >
{/* 面 A:正面出发,绕左而去;接缝棱在其右边 */} {/* 面 B:从 +90° 侧面转进来;接缝棱在其左边 */}
); };