import React from "react"; import { AbsoluteFill, Img, interpolate, spring, useCurrentFrame, useVideoConfig } from "remotion"; import { CAPTION_FONT } from "../fonts"; /** Petit logo en haut à droite, hors des zones couvertes par l'interface des réseaux. */ export const Watermark: React.FC<{ logoUrl: string; until?: number | null }> = ({ logoUrl, until }) => { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); if (until != null && frame / fps >= until) return null; return ( ); }; /** * Effet de fin : l'image s'assombrit, le logo apparaît en grand puis le nom * du magasin glisse en dessous. */ export const Outro: React.FC<{ start: number; logoUrl?: string; storeName?: string; opaque?: boolean }> = ({ start, logoUrl, storeName, opaque = false, }) => { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); const local = frame - Math.round(start * fps); if (local < 0) return null; const enter = spring({ frame: local, fps, config: { damping: 18, stiffness: 90 }, durationInFrames: 24 }); const name = spring({ frame: local - 8, fps, config: { damping: 18, stiffness: 90 }, durationInFrames: 24 }); const dim = interpolate(local, [0, 12], [0, opaque ? 1 : 0.62], { extrapolateRight: "clamp" }); return ( {logoUrl && ( )} {storeName && (
{storeName}
)}
); }; /** Fondu au noir final. */ export const FadeOut: React.FC<{ start: number; duration: number }> = ({ start, duration }) => { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); const opacity = interpolate(frame / fps, [start, start + duration], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp", }); return opacity > 0 ? : null; };