import { AbsoluteFill, useCurrentFrame, useVideoConfig, interpolate, spring, Img, staticFile, Sequence, } from "remotion"; import { Audio } from "@remotion/media"; import { MeetupCard } from "../../../components/MeetupCard"; // Spring configurations const SNAPPY = { damping: 15, stiffness: 80 }; // Stagger delay between meetup list items const LIST_ITEM_STAGGER = 10; // Upcoming meetup data const UPCOMING_MEETUPS = [ { name: "EINUNDZWANZIG Kempten", location: "Kempten im Allgäu", date: "Di, 28. Jan 2025", time: "19:00 Uhr", logoPath: "logos/EinundzwanzigKempten.jpg", isFeatured: true, }, { name: "EINUNDZWANZIG Memmingen", location: "Memmingen", date: "Mi, 29. Jan 2025", time: "19:30 Uhr", logoPath: "logos/EinundzwanzigMemmingen.jpg", isFeatured: false, }, { name: "EINUNDZWANZIG Friedrichshafen", location: "Friedrichshafen", date: "Do, 30. Jan 2025", time: "20:00 Uhr", logoPath: "logos/EinundzwanzigFriedrichshafen.png", isFeatured: false, }, ]; /** * MeetupShowcaseSceneMobile - Scene 4: Meine nächsten Meetup Termine for Mobile (12 seconds / 360 frames @ 30fps) * * Mobile layout adaptations: * - Vertical layout for featured meetup card (stacked info) * - Smaller card widths optimized for 1080px width * - Reduced text sizes and spacing * - Action buttons stacked vertically */ export const MeetupShowcaseSceneMobile: React.FC = () => { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); // 3D Perspective entrance animation (0-60 frames) const perspectiveSpring = spring({ frame, fps, config: { damping: 20, stiffness: 60 }, }); const perspectiveX = interpolate(perspectiveSpring, [0, 1], [20, 0]); const perspectiveScale = interpolate(perspectiveSpring, [0, 1], [0.9, 1]); const perspectiveOpacity = interpolate(perspectiveSpring, [0, 1], [0, 1]); // Header entrance animation (delayed) const headerDelay = Math.floor(0.3 * fps); const headerSpring = spring({ frame: frame - headerDelay, fps, config: SNAPPY, }); const headerOpacity = interpolate(headerSpring, [0, 1], [0, 1]); const headerY = interpolate(headerSpring, [0, 1], [-40, 0]); // Featured card entrance delay const featuredCardDelay = Math.floor(0.8 * fps); // Featured card 3D shadow animation const featuredSpring = spring({ frame: frame - featuredCardDelay, fps, config: { damping: 18, stiffness: 70 }, }); const featuredScale = interpolate(featuredSpring, [0, 1], [0.85, 1]); const featuredOpacity = interpolate(featuredSpring, [0, 1], [0, 1]); const featuredRotateX = interpolate(featuredSpring, [0, 1], [15, 0]); const featuredShadowY = interpolate(featuredSpring, [0, 1], [20, 40]); const featuredShadowBlur = interpolate(featuredSpring, [0, 1], [10, 60]); // Date/time info animation (after featured card) const dateDelay = featuredCardDelay + Math.floor(0.4 * fps); const dateSpring = spring({ frame: frame - dateDelay, fps, config: SNAPPY, }); const dateOpacity = interpolate(dateSpring, [0, 1], [0, 1]); const dateY = interpolate(dateSpring, [0, 1], [20, 0]); // Upcoming list header delay const listHeaderDelay = featuredCardDelay + Math.floor(1 * fps); const listHeaderSpring = spring({ frame: frame - listHeaderDelay, fps, config: SNAPPY, }); const listHeaderOpacity = interpolate(listHeaderSpring, [0, 1], [0, 1]); const listHeaderX = interpolate(listHeaderSpring, [0, 1], [-30, 0]); // Subtle glow pulse const glowIntensity = interpolate( Math.sin(frame * 0.05), [-1, 1], [0.3, 0.6] ); // Featured meetup data const featuredMeetup = UPCOMING_MEETUPS[0]; const upcomingMeetups = UPCOMING_MEETUPS.slice(1); return ( {/* Audio: slide-in for section entrance */} {/* Audio: card-slide for featured card */} {/* Audio: badge-appear for list items */} {/* Wallpaper Background */}
{/* Dark gradient overlay */}
{/* 3D Perspective Container */}
{/* Main Content - Centered for mobile */}
{/* Section Header */}

Meine nächsten Meetups

Kommende Bitcoin-Treffen in deiner Region

{/* Featured Meetup Card with 3D Shadow - Mobile optimized */}
{/* 3D Shadow beneath card */}
{/* Featured Meetup Card - Vertical layout for mobile */}
{/* Meetup Card Component */} {/* Date/Time Info - Below card for mobile */}
{/* Date */}
{featuredMeetup.date}
{/* Time */}
{featuredMeetup.time}
{/* Badge */}
Nächster Termin
{/* Upcoming Meetups Section */}
{/* Section Header */}

Weitere Termine

{/* Upcoming Meetups List - Vertical for mobile */}
{upcomingMeetups.map((meetup, index) => ( ))}
{/* Vignette overlay */}
); }; /** * Upcoming meetup list item for mobile */ type UpcomingMeetupItemMobileProps = { meetup: { name: string; location: string; date: string; time: string; logoPath: string; }; delay: number; glowIntensity: number; }; const UpcomingMeetupItemMobile: React.FC = ({ meetup, delay, glowIntensity, }) => { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); const adjustedFrame = Math.max(0, frame - delay); const itemSpring = spring({ frame: adjustedFrame, fps, config: SNAPPY, }); const itemOpacity = interpolate(itemSpring, [0, 1], [0, 1]); const itemY = interpolate(itemSpring, [0, 1], [30, 0]); const itemScale = interpolate(itemSpring, [0, 1], [0.9, 1]); return (
{/* Mini Logo */}
{/* Meetup Info */}
{meetup.name}
{meetup.date} {meetup.time}
); }; /** * Calendar icon SVG */ const CalendarIcon: React.FC = () => ( ); /** * Clock icon SVG */ const ClockIcon: React.FC = () => ( );