import React from 'react';
import { AbsoluteFill, Easing, interpolate, useCurrentFrame } from 'remotion';
import { FakeDashboard, Card, TitleBlock, G } from '../../_fixtures/Fixtures';
// anime-impact 动漫打击帧〔组合〕:crash-zoom 急推撞停在目标卡上的那 3 帧,
// 整幅画面反转成黑白负片 + 手绘放射集中线 + 红青通道 ±8px 色散——
// 像素被打了一拳,第 4 帧一切撤掉恢复干净特写 + 6px 震屏衰减。
// 节拍:0–24 建立全景 hold → 24–30 急推(6f ease-in 到 2.4x) →
// 30–32 冲击帧(3f 负片/集中线/RGB split,每帧换形态) →
// 33 起恢复特写 + 震屏衰减 → ~45–120 静止读卡。
const ZOOM_START = 24;
const ZOOM_END = 30; // 撞停帧
const IMPACT_LEN = 3; // 冲击帧持续 3f(30/31/32)
const RECOVER = ZOOM_END + IMPACT_LEN; // 33:恢复干净特写
// 目标卡:盖在 3x2 网格中排第 2 格上(列 2 行 1)
const CARD = { x: 808, y: 108, w: 524, h: 454 };
const CX = CARD.x + CARD.w / 2; // 1070
const CY = CARD.y + CARD.h / 2; // 335
const SCALE_END = 2.4;
// seed 正弦哈希(禁 Math.random)
const rnd = (i: number) => {
const s = Math.sin(i * 127.3) * 43758.5453;
return s - Math.floor(s);
};
// 手绘放射集中线:30 根从卡片周缘指向画框外的尖楔形,phase 换一次形态
const SpeedLines: React.FC<{ phase: number }> = ({ phase }) => {
const cx = 960;
const cy = 540;
const R_OUT = 1300; // 超出画框对角(~1101)
const polys = Array.from({ length: 30 }).map((_, i) => {
const k = i * 13 + phase * 101;
const ang = ((i + 0.5) / 30) * Math.PI * 2 + (rnd(k) - 0.5) * 0.22;
const r0 = 300 + rnd(k + 1) * 220; // 内端长短随机(卡片周缘一带)
const halfW = (7 + rnd(k + 2) * 16) / R_OUT; // 外端宽 7–23px 的楔形
const ax = cx + Math.cos(ang) * r0;
const ay = cy + Math.sin(ang) * r0;
const b1x = cx + Math.cos(ang - halfW) * R_OUT;
const b1y = cy + Math.sin(ang - halfW) * R_OUT;
const b2x = cx + Math.cos(ang + halfW) * R_OUT;
const b2y = cy + Math.sin(ang + halfW) * R_OUT;
return `${ax},${ay} ${b1x},${b1y} ${b2x},${b2y}`;
});
return (
);
};
// 目标卡叠层 + 全景底
const Scene: React.FC = () => (
<>