import React from 'react'; import { useCurrentFrame, useVideoConfig, interpolate, AbsoluteFill, Img, } from 'remotion'; // ============================================================================= // COMPOSITION CONFIG // ============================================================================= export const compositionConfig = { id: 'CoverScrollingGrid', durationInSeconds: 6, fps: 30, width: 2160, height: 2160, }; // ============================================================================= // STYLE CONSTANTS // ============================================================================= const COLORS = { primary: '#7C3AED', secondary: '#A78BFA', accent: '#C084FC', background: '#110A1F', text: '#FFFFFF', } as const; // ============================================================================= // GRID CONFIGURATION // ============================================================================= const TILE_SIZE = 940; const GAP = 24; const TILE_STEP = TILE_SIZE + GAP; const COLUMNS = 2; const TOTAL_GRID_WIDTH = COLUMNS * TILE_SIZE + (COLUMNS - 1) * GAP; const BORDER_RADIUS = 32; // Images — 4 per column const ALL_IMAGES = [ 'https://lumenor.ai/cdn-cgi/imagedelivery/F5KOmplEz0rStV2qDKhYag/ac7a7b98-88f1-4771-c8db-7db6aeed1700/tn', 'https://lumenor.ai/cdn-cgi/imagedelivery/F5KOmplEz0rStV2qDKhYag/9c34a520-4225-4798-e5c0-b8ef65f96800/tn', 'https://lumenor.ai/cdn-cgi/imagedelivery/F5KOmplEz0rStV2qDKhYag/578e7eeb-0766-40f8-498a-933f64158e00/tn', 'https://piktochart.com/wp-content/uploads/2023/11/paris-garbage-viral-ai-images.jpg', 'https://piktochart.com/wp-content/uploads/2023/11/jos-avery-viral-ai-images.jpg', 'https://lumenor.ai/cdn-cgi/imagedelivery/F5KOmplEz0rStV2qDKhYag/ad0a4b43-aa05-4c78-8a4f-e5f02638b100/tn', 'https://lumenor.ai/cdn-cgi/imagedelivery/F5KOmplEz0rStV2qDKhYag/d50f390c-a88b-4391-f81f-cf01329dfd00/tn', 'https://lumenor.ai/cdn-cgi/imagedelivery/F5KOmplEz0rStV2qDKhYag/ab2f27ea-ceaa-434d-bb34-6afd2ff51800/tn', ]; const COLUMN_IMAGES = [ [ALL_IMAGES[0], ALL_IMAGES[1], ALL_IMAGES[2], ALL_IMAGES[3]], [ALL_IMAGES[4], ALL_IMAGES[5], ALL_IMAGES[6], ALL_IMAGES[7]], ]; const TILES_PER_COL = COLUMN_IMAGES[0].length; const SET_HEIGHT = TILES_PER_COL * TILE_STEP; // Scroll speeds per column (px/sec) — varied for depth const SCROLL_SPEEDS = [340, 480]; // ============================================================================= // PRE-GENERATED DATA // ============================================================================= const seededRandom = (seed: number): number => { const x = Math.sin(seed * 9999) * 10000; return x - Math.floor(x); }; // ============================================================================= // SUB-COMPONENTS // ============================================================================= const ImageTile: React.FC<{ src: string; shimmerDelay: number; time: number; }> = ({ src, shimmerDelay, time }) => { const shimmerCycle = ((time + shimmerDelay) % 5) / 5; const shimmerX = interpolate(shimmerCycle, [0, 0.25, 0.65, 1], [-150, -150, 250, 250]); return (