@json-render/remotion 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,8 +18,8 @@ function remotionPromptTemplate(context) {
18
18
  lines.push("");
19
19
  lines.push(`{"op":"set","path":"/composition","value":{"id":"intro","fps":30,"width":1920,"height":1080,"durationInFrames":300}}
20
20
  {"op":"set","path":"/tracks","value":[{"id":"main","name":"Main","type":"video","enabled":true},{"id":"overlay","name":"Overlay","type":"overlay","enabled":true}]}
21
- {"op":"set","path":"/clips/0","value":{"id":"clip-1","trackId":"main","component":"TitleCard","props":{"title":"Welcome","subtitle":"Getting Started"},"from":0,"durationInFrames":90,"transitionIn":{"type":"fade","durationInFrames":15},"transitionOut":{"type":"fade","durationInFrames":15}}}
22
- {"op":"set","path":"/clips/1","value":{"id":"clip-2","trackId":"main","component":"TitleCard","props":{"title":"Features"},"from":90,"durationInFrames":90}}
21
+ {"op":"set","path":"/clips/0","value":{"id":"clip-1","trackId":"main","component":"TitleCard","props":{"title":"Welcome","subtitle":"Getting Started"},"from":0,"durationInFrames":90,"transitionIn":{"type":"fade","durationInFrames":15},"transitionOut":{"type":"fade","durationInFrames":15},"motion":{"enter":{"opacity":0,"y":50,"scale":0.9,"duration":25},"spring":{"damping":15}}}}
22
+ {"op":"set","path":"/clips/1","value":{"id":"clip-2","trackId":"main","component":"TitleCard","props":{"title":"Features"},"from":90,"durationInFrames":90,"motion":{"enter":{"opacity":0,"x":-100,"duration":20},"exit":{"opacity":0,"x":100,"duration":15}}}}
23
23
  {"op":"set","path":"/audio","value":{"tracks":[]}}`);
24
24
  lines.push("");
25
25
  const catalogData = catalog;
@@ -44,6 +44,36 @@ function remotionPromptTemplate(context) {
44
44
  }
45
45
  lines.push("");
46
46
  }
47
+ lines.push("MOTION SYSTEM:");
48
+ lines.push(
49
+ "Clips can have a 'motion' field for declarative animations (optional, use for dynamic/engaging videos):"
50
+ );
51
+ lines.push("");
52
+ lines.push(
53
+ "- enter: {opacity?, scale?, x?, y?, rotate?, duration?} - animate FROM these values TO normal when clip starts"
54
+ );
55
+ lines.push(
56
+ "- exit: {opacity?, scale?, x?, y?, rotate?, duration?} - animate FROM normal TO these values when clip ends"
57
+ );
58
+ lines.push(
59
+ "- spring: {damping?, stiffness?, mass?} - physics config (lower damping = more bounce)"
60
+ );
61
+ lines.push(
62
+ '- loop: {property, from, to, duration, easing?} - continuous animation (property: "scale"|"rotate"|"x"|"y"|"opacity")'
63
+ );
64
+ lines.push("");
65
+ lines.push("Example motion configs:");
66
+ lines.push(' Fade up: {"enter":{"opacity":0,"y":30,"duration":20}}');
67
+ lines.push(
68
+ ' Scale pop: {"enter":{"scale":0.5,"opacity":0,"duration":15},"spring":{"damping":10}}'
69
+ );
70
+ lines.push(
71
+ ' Slide in/out: {"enter":{"x":-100,"duration":20},"exit":{"x":100,"duration":15}}'
72
+ );
73
+ lines.push(
74
+ ' Gentle pulse: {"loop":{"property":"scale","from":1,"to":1.05,"duration":60,"easing":"ease"}}'
75
+ );
76
+ lines.push("");
47
77
  lines.push("RULES:");
48
78
  const baseRules = [
49
79
  "Output ONLY JSONL patches - one JSON object per line, no markdown, no code fences",
@@ -54,7 +84,9 @@ function remotionPromptTemplate(context) {
54
84
  "ONLY use components listed above",
55
85
  "fps is always 30 (1 second = 30 frames, 10 seconds = 300 frames)",
56
86
  `Clips on "main" track flow sequentially (from = previous clip's from + durationInFrames)`,
57
- 'Overlay clips (LowerThird, TextOverlay) go on "overlay" track'
87
+ 'Overlay clips (LowerThird, TextOverlay) go on "overlay" track',
88
+ "Use motion.enter for engaging clip entrances, motion.exit for smooth departures",
89
+ "Spring damping: 20=smooth, 10=bouncy, 5=very bouncy"
58
90
  ];
59
91
  const allRules = [...baseRules, ...customRules];
60
92
  allRules.forEach((rule, i) => {
@@ -116,6 +148,61 @@ var schema = defineSchema(
116
148
  transitionOut: s.object({
117
149
  type: s.ref("catalog.transitions"),
118
150
  durationInFrames: s.number()
151
+ }),
152
+ /** Declarative motion configuration for custom animations */
153
+ motion: s.object({
154
+ /** Enter animation - animates FROM these values TO neutral */
155
+ enter: s.object({
156
+ /** Starting opacity (0-1), animates to 1 */
157
+ opacity: s.number(),
158
+ /** Starting scale (e.g., 0.8 = 80%), animates to 1 */
159
+ scale: s.number(),
160
+ /** Starting X offset in pixels, animates to 0 */
161
+ x: s.number(),
162
+ /** Starting Y offset in pixels, animates to 0 */
163
+ y: s.number(),
164
+ /** Starting rotation in degrees, animates to 0 */
165
+ rotate: s.number(),
166
+ /** Duration of enter animation in frames (default: 20) */
167
+ duration: s.number()
168
+ }),
169
+ /** Exit animation - animates FROM neutral TO these values */
170
+ exit: s.object({
171
+ /** Ending opacity (0-1), animates from 1 */
172
+ opacity: s.number(),
173
+ /** Ending scale, animates from 1 */
174
+ scale: s.number(),
175
+ /** Ending X offset in pixels, animates from 0 */
176
+ x: s.number(),
177
+ /** Ending Y offset in pixels, animates from 0 */
178
+ y: s.number(),
179
+ /** Ending rotation in degrees, animates from 0 */
180
+ rotate: s.number(),
181
+ /** Duration of exit animation in frames (default: 20) */
182
+ duration: s.number()
183
+ }),
184
+ /** Spring physics configuration */
185
+ spring: s.object({
186
+ /** Damping coefficient (default: 20) */
187
+ damping: s.number(),
188
+ /** Stiffness (default: 100) */
189
+ stiffness: s.number(),
190
+ /** Mass (default: 1) */
191
+ mass: s.number()
192
+ }),
193
+ /** Continuous looping animation */
194
+ loop: s.object({
195
+ /** Property to animate: "scale" | "rotate" | "x" | "y" | "opacity" */
196
+ property: s.string(),
197
+ /** Starting value */
198
+ from: s.number(),
199
+ /** Ending value */
200
+ to: s.number(),
201
+ /** Duration of one cycle in frames */
202
+ duration: s.number(),
203
+ /** Easing type: "linear" | "ease" | "spring" (default: "ease") */
204
+ easing: s.string()
205
+ })
119
206
  })
120
207
  })
121
208
  ),
@@ -210,11 +297,13 @@ var standardComponentDefinitions = {
210
297
  props: z.object({
211
298
  quote: z.string(),
212
299
  author: z.string().nullable(),
213
- backgroundColor: z.string().nullable()
300
+ backgroundColor: z.string().nullable(),
301
+ textColor: z.string().nullable(),
302
+ transparent: z.boolean().nullable()
214
303
  }),
215
304
  type: "scene",
216
305
  defaultDuration: 150,
217
- description: "Quote display with attribution. Use for testimonials."
306
+ description: "Quote display with author. Props: quote, author, textColor, backgroundColor. Set transparent:true when using as overlay on images."
218
307
  },
219
308
  StatCard: {
220
309
  props: z.object({
@@ -353,4 +442,4 @@ export {
353
442
  standardTransitionDefinitions,
354
443
  standardEffectDefinitions
355
444
  };
356
- //# sourceMappingURL=chunk-5C3GTKV7.mjs.map
445
+ //# sourceMappingURL=chunk-VFMY2U5W.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schema.ts","../src/catalog/definitions.ts"],"sourcesContent":["import { defineSchema, type PromptContext } from \"@json-render/core\";\n\n/**\n * Prompt template for Remotion timeline generation\n *\n * Uses JSONL patch format (same as React) but builds up a timeline spec structure.\n */\nfunction remotionPromptTemplate(context: PromptContext): string {\n const { catalog, options } = context;\n const { system = \"You are a video timeline generator.\", customRules = [] } =\n options;\n\n const lines: string[] = [];\n lines.push(system);\n lines.push(\"\");\n\n // Output format - JSONL patches\n lines.push(\"OUTPUT FORMAT:\");\n lines.push(\n \"Output JSONL (one JSON object per line) with patches to build a timeline spec.\",\n );\n lines.push(\n \"Each line is a JSON patch operation. Build the timeline incrementally.\",\n );\n lines.push(\"\");\n lines.push(\"Example output (each line is a separate JSON object):\");\n lines.push(\"\");\n lines.push(`{\"op\":\"set\",\"path\":\"/composition\",\"value\":{\"id\":\"intro\",\"fps\":30,\"width\":1920,\"height\":1080,\"durationInFrames\":300}}\n{\"op\":\"set\",\"path\":\"/tracks\",\"value\":[{\"id\":\"main\",\"name\":\"Main\",\"type\":\"video\",\"enabled\":true},{\"id\":\"overlay\",\"name\":\"Overlay\",\"type\":\"overlay\",\"enabled\":true}]}\n{\"op\":\"set\",\"path\":\"/clips/0\",\"value\":{\"id\":\"clip-1\",\"trackId\":\"main\",\"component\":\"TitleCard\",\"props\":{\"title\":\"Welcome\",\"subtitle\":\"Getting Started\"},\"from\":0,\"durationInFrames\":90,\"transitionIn\":{\"type\":\"fade\",\"durationInFrames\":15},\"transitionOut\":{\"type\":\"fade\",\"durationInFrames\":15},\"motion\":{\"enter\":{\"opacity\":0,\"y\":50,\"scale\":0.9,\"duration\":25},\"spring\":{\"damping\":15}}}}\n{\"op\":\"set\",\"path\":\"/clips/1\",\"value\":{\"id\":\"clip-2\",\"trackId\":\"main\",\"component\":\"TitleCard\",\"props\":{\"title\":\"Features\"},\"from\":90,\"durationInFrames\":90,\"motion\":{\"enter\":{\"opacity\":0,\"x\":-100,\"duration\":20},\"exit\":{\"opacity\":0,\"x\":100,\"duration\":15}}}}\n{\"op\":\"set\",\"path\":\"/audio\",\"value\":{\"tracks\":[]}}`);\n lines.push(\"\");\n\n // Components\n const catalogData = catalog as {\n components?: Record<\n string,\n { description?: string; defaultDuration?: number }\n >;\n transitions?: Record<string, { description?: string }>;\n effects?: Record<string, { description?: string }>;\n };\n\n if (catalogData.components) {\n lines.push(\n `AVAILABLE COMPONENTS (${Object.keys(catalogData.components).length}):`,\n );\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.components)) {\n const duration = def.defaultDuration\n ? ` [default: ${def.defaultDuration} frames]`\n : \"\";\n lines.push(\n `- ${name}: ${def.description || \"No description\"}${duration}`,\n );\n }\n lines.push(\"\");\n }\n\n // Transitions\n if (\n catalogData.transitions &&\n Object.keys(catalogData.transitions).length > 0\n ) {\n lines.push(\"AVAILABLE TRANSITIONS:\");\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.transitions)) {\n lines.push(`- ${name}: ${def.description || \"No description\"}`);\n }\n lines.push(\"\");\n }\n\n // Motion system documentation\n lines.push(\"MOTION SYSTEM:\");\n lines.push(\n \"Clips can have a 'motion' field for declarative animations (optional, use for dynamic/engaging videos):\",\n );\n lines.push(\"\");\n lines.push(\n \"- enter: {opacity?, scale?, x?, y?, rotate?, duration?} - animate FROM these values TO normal when clip starts\",\n );\n lines.push(\n \"- exit: {opacity?, scale?, x?, y?, rotate?, duration?} - animate FROM normal TO these values when clip ends\",\n );\n lines.push(\n \"- spring: {damping?, stiffness?, mass?} - physics config (lower damping = more bounce)\",\n );\n lines.push(\n '- loop: {property, from, to, duration, easing?} - continuous animation (property: \"scale\"|\"rotate\"|\"x\"|\"y\"|\"opacity\")',\n );\n lines.push(\"\");\n lines.push(\"Example motion configs:\");\n lines.push(' Fade up: {\"enter\":{\"opacity\":0,\"y\":30,\"duration\":20}}');\n lines.push(\n ' Scale pop: {\"enter\":{\"scale\":0.5,\"opacity\":0,\"duration\":15},\"spring\":{\"damping\":10}}',\n );\n lines.push(\n ' Slide in/out: {\"enter\":{\"x\":-100,\"duration\":20},\"exit\":{\"x\":100,\"duration\":15}}',\n );\n lines.push(\n ' Gentle pulse: {\"loop\":{\"property\":\"scale\",\"from\":1,\"to\":1.05,\"duration\":60,\"easing\":\"ease\"}}',\n );\n lines.push(\"\");\n\n // Rules\n lines.push(\"RULES:\");\n const baseRules = [\n \"Output ONLY JSONL patches - one JSON object per line, no markdown, no code fences\",\n \"First set /composition with {id, fps:30, width:1920, height:1080, durationInFrames}\",\n \"Then set /tracks array with video/overlay tracks\",\n \"Then set each clip: /clips/0, /clips/1, etc.\",\n \"Finally set /audio with {tracks:[]}\",\n \"ONLY use components listed above\",\n \"fps is always 30 (1 second = 30 frames, 10 seconds = 300 frames)\",\n 'Clips on \"main\" track flow sequentially (from = previous clip\\'s from + durationInFrames)',\n 'Overlay clips (LowerThird, TextOverlay) go on \"overlay\" track',\n \"Use motion.enter for engaging clip entrances, motion.exit for smooth departures\",\n \"Spring damping: 20=smooth, 10=bouncy, 5=very bouncy\",\n ];\n const allRules = [...baseRules, ...customRules];\n allRules.forEach((rule, i) => {\n lines.push(`${i + 1}. ${rule}`);\n });\n\n return lines.join(\"\\n\");\n}\n\n/**\n * The schema for @json-render/remotion\n *\n * This schema is fundamentally different from the React element tree schema.\n * It's timeline-based, designed for video composition:\n *\n * - Spec: A composition with tracks containing timed clips\n * - Catalog: Video components (scenes, overlays, etc.) and effects\n *\n * This demonstrates that json-render is truly agnostic - different renderers\n * can have completely different spec formats.\n */\nexport const schema = defineSchema(\n (s) => ({\n // What the AI-generated SPEC looks like (timeline-based)\n spec: s.object({\n /** Composition settings */\n composition: s.object({\n /** Unique composition ID */\n id: s.string(),\n /** Frames per second */\n fps: s.number(),\n /** Width in pixels */\n width: s.number(),\n /** Height in pixels */\n height: s.number(),\n /** Total duration in frames */\n durationInFrames: s.number(),\n }),\n\n /** Timeline tracks (like layers in video editing) */\n tracks: s.array(\n s.object({\n /** Unique track ID */\n id: s.string(),\n /** Track name for organization */\n name: s.string(),\n /** Track type: \"video\" | \"audio\" | \"overlay\" | \"text\" */\n type: s.string(),\n /** Whether track is muted/hidden */\n enabled: s.boolean(),\n }),\n ),\n\n /** Clips placed on the timeline */\n clips: s.array(\n s.object({\n /** Unique clip ID */\n id: s.string(),\n /** Which track this clip belongs to */\n trackId: s.string(),\n /** Component type from catalog */\n component: s.ref(\"catalog.components\"),\n /** Component props */\n props: s.propsOf(\"catalog.components\"),\n /** Start frame (when clip begins) */\n from: s.number(),\n /** Duration in frames */\n durationInFrames: s.number(),\n /** Transition in effect */\n transitionIn: s.object({\n type: s.ref(\"catalog.transitions\"),\n durationInFrames: s.number(),\n }),\n /** Transition out effect */\n transitionOut: s.object({\n type: s.ref(\"catalog.transitions\"),\n durationInFrames: s.number(),\n }),\n /** Declarative motion configuration for custom animations */\n motion: s.object({\n /** Enter animation - animates FROM these values TO neutral */\n enter: s.object({\n /** Starting opacity (0-1), animates to 1 */\n opacity: s.number(),\n /** Starting scale (e.g., 0.8 = 80%), animates to 1 */\n scale: s.number(),\n /** Starting X offset in pixels, animates to 0 */\n x: s.number(),\n /** Starting Y offset in pixels, animates to 0 */\n y: s.number(),\n /** Starting rotation in degrees, animates to 0 */\n rotate: s.number(),\n /** Duration of enter animation in frames (default: 20) */\n duration: s.number(),\n }),\n /** Exit animation - animates FROM neutral TO these values */\n exit: s.object({\n /** Ending opacity (0-1), animates from 1 */\n opacity: s.number(),\n /** Ending scale, animates from 1 */\n scale: s.number(),\n /** Ending X offset in pixels, animates from 0 */\n x: s.number(),\n /** Ending Y offset in pixels, animates from 0 */\n y: s.number(),\n /** Ending rotation in degrees, animates from 0 */\n rotate: s.number(),\n /** Duration of exit animation in frames (default: 20) */\n duration: s.number(),\n }),\n /** Spring physics configuration */\n spring: s.object({\n /** Damping coefficient (default: 20) */\n damping: s.number(),\n /** Stiffness (default: 100) */\n stiffness: s.number(),\n /** Mass (default: 1) */\n mass: s.number(),\n }),\n /** Continuous looping animation */\n loop: s.object({\n /** Property to animate: \"scale\" | \"rotate\" | \"x\" | \"y\" | \"opacity\" */\n property: s.string(),\n /** Starting value */\n from: s.number(),\n /** Ending value */\n to: s.number(),\n /** Duration of one cycle in frames */\n duration: s.number(),\n /** Easing type: \"linear\" | \"ease\" | \"spring\" (default: \"ease\") */\n easing: s.string(),\n }),\n }),\n }),\n ),\n\n /** Audio configuration */\n audio: s.object({\n /** Background music/audio clips */\n tracks: s.array(\n s.object({\n id: s.string(),\n src: s.string(),\n from: s.number(),\n durationInFrames: s.number(),\n volume: s.number(),\n }),\n ),\n }),\n }),\n\n // What the CATALOG must provide\n catalog: s.object({\n /** Video component definitions (scenes, overlays, etc.) */\n components: s.map({\n /** Zod schema for component props */\n props: s.zod(),\n /** Component type: \"scene\" | \"overlay\" | \"text\" | \"image\" | \"video\" */\n type: s.string(),\n /** Default duration in frames (can be overridden per clip) */\n defaultDuration: s.number(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n /** Transition effect definitions */\n transitions: s.map({\n /** Default duration in frames */\n defaultDuration: s.number(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n /** Effect definitions (filters, animations, etc.) */\n effects: s.map({\n /** Zod schema for effect params */\n params: s.zod(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n }),\n }),\n {\n promptTemplate: remotionPromptTemplate,\n },\n);\n\n/**\n * Type for the Remotion schema\n */\nexport type RemotionSchema = typeof schema;\n\n/**\n * Infer the spec type from a catalog\n */\nexport type RemotionSpec<TCatalog> = typeof schema extends {\n createCatalog: (catalog: TCatalog) => { _specType: infer S };\n}\n ? S\n : never;\n","import { z } from \"zod\";\n\n/**\n * Standard component definitions for Remotion catalogs\n *\n * These can be used directly or extended with custom components.\n */\nexport const standardComponentDefinitions = {\n // ==========================================================================\n // Scene Components (full-screen)\n // ==========================================================================\n\n TitleCard: {\n props: z.object({\n title: z.string(),\n subtitle: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 90,\n description:\n \"Full-screen title card with centered text. Use for intros, outros, and section breaks.\",\n },\n\n ImageSlide: {\n props: z.object({\n src: z.string(),\n alt: z.string(),\n fit: z.enum([\"cover\", \"contain\"]).nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"image\",\n defaultDuration: 150,\n description:\n \"Full-screen image display. Use for product shots, photos, and visual content.\",\n },\n\n SplitScreen: {\n props: z.object({\n leftTitle: z.string(),\n rightTitle: z.string(),\n leftColor: z.string().nullable(),\n rightColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 120,\n description:\n \"Split screen with two sides. Use for comparisons or before/after.\",\n },\n\n QuoteCard: {\n props: z.object({\n quote: z.string(),\n author: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n transparent: z.boolean().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 150,\n description:\n \"Quote display with author. Props: quote, author, textColor, backgroundColor. Set transparent:true when using as overlay on images.\",\n },\n\n StatCard: {\n props: z.object({\n value: z.string(),\n label: z.string(),\n prefix: z.string().nullable(),\n suffix: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 90,\n description: \"Large statistic display. Use for key metrics and numbers.\",\n },\n\n TypingText: {\n props: z.object({\n text: z.string(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n fontSize: z.number().nullable(),\n fontFamily: z.enum([\"monospace\", \"sans-serif\", \"serif\"]).nullable(),\n showCursor: z.boolean().nullable(),\n cursorChar: z.string().nullable(),\n charsPerSecond: z.number().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 180,\n description:\n \"Terminal-style typing animation that reveals text character by character. Perfect for code demos, CLI commands, and dramatic text reveals.\",\n },\n\n // ==========================================================================\n // Overlay Components\n // ==========================================================================\n\n LowerThird: {\n props: z.object({\n name: z.string(),\n title: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 120,\n description:\n \"Name/title overlay in lower third of screen. Use to identify speakers.\",\n },\n\n TextOverlay: {\n props: z.object({\n text: z.string(),\n position: z.enum([\"top\", \"center\", \"bottom\"]).nullable(),\n fontSize: z.enum([\"small\", \"medium\", \"large\"]).nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 90,\n description: \"Simple text overlay. Use for captions and annotations.\",\n },\n\n LogoBug: {\n props: z.object({\n position: z\n .enum([\"top-left\", \"top-right\", \"bottom-left\", \"bottom-right\"])\n .nullable(),\n opacity: z.number().nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 300,\n description: \"Corner logo watermark. Use for branding throughout video.\",\n },\n\n // ==========================================================================\n // Video Components\n // ==========================================================================\n\n VideoClip: {\n props: z.object({\n src: z.string(),\n startFrom: z.number().nullable(),\n volume: z.number().nullable(),\n }),\n type: \"video\",\n defaultDuration: 150,\n description: \"Video file playback. Use for B-roll and footage.\",\n },\n};\n\n/**\n * Standard transition definitions for Remotion catalogs\n */\nexport const standardTransitionDefinitions = {\n fade: {\n defaultDuration: 15,\n description: \"Smooth fade in/out. Use for gentle transitions.\",\n },\n slideLeft: {\n defaultDuration: 20,\n description: \"Slide from right to left. Use for forward progression.\",\n },\n slideRight: {\n defaultDuration: 20,\n description: \"Slide from left to right. Use for backward progression.\",\n },\n slideUp: {\n defaultDuration: 15,\n description: \"Slide from bottom to top. Use for overlays appearing.\",\n },\n slideDown: {\n defaultDuration: 15,\n description: \"Slide from top to bottom. Use for overlays disappearing.\",\n },\n zoom: {\n defaultDuration: 20,\n description: \"Zoom in/out effect. Use for emphasis.\",\n },\n wipe: {\n defaultDuration: 15,\n description: \"Horizontal wipe. Use for scene changes.\",\n },\n none: {\n defaultDuration: 0,\n description: \"No transition (hard cut).\",\n },\n};\n\n/**\n * Standard effect definitions for Remotion catalogs\n */\nexport const standardEffectDefinitions = {\n kenBurns: {\n params: z.object({\n startScale: z.number(),\n endScale: z.number(),\n panX: z.number().nullable(),\n panY: z.number().nullable(),\n }),\n description: \"Ken Burns pan and zoom effect for images.\",\n },\n pulse: {\n params: z.object({\n intensity: z.number(),\n }),\n description: \"Subtle pulsing scale effect for emphasis.\",\n },\n shake: {\n params: z.object({\n intensity: z.number(),\n }),\n description: \"Camera shake effect for energy.\",\n },\n};\n\n/**\n * Type for component definition\n */\nexport type ComponentDefinition = {\n props: z.ZodType;\n type: string;\n defaultDuration: number;\n description: string;\n};\n\n/**\n * Type for transition definition\n */\nexport type TransitionDefinition = {\n defaultDuration: number;\n description: string;\n};\n\n/**\n * Type for effect definition\n */\nexport type EffectDefinition = {\n params: z.ZodType;\n description: string;\n};\n"],"mappings":"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","names":[]}
package/dist/index.d.mts CHANGED
@@ -7,6 +7,73 @@ import 'react';
7
7
  /**
8
8
  * Types for Remotion timeline components
9
9
  */
10
+ /**
11
+ * Motion state for enter/exit animations
12
+ * Values animate FROM these values TO neutral (enter) or FROM neutral TO these values (exit)
13
+ */
14
+ interface MotionState {
15
+ /** Opacity (0-1), default: 1 */
16
+ opacity?: number;
17
+ /** Scale multiplier (0.8 = 80%), default: 1 */
18
+ scale?: number;
19
+ /** Translate X in pixels, default: 0 */
20
+ x?: number;
21
+ /** Translate Y in pixels, default: 0 */
22
+ y?: number;
23
+ /** Rotation in degrees, default: 0 */
24
+ rotate?: number;
25
+ /** Duration in frames, default: 20 */
26
+ duration?: number;
27
+ }
28
+ /**
29
+ * Spring physics configuration
30
+ */
31
+ interface SpringConfig {
32
+ /** Damping coefficient, default: 20 */
33
+ damping?: number;
34
+ /** Stiffness, default: 100 */
35
+ stiffness?: number;
36
+ /** Mass, default: 1 */
37
+ mass?: number;
38
+ }
39
+ /**
40
+ * Continuous loop animation
41
+ */
42
+ interface MotionLoop {
43
+ /** Property to animate */
44
+ property: "scale" | "rotate" | "x" | "y" | "opacity";
45
+ /** Starting value */
46
+ from: number;
47
+ /** Ending value */
48
+ to: number;
49
+ /** Duration of one cycle in frames */
50
+ duration: number;
51
+ /** Easing type, default: "ease" */
52
+ easing?: "linear" | "ease" | "spring";
53
+ }
54
+ /**
55
+ * Declarative motion configuration for clips
56
+ */
57
+ interface Motion {
58
+ /** Enter animation - animates FROM these values TO neutral */
59
+ enter?: MotionState;
60
+ /** Exit animation - animates FROM neutral TO these values */
61
+ exit?: MotionState;
62
+ /** Spring physics config (applies to enter/exit) */
63
+ spring?: SpringConfig;
64
+ /** Continuous looping animation */
65
+ loop?: MotionLoop;
66
+ }
67
+ /**
68
+ * Motion styles calculated by useMotion hook
69
+ */
70
+ interface MotionStyles {
71
+ opacity: number;
72
+ translateX: number;
73
+ translateY: number;
74
+ scale: number;
75
+ rotate: number;
76
+ }
10
77
  /**
11
78
  * Clip data passed to components
12
79
  */
@@ -25,6 +92,8 @@ interface Clip {
25
92
  type: string;
26
93
  durationInFrames: number;
27
94
  };
95
+ /** Declarative motion configuration */
96
+ motion?: Motion;
28
97
  }
29
98
  /**
30
99
  * Timeline spec structure
@@ -89,15 +158,31 @@ type ComponentRegistry = Record<string, ClipComponent>;
89
158
  * - wipe
90
159
  */
91
160
  declare function useTransition(clip: Clip, frame: number): TransitionStyles;
161
+ /**
162
+ * Calculate motion styles based on clip's motion configuration
163
+ *
164
+ * Handles declarative motion:
165
+ * - enter: animate FROM values TO neutral
166
+ * - exit: animate FROM neutral TO values
167
+ * - loop: continuous animation during clip lifetime
168
+ * - spring: physics-based easing
169
+ */
170
+ declare function useMotion(clip: Clip, frame: number): MotionStyles;
92
171
 
93
172
  interface ClipWrapperProps {
94
173
  clip: Clip;
95
174
  children: React.ReactNode;
96
175
  }
97
176
  /**
98
- * Wrapper component that applies transition animations to clips
177
+ * Wrapper component that applies transition and motion animations to clips
178
+ *
179
+ * Automatically handles:
180
+ * - transitionIn/transitionOut: basic transition presets (fade, slide, zoom, etc.)
181
+ * - motion: declarative enter/exit/loop animations with spring physics
99
182
  *
100
- * Automatically handles transitionIn and transitionOut based on clip config.
183
+ * Transitions and motion compose together:
184
+ * - Opacity: multiplied (both affect final opacity)
185
+ * - Transforms: added (both contribute to final position/scale/rotation)
101
186
  */
102
187
  declare function ClipWrapper({ clip, children }: ClipWrapperProps): react_jsx_runtime.JSX.Element;
103
188
 
@@ -163,4 +248,4 @@ interface RendererProps {
163
248
  */
164
249
  declare function Renderer({ spec, components: customComponents, }: RendererProps): react_jsx_runtime.JSX.Element;
165
250
 
166
- export { type AudioTrack, type Clip, type ClipComponent, ClipWrapper, type ComponentRegistry, ImageSlide, LogoBug, LowerThird, QuoteCard, Renderer, SplitScreen, StatCard, TextOverlay, type TimelineSpec, TitleCard, type TransitionStyles, TypingText, VideoClip, standardComponents, useTransition };
251
+ export { type AudioTrack, type Clip, type ClipComponent, ClipWrapper, type ComponentRegistry, ImageSlide, LogoBug, LowerThird, type Motion, type MotionLoop, type MotionState, type MotionStyles, QuoteCard, Renderer, SplitScreen, type SpringConfig, StatCard, TextOverlay, type TimelineSpec, TitleCard, type TransitionStyles, TypingText, VideoClip, standardComponents, useMotion, useTransition };
package/dist/index.d.ts CHANGED
@@ -7,6 +7,73 @@ import 'react';
7
7
  /**
8
8
  * Types for Remotion timeline components
9
9
  */
10
+ /**
11
+ * Motion state for enter/exit animations
12
+ * Values animate FROM these values TO neutral (enter) or FROM neutral TO these values (exit)
13
+ */
14
+ interface MotionState {
15
+ /** Opacity (0-1), default: 1 */
16
+ opacity?: number;
17
+ /** Scale multiplier (0.8 = 80%), default: 1 */
18
+ scale?: number;
19
+ /** Translate X in pixels, default: 0 */
20
+ x?: number;
21
+ /** Translate Y in pixels, default: 0 */
22
+ y?: number;
23
+ /** Rotation in degrees, default: 0 */
24
+ rotate?: number;
25
+ /** Duration in frames, default: 20 */
26
+ duration?: number;
27
+ }
28
+ /**
29
+ * Spring physics configuration
30
+ */
31
+ interface SpringConfig {
32
+ /** Damping coefficient, default: 20 */
33
+ damping?: number;
34
+ /** Stiffness, default: 100 */
35
+ stiffness?: number;
36
+ /** Mass, default: 1 */
37
+ mass?: number;
38
+ }
39
+ /**
40
+ * Continuous loop animation
41
+ */
42
+ interface MotionLoop {
43
+ /** Property to animate */
44
+ property: "scale" | "rotate" | "x" | "y" | "opacity";
45
+ /** Starting value */
46
+ from: number;
47
+ /** Ending value */
48
+ to: number;
49
+ /** Duration of one cycle in frames */
50
+ duration: number;
51
+ /** Easing type, default: "ease" */
52
+ easing?: "linear" | "ease" | "spring";
53
+ }
54
+ /**
55
+ * Declarative motion configuration for clips
56
+ */
57
+ interface Motion {
58
+ /** Enter animation - animates FROM these values TO neutral */
59
+ enter?: MotionState;
60
+ /** Exit animation - animates FROM neutral TO these values */
61
+ exit?: MotionState;
62
+ /** Spring physics config (applies to enter/exit) */
63
+ spring?: SpringConfig;
64
+ /** Continuous looping animation */
65
+ loop?: MotionLoop;
66
+ }
67
+ /**
68
+ * Motion styles calculated by useMotion hook
69
+ */
70
+ interface MotionStyles {
71
+ opacity: number;
72
+ translateX: number;
73
+ translateY: number;
74
+ scale: number;
75
+ rotate: number;
76
+ }
10
77
  /**
11
78
  * Clip data passed to components
12
79
  */
@@ -25,6 +92,8 @@ interface Clip {
25
92
  type: string;
26
93
  durationInFrames: number;
27
94
  };
95
+ /** Declarative motion configuration */
96
+ motion?: Motion;
28
97
  }
29
98
  /**
30
99
  * Timeline spec structure
@@ -89,15 +158,31 @@ type ComponentRegistry = Record<string, ClipComponent>;
89
158
  * - wipe
90
159
  */
91
160
  declare function useTransition(clip: Clip, frame: number): TransitionStyles;
161
+ /**
162
+ * Calculate motion styles based on clip's motion configuration
163
+ *
164
+ * Handles declarative motion:
165
+ * - enter: animate FROM values TO neutral
166
+ * - exit: animate FROM neutral TO values
167
+ * - loop: continuous animation during clip lifetime
168
+ * - spring: physics-based easing
169
+ */
170
+ declare function useMotion(clip: Clip, frame: number): MotionStyles;
92
171
 
93
172
  interface ClipWrapperProps {
94
173
  clip: Clip;
95
174
  children: React.ReactNode;
96
175
  }
97
176
  /**
98
- * Wrapper component that applies transition animations to clips
177
+ * Wrapper component that applies transition and motion animations to clips
178
+ *
179
+ * Automatically handles:
180
+ * - transitionIn/transitionOut: basic transition presets (fade, slide, zoom, etc.)
181
+ * - motion: declarative enter/exit/loop animations with spring physics
99
182
  *
100
- * Automatically handles transitionIn and transitionOut based on clip config.
183
+ * Transitions and motion compose together:
184
+ * - Opacity: multiplied (both affect final opacity)
185
+ * - Transforms: added (both contribute to final position/scale/rotation)
101
186
  */
102
187
  declare function ClipWrapper({ clip, children }: ClipWrapperProps): react_jsx_runtime.JSX.Element;
103
188
 
@@ -163,4 +248,4 @@ interface RendererProps {
163
248
  */
164
249
  declare function Renderer({ spec, components: customComponents, }: RendererProps): react_jsx_runtime.JSX.Element;
165
250
 
166
- export { type AudioTrack, type Clip, type ClipComponent, ClipWrapper, type ComponentRegistry, ImageSlide, LogoBug, LowerThird, QuoteCard, Renderer, SplitScreen, StatCard, TextOverlay, type TimelineSpec, TitleCard, type TransitionStyles, TypingText, VideoClip, standardComponents, useTransition };
251
+ export { type AudioTrack, type Clip, type ClipComponent, ClipWrapper, type ComponentRegistry, ImageSlide, LogoBug, LowerThird, type Motion, type MotionLoop, type MotionState, type MotionStyles, QuoteCard, Renderer, SplitScreen, type SpringConfig, StatCard, TextOverlay, type TimelineSpec, TitleCard, type TransitionStyles, TypingText, VideoClip, standardComponents, useMotion, useTransition };