import React from "react"; import {AbsoluteFill, Sequence, interpolate, spring, useCurrentFrame} from "remotion"; import {palette} from "./contract"; const C = palette; const a = (hex: string, opacity: number) => { const h = hex.replace("#", ""); return `rgba(${parseInt(h.slice(0, 2), 16)},${parseInt(h.slice(2, 4), 16)},${parseInt(h.slice(4, 6), 16)},${opacity})`; }; const ramp = (frame: number, start: number, end: number) => interpolate(frame, [start, end], [0, 1], {extrapolateLeft: "clamp", extrapolateRight: "clamp"}); const ease = (frame: number, delay = 0) => spring({frame: Math.max(0, frame - delay), fps: 30, config: {damping: 22, stiffness: 145, mass: 0.9}}); const Mark: React.FC<{size?: number; color?: string}> = ({size = 48, color = C.accent}) => ( ); const Check: React.FC<{size?: number; color?: string}> = ({size = 24, color = C.background}) => ( ); const Backdrop: React.FC = () => ( {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(i =>
)}
); const Header: React.FC = () => { const f = useCurrentFrame(); return
Relay
{[0, 1, 2].map(i =>
)}
; }; const IntroArt: React.FC<{frame: number}> = ({frame}) => { const p = ease(frame, 6); const tile = ease(frame, 18); return
{["M", "T", "W", "T", "F"].map((d, i) =>
{d}
)}
{[1, 2, 3, 4].map(i =>
)} {[0, 1, 2].map(i =>
)}
{["A", "J", "M"].map((v, i) =>
{v}
)}
; }; const Intro: React.FC = () => { const f = useCurrentFrame(); const exit = ramp(f, 78, 89); const p = ease(f, 2); const q = ease(f, 12); return
Relay.
Make room for
focused work
; }; const FeatureGlyph: React.FC<{index: number}> = ({index}) => {index === 0 ? <>{[0, 1, 2].map(i => )} : index === 1 ? <> : <>} ; const FeatureTitle: React.FC<{index: number}> = ({index}) => { const f = useCurrentFrame(); const p = ease(f); const out = ramp(f, 52, 59); const lines = [["Plan", "together"], ["Protect", "focus time"], ["See", "progress"]][index]; return
0{index + 1}/ 03
{lines[0]}
{lines[1]}
; }; const Avatar: React.FC<{letter: string; color: string; size?: number}> = ({letter, color, size = 32}) =>
{letter}
; const TaskCard: React.FC<{x: number; y: number; title: string; time: string; color: string; person: string; height?: number; opacity?: number}> = ({x, y, title, time, color, person, height = 106, opacity = 1}) =>
{title}
{time}
; const Calendar: React.FC<{frame: number}> = ({frame}) => { const focus = ease(frame, 63); const show = 1 - ramp(frame, 119, 132); return
{["Mon", "Tue", "Wed", "Thu"].map((day, i) =>
{day}{19 + i}
)} {["09:00", "11:00", "13:00", "15:00"].map((time, i) => {time}
)} 0.5 ? "14:00–15:00" : "11:00–12:00"} color={C.secondary} person="M" height={101} /> 0.5 ? "14:00–15:00" : "11:00–12:00"} color={C.secondary} person="A" height={101} /> {[0, 1].map(i =>
Focus time
11:00–13:00
)}
; }; const Progress: React.FC<{frame: number}> = ({frame}) => { const p = ease(frame, 126); const growth = ease(frame, 136); return
This week
{[{name: "Design", progress: 100, color: C.accent}, {name: "Build", progress: 75, color: C.secondary}, {name: "Launch", progress: 50, color: C.foreground}].map(item =>
{item.name}
{Math.round(item.progress * Math.min(1, growth))}%
)}
TasksStatus
{[{name: "Sprint plan", owner: "A", done: true}, {name: "Design review", owner: "J", done: true}, {name: "Build", owner: "M", done: false}].map((item, i) => { const q = ease(frame, 139 + i * 5); return
{item.done ? :
}
{item.name}
{item.done ? "Done" : "In progress"}
; })}
; }; const Product: React.FC = () => { const f = useCurrentFrame(); const p = ease(f); const out = ramp(f, 171, 179); const progress = f >= 125; return {[0, 1, 2].map(i => )}
Relay {progress ? "Progress" : "Week of May 19"}
{["Calendar", "Progress"].map((v, i) =>
{v}
)}
{["A", "J", "M"].map((letter, i) => )}
WORKSPACE
{["Week plan", "Team", "Projects"].map((label, i) =>
{label}
)}
Alex
; }; const Outro: React.FC = () => { const f = useCurrentFrame(); const p = ramp(f, 0, 12); const y = (1 - ramp(f, 0, 15)) * 27; const mark = ease(f); return
Start your next week
with Relay
{[0, 1, 2, 3, 4].map((i) =>
)}
; }; export const BenchmarkVideo: React.FC = () => { return
; };