diff --git a/marketing/product-film/src/components/KenBurns.tsx b/marketing/product-film/src/components/KenBurns.tsx new file mode 100644 index 0000000..dfce3f5 --- /dev/null +++ b/marketing/product-film/src/components/KenBurns.tsx @@ -0,0 +1,15 @@ +import { useCurrentFrame, useVideoConfig, interpolate } from "remotion"; + +// Slow zoom/pan over its children across the whole sequence the component lives in. +export const KenBurns: React.FC<{ + children: React.ReactNode; + from?: number; + to?: number; + durationInFrames: number; +}> = ({ children, from = 1.0, to = 1.08, durationInFrames }) => { + const frame = useCurrentFrame(); + const scale = interpolate(frame, [0, durationInFrames], [from, to], { + extrapolateRight: "clamp", + }); + return
{children}
; +}; diff --git a/marketing/product-film/src/components/ScreenFrame.tsx b/marketing/product-film/src/components/ScreenFrame.tsx new file mode 100644 index 0000000..5f4b4ac --- /dev/null +++ b/marketing/product-film/src/components/ScreenFrame.tsx @@ -0,0 +1,48 @@ +import { useState } from "react"; +import { AbsoluteFill, staticFile } from "remotion"; +import { theme } from "../theme"; + +export const ScreenFrame: React.FC<{ + captureId: string; + scale?: number; +}> = ({ captureId, scale = 0.86 }) => { + const [errored, setErrored] = useState(false); + const src = staticFile(`captures/${captureId}.png`); + + return ( + +
+
+ + + + app.lynkeduppro.com +
+
+ {errored ? ( +
+ [capture missing: {captureId}] +
+ ) : ( + setErrored(true)} + style={{ width: "100%", height: "100%", objectFit: "cover", objectPosition: "top center", display: "block" }} + /> + )} +
+
+
+ ); +};