Spaces:
Running
Running
File size: 3,459 Bytes
cfe45d5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | import { AbsoluteFill, interpolate, useCurrentFrame } from "remotion";
import { SceneLayoutProps } from "./types";
export const CodeBlock: React.FC<SceneLayoutProps> = ({
title,
accentColor,
bgColor,
textColor,
codeLines = [],
codeLanguage = "",
aspectRatio,
}) => {
const frame = useCurrentFrame();
const p = aspectRatio === "portrait";
const titleOp = interpolate(frame, [0, 20], [0, 1], {
extrapolateRight: "clamp",
});
const codeOp = interpolate(frame, [15, 40], [0, 1], {
extrapolateRight: "clamp",
});
const codeY = interpolate(frame, [15, 40], [30, 0], {
extrapolateRight: "clamp",
});
const lineReveal = interpolate(frame, [20, 20 + codeLines.length * 10], [0, codeLines.length], {
extrapolateRight: "clamp",
});
const cursorBlink = Math.floor(frame / 15) % 2;
// Terminal-style dark card (always dark regardless of bgColor)
const termBg = "#1a1a2e";
return (
<AbsoluteFill
style={{
backgroundColor: bgColor,
padding: p ? "60px 40px" : "80px 100px",
display: "flex",
flexDirection: "column",
justifyContent: "center",
}}
>
<h2
style={{
color: textColor,
fontSize: p ? 32 : 42,
fontWeight: 700,
fontFamily: "Inter, sans-serif",
opacity: titleOp,
marginBottom: p ? 28 : 40,
}}
>
{title}
</h2>
<div
style={{
backgroundColor: termBg,
borderRadius: 16,
padding: p ? "24px 28px" : "32px 40px",
border: "1px solid #333",
opacity: codeOp,
transform: `translateY(${codeY}px)`,
}}
>
{/* Terminal dots */}
<div style={{ display: "flex", gap: 8, marginBottom: p ? 16 : 20 }}>
<div style={{ width: 12, height: 12, borderRadius: "50%", backgroundColor: "#FF5F57" }} />
<div style={{ width: 12, height: 12, borderRadius: "50%", backgroundColor: "#FEBC2E" }} />
<div style={{ width: 12, height: 12, borderRadius: "50%", backgroundColor: "#28C840" }} />
{codeLanguage && (
<span
style={{
marginLeft: 12,
fontSize: p ? 11 : 13,
color: "#666",
fontFamily: "'Fira Code', 'Courier New', monospace",
}}
>
{codeLanguage}
</span>
)}
</div>
{codeLines.map((line, i) => (
<div
key={i}
style={{
fontFamily: "'Fira Code', 'Courier New', monospace",
fontSize: p ? 16 : 22,
lineHeight: 2,
color: i < Math.floor(lineReveal) ? "#E0E0E0" : "transparent",
transition: "color 0.3s",
whiteSpace: "pre",
}}
>
<span style={{ color: "#555", marginRight: p ? 10 : 16, fontSize: p ? 12 : 16 }}>
{String(i + 1).padStart(2, " ")}
</span>
{line}
{i === Math.floor(lineReveal) && (
<span style={{ opacity: cursorBlink, color: accentColor }}>|</span>
)}
</div>
))}
</div>
<div
style={{
position: "absolute",
bottom: 0,
left: 0,
width: "100%",
height: 4,
backgroundColor: accentColor,
}}
/>
</AbsoluteFill>
);
};
|