feat(film): theme tokens, blueprint background, caption component
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
import { AbsoluteFill } from "remotion";
|
||||
import { theme } from "../theme";
|
||||
|
||||
export const BlueprintBg: React.FC<{ opacity?: number }> = ({ opacity = 0.4 }) => {
|
||||
const line = "rgba(59,130,246,0.10)";
|
||||
return (
|
||||
<AbsoluteFill
|
||||
style={{
|
||||
backgroundColor: theme.bg,
|
||||
backgroundImage: `linear-gradient(${line} 1px, transparent 1px), linear-gradient(90deg, ${line} 1px, transparent 1px)`,
|
||||
backgroundSize: "48px 48px",
|
||||
opacity,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
import { useCurrentFrame, interpolate, AbsoluteFill } from "remotion";
|
||||
import { theme } from "../theme";
|
||||
|
||||
type Position = "bottom" | "center";
|
||||
|
||||
export const Caption: React.FC<{
|
||||
text: string;
|
||||
startFrame: number;
|
||||
durationInFrames: number;
|
||||
position?: Position;
|
||||
}> = ({ text, startFrame, durationInFrames, position = "bottom" }) => {
|
||||
const frame = useCurrentFrame();
|
||||
const local = frame - startFrame;
|
||||
if (local < 0 || local > durationInFrames) return null;
|
||||
|
||||
const opacity = interpolate(
|
||||
local,
|
||||
[0, 12, durationInFrames - 12, durationInFrames],
|
||||
[0, 1, 1, 0],
|
||||
{ extrapolateLeft: "clamp", extrapolateRight: "clamp" }
|
||||
);
|
||||
const y = interpolate(local, [0, 12], [20, 0], { extrapolateRight: "clamp" });
|
||||
|
||||
return (
|
||||
<AbsoluteFill
|
||||
style={{
|
||||
justifyContent: position === "bottom" ? "flex-end" : "center",
|
||||
alignItems: "center",
|
||||
paddingBottom: position === "bottom" ? 90 : 0,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
opacity,
|
||||
transform: `translateY(${y}px)`,
|
||||
maxWidth: 1200,
|
||||
textAlign: "center",
|
||||
fontFamily: theme.font,
|
||||
fontWeight: 800,
|
||||
fontSize: position === "center" ? 64 : 44,
|
||||
lineHeight: 1.15,
|
||||
color: theme.text,
|
||||
background: "rgba(9,9,11,0.55)",
|
||||
backdropFilter: "blur(8px)",
|
||||
padding: "18px 36px",
|
||||
borderRadius: 18,
|
||||
border: `1px solid ${theme.border}`,
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
</div>
|
||||
</AbsoluteFill>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
export const theme = {
|
||||
bg: "#09090b",
|
||||
surface: "rgba(255,255,255,0.03)",
|
||||
border: "rgba(255,255,255,0.10)",
|
||||
text: "#ffffff",
|
||||
textDim: "rgba(255,255,255,0.55)",
|
||||
blue: "#3b82f6",
|
||||
cyan: "#22d3ee",
|
||||
emerald: "#10b981",
|
||||
amber: "#f59e0b",
|
||||
red: "#ef4444",
|
||||
font: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Inter, sans-serif',
|
||||
mono: 'ui-monospace, SFMono-Regular, Menlo, monospace',
|
||||
brandGradient: "linear-gradient(90deg, #60a5fa, #3b82f6, #22d3ee)",
|
||||
} as const;
|
||||
Reference in New Issue
Block a user