catalog.ts 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. import { z } from "zod";
  2. /**
  3. * Standard component definitions for Remotion catalogs
  4. *
  5. * These can be used directly or extended with custom components.
  6. */
  7. export const standardComponentDefinitions = {
  8. // ==========================================================================
  9. // Scene Components (full-screen)
  10. // ==========================================================================
  11. TitleCard: {
  12. props: z.object({
  13. title: z.string(),
  14. subtitle: z.string().nullable(),
  15. backgroundColor: z.string().nullable(),
  16. textColor: z.string().nullable(),
  17. }),
  18. type: "scene",
  19. defaultDuration: 90,
  20. description:
  21. "Full-screen title card with centered text. Use for intros, outros, and section breaks.",
  22. example: { title: "Welcome", subtitle: "An introduction" },
  23. },
  24. ImageSlide: {
  25. props: z.object({
  26. src: z.string(),
  27. alt: z.string(),
  28. fit: z.enum(["cover", "contain"]).nullable(),
  29. backgroundColor: z.string().nullable(),
  30. }),
  31. type: "image",
  32. defaultDuration: 150,
  33. description:
  34. "Full-screen image display. Use for product shots, photos, and visual content.",
  35. example: {
  36. src: "https://picsum.photos/1920/1080?random=1",
  37. alt: "Hero image",
  38. fit: "cover",
  39. },
  40. },
  41. SplitScreen: {
  42. props: z.object({
  43. leftTitle: z.string(),
  44. rightTitle: z.string(),
  45. leftColor: z.string().nullable(),
  46. rightColor: z.string().nullable(),
  47. }),
  48. type: "scene",
  49. defaultDuration: 120,
  50. description:
  51. "Split screen with two sides. Use for comparisons or before/after.",
  52. },
  53. QuoteCard: {
  54. props: z.object({
  55. quote: z.string(),
  56. author: z.string().nullable(),
  57. backgroundColor: z.string().nullable(),
  58. textColor: z.string().nullable(),
  59. transparent: z.boolean().nullable(),
  60. }),
  61. type: "scene",
  62. defaultDuration: 150,
  63. description:
  64. "Quote display with author. Props: quote, author, textColor, backgroundColor. Set transparent:true when using as overlay on images.",
  65. example: {
  66. quote: "The best way to predict the future is to invent it.",
  67. author: "Alan Kay",
  68. },
  69. },
  70. StatCard: {
  71. props: z.object({
  72. value: z.string(),
  73. label: z.string(),
  74. prefix: z.string().nullable(),
  75. suffix: z.string().nullable(),
  76. backgroundColor: z.string().nullable(),
  77. }),
  78. type: "scene",
  79. defaultDuration: 90,
  80. description: "Large statistic display. Use for key metrics and numbers.",
  81. example: { value: "10M+", label: "Users worldwide", prefix: "" },
  82. },
  83. TypingText: {
  84. props: z.object({
  85. text: z.string(),
  86. backgroundColor: z.string().nullable(),
  87. textColor: z.string().nullable(),
  88. fontSize: z.number().nullable(),
  89. fontFamily: z.enum(["monospace", "sans-serif", "serif"]).nullable(),
  90. showCursor: z.boolean().nullable(),
  91. cursorChar: z.string().nullable(),
  92. charsPerSecond: z.number().nullable(),
  93. }),
  94. type: "scene",
  95. defaultDuration: 180,
  96. description:
  97. "Terminal-style typing animation that reveals text character by character. Perfect for code demos, CLI commands, and dramatic text reveals.",
  98. },
  99. // ==========================================================================
  100. // Overlay Components
  101. // ==========================================================================
  102. LowerThird: {
  103. props: z.object({
  104. name: z.string(),
  105. title: z.string().nullable(),
  106. backgroundColor: z.string().nullable(),
  107. }),
  108. type: "overlay",
  109. defaultDuration: 120,
  110. description:
  111. "Name/title overlay in lower third of screen. Use to identify speakers.",
  112. },
  113. TextOverlay: {
  114. props: z.object({
  115. text: z.string(),
  116. position: z.enum(["top", "center", "bottom"]).nullable(),
  117. fontSize: z.enum(["small", "medium", "large"]).nullable(),
  118. }),
  119. type: "overlay",
  120. defaultDuration: 90,
  121. description: "Simple text overlay. Use for captions and annotations.",
  122. },
  123. LogoBug: {
  124. props: z.object({
  125. position: z
  126. .enum(["top-left", "top-right", "bottom-left", "bottom-right"])
  127. .nullable(),
  128. opacity: z.number().nullable(),
  129. }),
  130. type: "overlay",
  131. defaultDuration: 300,
  132. description: "Corner logo watermark. Use for branding throughout video.",
  133. },
  134. // ==========================================================================
  135. // Video Components
  136. // ==========================================================================
  137. VideoClip: {
  138. props: z.object({
  139. src: z.string(),
  140. startFrom: z.number().nullable(),
  141. volume: z.number().nullable(),
  142. }),
  143. type: "video",
  144. defaultDuration: 150,
  145. description: "Video file playback. Use for B-roll and footage.",
  146. },
  147. };
  148. /**
  149. * Standard transition definitions for Remotion catalogs
  150. */
  151. export const standardTransitionDefinitions = {
  152. fade: {
  153. defaultDuration: 15,
  154. description: "Smooth fade in/out. Use for gentle transitions.",
  155. },
  156. slideLeft: {
  157. defaultDuration: 20,
  158. description: "Slide from right to left. Use for forward progression.",
  159. },
  160. slideRight: {
  161. defaultDuration: 20,
  162. description: "Slide from left to right. Use for backward progression.",
  163. },
  164. slideUp: {
  165. defaultDuration: 15,
  166. description: "Slide from bottom to top. Use for overlays appearing.",
  167. },
  168. slideDown: {
  169. defaultDuration: 15,
  170. description: "Slide from top to bottom. Use for overlays disappearing.",
  171. },
  172. zoom: {
  173. defaultDuration: 20,
  174. description: "Zoom in/out effect. Use for emphasis.",
  175. },
  176. wipe: {
  177. defaultDuration: 15,
  178. description: "Horizontal wipe. Use for scene changes.",
  179. },
  180. none: {
  181. defaultDuration: 0,
  182. description: "No transition (hard cut).",
  183. },
  184. };
  185. /**
  186. * Standard effect definitions for Remotion catalogs
  187. */
  188. export const standardEffectDefinitions = {
  189. kenBurns: {
  190. params: z.object({
  191. startScale: z.number(),
  192. endScale: z.number(),
  193. panX: z.number().nullable(),
  194. panY: z.number().nullable(),
  195. }),
  196. description: "Ken Burns pan and zoom effect for images.",
  197. },
  198. pulse: {
  199. params: z.object({
  200. intensity: z.number(),
  201. }),
  202. description: "Subtle pulsing scale effect for emphasis.",
  203. },
  204. shake: {
  205. params: z.object({
  206. intensity: z.number(),
  207. }),
  208. description: "Camera shake effect for energy.",
  209. },
  210. };
  211. /**
  212. * Type for component definition
  213. */
  214. export type ComponentDefinition = {
  215. props: z.ZodType;
  216. type: string;
  217. defaultDuration: number;
  218. description: string;
  219. };
  220. /**
  221. * Type for transition definition
  222. */
  223. export type TransitionDefinition = {
  224. defaultDuration: number;
  225. description: string;
  226. };
  227. /**
  228. * Type for effect definition
  229. */
  230. export type EffectDefinition = {
  231. params: z.ZodType;
  232. description: string;
  233. };