/** * slowmo/recreate - Animation Recreation Skill * * This module provides AI-powered analysis and recreation of animations. * Feed it a video, GIF, or screenshots of an animation, and it will * generate code to recreate it in your preferred animation runtime. * * ## Supported AI Backends: * - Google Gemini (recommended for video understanding) * - OpenAI GPT-4 Vision * - Anthropic Claude * * ## Supported Output Runtimes: * - CSS Animations/Keyframes * - Framer Motion (React) * - GSAP * - Remotion (React video) * - Motion One * - Anime.js * - Three.js (3D animations) * - Lottie (export format) * * @example * import { recreate } from 'slowmo/recreate'; * * const code = await recreate({ * source: './animation.mp4', * runtime: 'framer-motion', * apiKey: process.env.GEMINI_API_KEY, * }); */ /** * Supported animation runtime targets */ export type AnimationRuntime = 'css' | 'framer-motion' | 'gsap' | 'remotion' | 'motion-one' | 'anime' | 'three' | 'lottie' | 'react-spring' | 'popmotion'; /** * Supported AI backends for analysis */ export type AIBackend = 'gemini' | 'openai' | 'anthropic'; /** * Source input types */ export type SourceInput = string | Blob | ArrayBuffer | File | HTMLVideoElement | HTMLCanvasElement; /** * Frame extraction options */ export interface FrameExtractionOptions { /** Frames per second to extract (default: 10) */ fps?: number; /** Maximum number of frames to extract (default: 30) */ maxFrames?: number; /** Image format for extracted frames */ format?: 'jpeg' | 'png' | 'webp'; /** Quality for lossy formats (0-1, default: 0.8) */ quality?: number; } /** * UI element detected in the animation */ export interface UIElement { /** Type of UI element */ type: 'button' | 'card' | 'panel' | 'input' | 'modal' | 'menu' | 'icon' | 'text' | 'image' | 'container' | 'other'; /** Role in the animation */ role: 'trigger' | 'animated' | 'container' | 'static'; /** Description of the element */ description: string; /** CSS-like properties (background, border, etc.) */ styles?: Record; /** Text content if visible */ text?: string; } /** * User interaction detected in the video */ export interface UserInteraction { /** Type of interaction */ type: 'click' | 'hover' | 'scroll' | 'drag' | 'keypress' | 'focus'; /** When in the video (normalized 0-1) */ timestamp: number; /** What element was interacted with */ target: string; /** Description of what happened */ description: string; } /** * Animation analysis result from AI */ export interface AnimationAnalysis { /** Human-readable description of the animation */ description: string; /** Duration estimate in seconds */ duration: number; /** Detected easing function */ easing: string; /** List of animated properties detected */ properties: AnimatedProperty[]; /** Keyframes with timing */ keyframes: Keyframe[]; /** Color palette detected */ colors: string[]; /** Overall animation style/category */ style: AnimationStyle; /** Confidence score (0-1) */ confidence: number; /** UI elements detected in the recording */ uiElements?: UIElement[]; /** User interactions visible in the recording */ interactions?: UserInteraction[]; /** Whether this is an interactive component (vs pure animation) */ isInteractive?: boolean; /** Raw AI response for debugging */ rawResponse?: string; } export interface AnimatedProperty { name: string; startValue: string | number; endValue: string | number; unit?: string; } export interface Keyframe { offset: number; properties: Record; easing?: string; } export type AnimationStyle = 'entrance' | 'exit' | 'attention' | 'background' | 'loading' | 'transition' | 'hover' | 'scroll' | 'parallax' | 'morphing' | 'particle' | 'physics' | 'custom'; /** * Code generation result */ export interface GeneratedCode { /** The generated animation code (CSS for interactive, full code otherwise) */ code: string; /** HTML structure (for interactive components) */ html?: string; /** JavaScript for interactivity */ javascript?: string; /** Runtime this code targets */ runtime: AnimationRuntime; /** Language of the code */ language: 'typescript' | 'javascript' | 'css' | 'json'; /** Required dependencies */ dependencies: string[]; /** Usage example */ usage: string; /** Additional notes or warnings */ notes?: string[]; /** Whether this is an interactive component */ isInteractive?: boolean; } /** * Main recreation options */ export interface RecreateOptions { /** Video, GIF, image(s), or URL to analyze */ source: SourceInput | SourceInput[]; /** Target animation runtime */ runtime: AnimationRuntime; /** AI backend to use (default: 'gemini') */ backend?: AIBackend; /** API key for the AI service */ apiKey: string; /** Custom API endpoint (for proxies or self-hosted) */ apiEndpoint?: string; /** Frame extraction options */ frameOptions?: FrameExtractionOptions; /** Additional context about the animation */ context?: string; /** Preferred coding style */ style?: 'minimal' | 'detailed' | 'production'; /** Include TypeScript types */ typescript?: boolean; /** Custom system prompt addition */ customPrompt?: string; } /** * Complete recreation result */ export interface RecreateResult { /** Analysis of the input animation */ analysis: AnimationAnalysis; /** Generated code for the target runtime */ code: GeneratedCode; /** Frames extracted for analysis */ frames?: string[]; /** Processing metadata */ meta: { processingTime: number; framesAnalyzed: number; backend: AIBackend; model: string; timing: { frameExtraction: number; analysis: number; codeGeneration: number; }; sourceInfo?: { sizeBytes: number; mimeType?: string; }; }; } interface RuntimePreset { name: string; description: string; language: 'typescript' | 'javascript' | 'css' | 'json'; dependencies: string[]; template: string; systemPrompt: string; examples: string[]; } declare const RUNTIME_PRESETS: Record; interface AIRequest { images: string[]; prompt: string; apiKey: string; endpoint?: string; } interface AIResponse { content: string; model: string; usage?: { inputTokens: number; outputTokens: number; }; } declare const AI_BACKENDS: Record Promise>; /** * Extract frames from a video element */ declare function extractFramesFromVideo(video: HTMLVideoElement, options?: FrameExtractionOptions): Promise; /** * Load source and extract frames for analysis */ declare function prepareFrames(source: SourceInput | SourceInput[], options?: FrameExtractionOptions): Promise; declare function buildAnalysisPrompt(runtime: AnimationRuntime, context?: string): string; declare function buildCodeGenerationPrompt(analysis: AnimationAnalysis, runtime: AnimationRuntime, options?: { style?: 'minimal' | 'detailed' | 'production'; typescript?: boolean; customPrompt?: string; }): string; /** * Recreate an animation from video/images using AI analysis. * * @example * const result = await recreate({ * source: './my-animation.mp4', * runtime: 'framer-motion', * apiKey: process.env.GEMINI_API_KEY, * }); * * console.log(result.code.code); */ export declare function recreate(options: RecreateOptions): Promise; /** * Quick recreation with minimal options */ export declare function quickRecreate(source: SourceInput | SourceInput[], runtime: AnimationRuntime, apiKey: string): Promise; /** * Analyze animation without generating code */ export declare function analyze(source: SourceInput | SourceInput[], apiKey: string, backend?: AIBackend): Promise; /** * Get available runtime presets */ export declare function getRuntimes(): Array<{ id: AnimationRuntime; name: string; description: string; }>; /** * Get details about a specific runtime */ export declare function getRuntimeInfo(runtime: AnimationRuntime): RuntimePreset | undefined; export { RUNTIME_PRESETS, AI_BACKENDS, extractFramesFromVideo, prepareFrames, buildAnalysisPrompt, buildCodeGenerationPrompt, }; export default recreate;