CODE · 3.9 KB
remotion/ProcessTensionFilm.jsx
Workspace snapshot · 09/04 14:52
import React from "react";
import {
AbsoluteFill,
Audio,
Img,
OffthreadVideo,
Sequence,
interpolate,
staticFile,
useCurrentFrame,
} from "remotion";
import gallery from "../assets/generated/benchmark-reset-v1/concept-b-embedded-type-gallery-v1.png";
import conflict from "../assets/generated/benchmark-reset-v1/concept-b-embedded-type-conflict-v1.png";
import criterion from "../assets/generated/benchmark-reset-v1/concept-b-embedded-type-criterion-v1.png";
import decision from "../assets/generated/benchmark-reset-v1/concept-b-embedded-type-decision-v1.png";
import resolve from "../assets/generated/benchmark-reset-v1/concept-b-embedded-type-resolve-v2.png";
const clamp = { extrapolateLeft: "clamp", extrapolateRight: "clamp" };
const Grain = () => {
const frame = useCurrentFrame();
return <AbsoluteFill style={{
pointerEvents: "none",
opacity: 0.075,
mixBlendMode: "multiply",
backgroundImage: "radial-gradient(#101218 0.75px, transparent 0.75px)",
backgroundSize: "8px 8px",
transform: `translate(${frame % 3}px,${(frame * 2) % 3}px)`,
}} />;
};
const FullStill = ({ src, fromScale, toScale, fromX = 0, toX = 0, fromY = 0, toY = 0, duration }) => {
const frame = useCurrentFrame();
const scale = interpolate(frame, [0, duration], [fromScale, toScale], clamp);
const x = interpolate(frame, [0, duration], [fromX, toX], clamp);
const y = interpolate(frame, [0, duration], [fromY, toY], clamp);
return <AbsoluteFill style={{ overflow: "hidden", background: "#f6f5f0" }}>
<Img src={src} style={{ width: "100%", height: "100%", objectFit: "contain", transform: `translate3d(${x}px,${y}px,0) scale(${scale})` }} />
</AbsoluteFill>;
};
const Opening = () => <AbsoluteFill style={{ background: "#f6f5f0" }}>
<OffthreadVideo
src={staticFile("media/reset-v1/embedded-type-gallery-v1-kling-v3-pro.mp4")}
muted
style={{ width: "100%", height: "100%", objectFit: "cover" }}
/>
</AbsoluteFill>;
const FiveRouteCuts = () => {
const frame = useCurrentFrame();
const stepLength = 18;
const step = Math.min(4, Math.floor(frame / stepLength));
const within = frame % stepLength;
const centers = [105, 320, 540, 770, 955];
const scale = 2.32;
const drift = interpolate(within, [0, stepLength - 1], [-18, 18], clamp);
const left = 540 - centers[step] * scale + drift;
const top = 960 - 1335 * scale;
const pulse = interpolate(within, [0, 2, 5], [0.92, 0.28, 0], clamp);
return <AbsoluteFill style={{ overflow: "hidden", background: "#f6f5f0" }}>
<Img src={gallery} style={{ position: "absolute", width: 1080 * scale, height: 1920 * scale, left, top }} />
<AbsoluteFill style={{ background: "#fff", opacity: pulse }} />
</AbsoluteFill>;
};
const FinalResolve = () => {
const frame = useCurrentFrame();
const scale = interpolate(frame, [0, 10, 32, 165], [1.16, 1.08, 1, 1.035], clamp);
const y = interpolate(frame, [0, 24, 165], [54, 0, -12], clamp);
return <AbsoluteFill style={{ overflow: "hidden", background: "#f6f5f0" }}>
<Img src={resolve} style={{ width: "100%", height: "100%", objectFit: "contain", transform: `translateY(${y}px) scale(${scale})` }} />
</AbsoluteFill>;
};
export const ProcessTensionFilm = () => <AbsoluteFill style={{ background: "#f6f5f0" }}>
<Audio src={staticFile("pengin-editorial-beat.wav")} volume={0.72} />
<Sequence from={0} durationInFrames={105}><Opening /></Sequence>
<Sequence from={105} durationInFrames={90}><FiveRouteCuts /></Sequence>
<Sequence from={195} durationInFrames={90}><FullStill src={conflict} fromScale={1} toScale={1.025} duration={90} /></Sequence>
<Sequence from={285} durationInFrames={90}><FullStill src={criterion} fromScale={1} toScale={1.025} duration={90} /></Sequence>
<Sequence from={375} durationInFrames={120}><FullStill src={decision} fromScale={1} toScale={1.025} duration={120} /></Sequence>
<Sequence from={495} durationInFrames={165}><FinalResolve /></Sequence>
<Grain />
</AbsoluteFill>;