// neon-frame-forerun v3 —— v2 基础上按用户意见新增(clickup04 五张): // 框内各组件/文字初始悬空在页面上空(3D 抬起),悬空时在面板上映射 // 同形软影,随页面点亮进程同步先后贴合(FloatWrap 模式,对标截图③: // tab/组件悬空带错位影 → ④全部贴合)。v2 已有:强透视直角框左缘中点 // 两头奔画、面板原地由暗转亮、背景霓虹管框群中亮尾熄。 import React, { useId } from 'react'; import { AbsoluteFill, useCurrentFrame, interpolate, Easing } from 'remotion'; const easeFall = Easing.bezier(0.5, 0.05, 0.6, 1); // 加速下落、末端软着陆 /* 悬浮 + 同形软影:h=悬浮高度(px)。本体向左上抬起,原位留模糊压暗同形影, * h→0 时重合、影子消失(对标批次11 GrazeFaceTour FloatWrap) */ const FloatWrap: React.FC<{ h: number; children: React.ReactNode }> = ({ h, children }) => (
{h > 1 && (
{children}
)}
{children}
); /* land=贴合完成时刻(0..1),之前从 H 高度加速贴落 */ const liftOf = (t: number, land: number, H: number) => { const FALL = 0.3; const p = Math.min(1, Math.max(0, (t - (land - FALL)) / FALL)); return (1 - easeFall(p)) * H; }; const mulberry32 = (a: number) => () => { let t = (a += 0x6d2b79f5); t = Math.imul(t ^ (t >>> 15), t | 1); t ^= t + Math.imul(t ^ (t >>> 7), t | 61); return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }; const ink = '#3c3c3a'; const mid = '#9a9a98'; const line = '#e3e3e1'; const PW = 1330; const PH = 900; const PL = 1000; // 归一路径长 // 直角矩形路径:从左缘中点出发(对应截图①左缘先亮) const FRAME_D = `M 0 ${PH / 2} L 0 0 L ${PW} 0 L ${PW} ${PH} L 0 ${PH} Z`; const Chip: React.FC<{ w: number }> = ({ w }) => (
); /* t = 贴落进程(0..1)。各组件按页面展示顺序(侧栏自上而下、主区自上而下) * 错峰从空中贴落,悬空时投同形软影(对标截图③虚影→④⑤贴合) */ const GrayHome: React.FC<{ t?: number }> = ({ t = 1 }) => { const L = (land: number, H = 72) => liftOf(t, land, H * 1.7); return (
{[76, 56, 96, 110, 66, 60].map((w, i) => (
))}
{[104, 126, 96, 118, 88].map((w, i) => (
))}
{[0, 1, 2, 3, 4, 5, 6].map((i) => ( ))}
{[54, 84, 50, 82].map((w, i) => (
))}
{[0, 1, 2, 3].map((i) => (
{[0, 1, 2].map((k) =>
)}
))}
); }; // 背景霓虹管框:大、亮、带透视错落(截图③④) type BgFrame = { x: number; y: number; w: number; h: number; hue: string; phase: number; period: number; skew: number }; const rng = mulberry32(20260718); const HUES = ['#b06af0', '#e879c9', '#f0a35c', '#6a7df0', '#e0679a', '#8a5cf0', '#c06af0']; const BG_FRAMES: BgFrame[] = Array.from({ length: 18 }).map(() => ({ x: rng() * 2000 - 120, y: rng() * 1100 - 60, w: 160 + rng() * 480, h: 70 + rng() * 220, hue: HUES[Math.floor(rng() * HUES.length)], phase: rng() * 90, period: 55 + rng() * 70, skew: -14 + rng() * 10, })); export const NeonFrameForerun: React.FC = () => { const frame = useCurrentFrame(); // 滤镜/渐变 ID 按实例生成,多实例同场不串引(useId 的 «:» 在 url() 里非法,需清洗) const uid = useId().replace(/[^a-zA-Z0-9]/g, ''); // 主框描画:左缘中点向两头奔跑,26 帧成型(截图①→②) const trace = interpolate(frame, [2, 28], [0, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.bezier(0.3, 0.1, 0.3, 1), }); // 面板原地显影:框成型后内容从近黑到暗灰(截图②),再全亮(截图③) const lit = interpolate(frame, [24, 46, 78], [0.0, 0.3, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.bezier(0.35, 0, 0.3, 1), }); // 主框独立描边可见度:面板亮起后并入面板 rim 辉光(截图③以后细线淡出,糊辉光留下) const frameLine = interpolate(frame, [50, 90], [1, 0], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', }); const rimGlow = interpolate(frame, [28, 60, 108, 132], [0.9, 1, 0.75, 0.5], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', }); // 背景:中段全亮(截图③④)→ 尾段熄灭(截图⑤) const bgLit = interpolate(frame, [8, 44, 96, 128], [0.15, 1, 0.85, 0.06], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', }); // 强透视 → 缓和:框飞入时角度大,面板亮起后落定(截图①梯形→③④缓斜) const settle = interpolate(frame, [0, 70], [0, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.out(Easing.cubic), }); const rotY = -26 + 15 * settle; const rotX = 7 - 3 * settle; const rotZ = -9 + 4.5 * settle; const scale = 0.94 + 0.1 * settle; const headP = trace * (PL / 2); // 组件贴落进程:与页面点亮(lit 24→78)同步推进,稍滞后收尾—— // "和页面的展示同步完成贴合" const drop = interpolate(frame, [34, 98], [0, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', }); return ( {/* 背景霓虹管框群 */} {BG_FRAMES.map((b, i) => { const breath = 0.5 + 0.5 * Math.sin(((frame + b.phase) / b.period) * Math.PI * 2); const op = bgLit * (0.18 + 0.4 * breath); return ( ); })} {/* 主体:强透视斜置的框 + 面板 */}
{/* 面板:原地由暗转亮(无位移缩放) */}
0.55 ? 1 : 0, filter: `brightness(${Math.max(0.05, lit)})` }}> {/* 未点亮时的冷色压暗罩 */}
{/* 面板 rim 辉光(框光并入后由它承担,底缘最强——对应截图③④底/右缘粉光) */}
{/* 霓虹描边框:左缘中点出发两头奔画,直角转角 */} {[1, -1].map((dir) => ( {/* 糊辉光层:一直保留 */} {/* 亮芯细线:面板亮起后淡出并入 rim */} {/* 奔跑亮头 */} {trace < 1 && ( )} ))}
); };