import React from 'react'; import { useCurrentFrame, useVideoConfig, interpolate, Easing, AbsoluteFill } from 'remotion'; // ============================================================================= // COMPOSITION CONFIG (Required for auto-discovery) // ============================================================================= export const compositionConfig = { id: 'SpinningWheel60FPS', durationInSeconds: 4, fps: 60, width: 1920, height: 1080, }; // ============================================================================= // PRE-GENERATED DATA // ============================================================================= const SPOKE_COUNT = 12; const spokes = Array.from({ length: SPOKE_COUNT }, (_, i) => ({ id: i, angle: (360 / SPOKE_COUNT) * i, })); const TICK_MARKS = Array.from({ length: 60 }, (_, i) => ({ id: i, angle: (360 / 60) * i, isMajor: i % 5 === 0, })); // ============================================================================= // MAIN COMPONENT // ============================================================================= const SpinningWheel60FPS: React.FC = () => { const frame = useCurrentFrame(); const { fps, durationInFrames } = useVideoConfig(); // Wheel rotation - 2 full rotations over the duration const rotation = interpolate( frame, [0, durationInFrames], [0, 720], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', } ); // FPS badge pulse const badgePulse = interpolate( frame % 60, [0, 30, 60], [1, 1.05, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', } ); // Intro animation const introScale = interpolate( frame, [0, 40], [0.8, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.out(Easing.back(1.5)), } ); const introOpacity = interpolate( frame, [0, 30], [0, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', } ); return ( {/* Background grid */}
{/* Radial glow behind wheel */}
{/* Main wheel container */}
{/* Outer ring with tick marks */}
{/* Tick marks */} {TICK_MARKS.map((tick) => (
))}
{/* Spinning wheel */}
{/* Spokes */} {spokes.map((spoke, index) => (
))} {/* Center hub */}
{/* Inner dot */}
{/* Direction indicator (stationary) */}
{/* FPS Badge */}
60 FPS
{/* Frame counter */}
Frame
{String(frame).padStart(3, '0')}
{/* Rotation indicator */}
Rotation
{rotation.toFixed(1)}°
{/* Time indicator */}
Time
{(frame / fps).toFixed(2)}s
); }; export default SpinningWheel60FPS;