dsh-remotion 0.2.0 → 0.3.0

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.
Files changed (292) hide show
  1. package/README.en.md +7 -5
  2. package/README.md +3 -3
  3. package/lib/index.d.ts +2 -2
  4. package/lib/index.js +15 -2
  5. package/package.json +1 -1
  6. package/skills/remotion-best-practices/SKILL.md +59 -0
  7. package/skills/remotion-best-practices/agents/openai.yaml +7 -0
  8. package/skills/remotion-best-practices/assets/remotion-icon.png +0 -0
  9. package/skills/remotion-best-practices/remotion-captions/SKILL.md +36 -0
  10. package/skills/remotion-best-practices/remotion-captions/agents/openai.yaml +7 -0
  11. package/skills/remotion-best-practices/remotion-captions/assets/remotion-icon.png +0 -0
  12. package/skills/{remotion/rules → remotion-best-practices/remotion-captions}/display-captions.md +9 -3
  13. package/skills/{remotion/rules → remotion-best-practices/remotion-captions}/import-srt-captions.md +5 -1
  14. package/skills/remotion-best-practices/remotion-create/SKILL.md +68 -0
  15. package/skills/remotion-best-practices/remotion-create/agents/openai.yaml +7 -0
  16. package/skills/remotion-best-practices/remotion-create/assets/remotion-icon.png +0 -0
  17. package/skills/{remotion/rules → remotion-best-practices/remotion-create}/tailwind.md +1 -1
  18. package/skills/remotion-best-practices/remotion-create/video-layout.md +9 -0
  19. package/skills/remotion-best-practices/remotion-docs/SKILL.md +46 -0
  20. package/skills/remotion-best-practices/remotion-docs/agents/openai.yaml +7 -0
  21. package/skills/remotion-best-practices/remotion-docs/assets/remotion-icon.png +0 -0
  22. package/skills/remotion-best-practices/remotion-interactivity/SKILL.md +247 -0
  23. package/skills/remotion-best-practices/remotion-interactivity/agents/openai.yaml +7 -0
  24. package/skills/remotion-best-practices/remotion-interactivity/assets/remotion-icon.png +0 -0
  25. package/skills/remotion-best-practices/remotion-maps/SKILL.md +36 -0
  26. package/skills/remotion-best-practices/remotion-maps/agents/openai.yaml +7 -0
  27. package/skills/remotion-best-practices/remotion-maps/assets/remotion-icon.png +0 -0
  28. package/skills/remotion-best-practices/remotion-maps/techniques/cesium/TECHNIQUE.md +89 -0
  29. package/skills/remotion-best-practices/remotion-maps/techniques/cesium/assets/CesiumFlythrough.tsx +284 -0
  30. package/skills/remotion-best-practices/remotion-maps/techniques/cesium/assets/cesium-path.json +299 -0
  31. package/skills/remotion-best-practices/remotion-maps/techniques/cesium/assets/city-path.json +12 -0
  32. package/skills/remotion-best-practices/remotion-maps/techniques/cesium/assets/example-Root.tsx +39 -0
  33. package/skills/remotion-best-practices/remotion-maps/techniques/cesium/assets/flight-path.ts +35 -0
  34. package/skills/remotion-best-practices/remotion-maps/techniques/cesium/assets/sample-river.geojson +215 -0
  35. package/skills/remotion-best-practices/remotion-maps/techniques/cesium/references/3d-data-sources.md +43 -0
  36. package/skills/remotion-best-practices/remotion-maps/techniques/cesium/references/3d-flyover-architecture.md +128 -0
  37. package/skills/remotion-best-practices/remotion-maps/techniques/cesium/references/3d-troubleshooting.md +57 -0
  38. package/skills/remotion-best-practices/remotion-maps/techniques/cesium/scripts/prep-cesium-path.mjs +161 -0
  39. package/skills/remotion-best-practices/remotion-maps/techniques/mapbox/TECHNIQUE.md +449 -0
  40. package/skills/remotion-best-practices/remotion-maps/techniques/mapbox/references/render-stability.md +64 -0
  41. package/skills/remotion-best-practices/remotion-maps/techniques/maplibre/TECHNIQUE.md +465 -0
  42. package/skills/remotion-best-practices/remotion-maps/techniques/maplibre/references/render-stability.md +64 -0
  43. package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/TECHNIQUE.md +80 -0
  44. package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/assets/CountryLabel.tsx +70 -0
  45. package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/assets/MapTilerVectorElement.ts +80 -0
  46. package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/assets/RiverReveal.tsx +363 -0
  47. package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/assets/example-Root.tsx +22 -0
  48. package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/assets/sample-data/country-meta.json +7535 -0
  49. package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/assets/sample-data/yarlung-flow.json +605 -0
  50. package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/assets/tokens.ts +34 -0
  51. package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/references/map-data-sources.md +91 -0
  52. package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/references/map-explainer-architecture.md +129 -0
  53. package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/references/map-geo-prep.md +85 -0
  54. package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/references/render-stability.md +64 -0
  55. package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/scripts/prep-geo.mjs +202 -0
  56. package/skills/remotion-best-practices/remotion-maps/techniques/static-map/TECHNIQUE.md +37 -0
  57. package/skills/remotion-best-practices/remotion-markup/SKILL.md +365 -0
  58. package/skills/remotion-best-practices/remotion-markup/agents/openai.yaml +7 -0
  59. package/skills/remotion-best-practices/remotion-markup/assets/remotion-icon.png +0 -0
  60. package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/audio.md +4 -2
  61. package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/calculate-metadata.md +4 -2
  62. package/skills/remotion-best-practices/remotion-markup/compositions.md +117 -0
  63. package/skills/remotion-best-practices/remotion-markup/cropping.md +34 -0
  64. package/skills/remotion-best-practices/remotion-markup/effects.md +251 -0
  65. package/skills/{remotion/rules/videos.md → remotion-best-practices/remotion-markup/embedding-videos.md} +6 -4
  66. package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/ffmpeg.md +5 -1
  67. package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/gifs.md +55 -9
  68. package/skills/remotion-best-practices/remotion-markup/google-fonts.md +76 -0
  69. package/skills/remotion-best-practices/remotion-markup/html-in-canvas.md +128 -0
  70. package/skills/remotion-best-practices/remotion-markup/images.md +73 -0
  71. package/skills/remotion-best-practices/remotion-markup/light-leaks.md +106 -0
  72. package/skills/remotion-best-practices/remotion-markup/local-fonts.md +69 -0
  73. package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/lottie.md +4 -1
  74. package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/measuring-dom-nodes.md +5 -1
  75. package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/measuring-text.md +8 -2
  76. package/skills/remotion-best-practices/remotion-markup/multi-scene-video.md +81 -0
  77. package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/parameters.md +3 -1
  78. package/skills/remotion-best-practices/remotion-markup/remotion-maps/SKILL.md +36 -0
  79. package/skills/remotion-best-practices/remotion-markup/remotion-maps/agents/openai.yaml +7 -0
  80. package/skills/remotion-best-practices/remotion-markup/remotion-maps/assets/remotion-icon.png +0 -0
  81. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/TECHNIQUE.md +89 -0
  82. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/assets/CesiumFlythrough.tsx +284 -0
  83. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/assets/cesium-path.json +299 -0
  84. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/assets/city-path.json +12 -0
  85. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/assets/example-Root.tsx +39 -0
  86. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/assets/flight-path.ts +35 -0
  87. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/assets/sample-river.geojson +215 -0
  88. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/references/3d-data-sources.md +43 -0
  89. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/references/3d-flyover-architecture.md +128 -0
  90. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/references/3d-troubleshooting.md +57 -0
  91. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/scripts/prep-cesium-path.mjs +161 -0
  92. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/mapbox/TECHNIQUE.md +449 -0
  93. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/mapbox/references/render-stability.md +64 -0
  94. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maplibre/TECHNIQUE.md +465 -0
  95. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maplibre/references/render-stability.md +64 -0
  96. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/TECHNIQUE.md +80 -0
  97. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/assets/CountryLabel.tsx +70 -0
  98. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/assets/MapTilerVectorElement.ts +80 -0
  99. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/assets/RiverReveal.tsx +363 -0
  100. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/assets/example-Root.tsx +22 -0
  101. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/assets/sample-data/country-meta.json +7535 -0
  102. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/assets/sample-data/yarlung-flow.json +605 -0
  103. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/assets/tokens.ts +34 -0
  104. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/references/map-data-sources.md +91 -0
  105. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/references/map-explainer-architecture.md +129 -0
  106. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/references/map-geo-prep.md +85 -0
  107. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/references/render-stability.md +64 -0
  108. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/scripts/prep-geo.mjs +202 -0
  109. package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/static-map/TECHNIQUE.md +37 -0
  110. package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/sequencing.md +63 -12
  111. package/skills/remotion-best-practices/remotion-markup/sfx.md +51 -0
  112. package/skills/remotion-best-practices/remotion-markup/text-highlights.md +56 -0
  113. package/skills/remotion-best-practices/remotion-markup/timing.md +111 -0
  114. package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/transitions.md +49 -7
  115. package/skills/remotion-best-practices/remotion-markup/video-editing.md +90 -0
  116. package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/voiceover.md +2 -2
  117. package/skills/remotion-best-practices/remotion-multimedia/SKILL.md +20 -0
  118. package/skills/remotion-best-practices/remotion-multimedia/agents/openai.yaml +7 -0
  119. package/skills/remotion-best-practices/remotion-multimedia/assets/remotion-icon.png +0 -0
  120. package/skills/{remotion/rules → remotion-best-practices/remotion-multimedia}/get-audio-duration.md +1 -3
  121. package/skills/{remotion/rules → remotion-best-practices/remotion-multimedia}/get-video-dimensions.md +1 -3
  122. package/skills/{remotion/rules → remotion-best-practices/remotion-multimedia}/get-video-duration.md +1 -3
  123. package/skills/remotion-best-practices/remotion-render/SKILL.md +27 -0
  124. package/skills/remotion-best-practices/remotion-render/agents/openai.yaml +7 -0
  125. package/skills/remotion-best-practices/remotion-render/assets/remotion-icon.png +0 -0
  126. package/skills/remotion-best-practices/remotion-saas/SKILL.md +33 -0
  127. package/skills/remotion-best-practices/remotion-saas/agents/openai.yaml +7 -0
  128. package/skills/remotion-best-practices/remotion-saas/assets/remotion-icon.png +0 -0
  129. package/skills/remotion-best-practices/remotion-saas/framework.md +21 -0
  130. package/skills/remotion-best-practices/remotion-saas/player.md +33 -0
  131. package/skills/remotion-best-practices/remotion-saas/rendering.md +69 -0
  132. package/skills/remotion-best-practices/remotion-studio/SKILL.md +24 -0
  133. package/skills/remotion-best-practices/remotion-studio/agents/openai.yaml +7 -0
  134. package/skills/remotion-best-practices/remotion-studio/assets/remotion-icon.png +0 -0
  135. package/skills/remotion-best-practices/remotion-upgrade/SKILL.md +31 -0
  136. package/skills/remotion-best-practices/remotion-upgrade/agents/openai.yaml +7 -0
  137. package/skills/remotion-best-practices/remotion-upgrade/assets/remotion-icon.png +0 -0
  138. package/skills/remotion-captions/SKILL.md +36 -0
  139. package/skills/remotion-captions/agents/openai.yaml +7 -0
  140. package/skills/remotion-captions/assets/remotion-icon.png +0 -0
  141. package/skills/remotion-captions/display-captions.md +190 -0
  142. package/skills/remotion-captions/import-srt-captions.md +73 -0
  143. package/skills/remotion-captions/transcribe-captions.md +70 -0
  144. package/skills/remotion-create/SKILL.md +68 -0
  145. package/skills/remotion-create/agents/openai.yaml +7 -0
  146. package/skills/remotion-create/assets/remotion-icon.png +0 -0
  147. package/skills/remotion-create/tailwind.md +11 -0
  148. package/skills/remotion-create/video-layout.md +9 -0
  149. package/skills/remotion-docs/SKILL.md +46 -0
  150. package/skills/remotion-docs/agents/openai.yaml +7 -0
  151. package/skills/remotion-docs/assets/remotion-icon.png +0 -0
  152. package/skills/remotion-interactivity/SKILL.md +247 -0
  153. package/skills/remotion-interactivity/agents/openai.yaml +7 -0
  154. package/skills/remotion-interactivity/assets/remotion-icon.png +0 -0
  155. package/skills/remotion-maps/SKILL.md +36 -0
  156. package/skills/remotion-maps/agents/openai.yaml +7 -0
  157. package/skills/remotion-maps/assets/remotion-icon.png +0 -0
  158. package/skills/remotion-maps/techniques/cesium/TECHNIQUE.md +89 -0
  159. package/skills/remotion-maps/techniques/cesium/assets/CesiumFlythrough.tsx +284 -0
  160. package/skills/remotion-maps/techniques/cesium/assets/cesium-path.json +299 -0
  161. package/skills/remotion-maps/techniques/cesium/assets/city-path.json +12 -0
  162. package/skills/remotion-maps/techniques/cesium/assets/example-Root.tsx +39 -0
  163. package/skills/remotion-maps/techniques/cesium/assets/flight-path.ts +35 -0
  164. package/skills/remotion-maps/techniques/cesium/assets/sample-river.geojson +215 -0
  165. package/skills/remotion-maps/techniques/cesium/references/3d-data-sources.md +43 -0
  166. package/skills/remotion-maps/techniques/cesium/references/3d-flyover-architecture.md +128 -0
  167. package/skills/remotion-maps/techniques/cesium/references/3d-troubleshooting.md +57 -0
  168. package/skills/remotion-maps/techniques/cesium/scripts/prep-cesium-path.mjs +161 -0
  169. package/skills/remotion-maps/techniques/mapbox/TECHNIQUE.md +449 -0
  170. package/skills/remotion-maps/techniques/mapbox/references/render-stability.md +64 -0
  171. package/skills/remotion-maps/techniques/maplibre/TECHNIQUE.md +465 -0
  172. package/skills/remotion-maps/techniques/maplibre/references/render-stability.md +64 -0
  173. package/skills/remotion-maps/techniques/maptiler/TECHNIQUE.md +80 -0
  174. package/skills/remotion-maps/techniques/maptiler/assets/CountryLabel.tsx +70 -0
  175. package/skills/remotion-maps/techniques/maptiler/assets/MapTilerVectorElement.ts +80 -0
  176. package/skills/remotion-maps/techniques/maptiler/assets/RiverReveal.tsx +363 -0
  177. package/skills/remotion-maps/techniques/maptiler/assets/example-Root.tsx +22 -0
  178. package/skills/remotion-maps/techniques/maptiler/assets/sample-data/country-meta.json +7535 -0
  179. package/skills/remotion-maps/techniques/maptiler/assets/sample-data/yarlung-flow.json +605 -0
  180. package/skills/remotion-maps/techniques/maptiler/assets/tokens.ts +34 -0
  181. package/skills/remotion-maps/techniques/maptiler/references/map-data-sources.md +91 -0
  182. package/skills/remotion-maps/techniques/maptiler/references/map-explainer-architecture.md +129 -0
  183. package/skills/remotion-maps/techniques/maptiler/references/map-geo-prep.md +85 -0
  184. package/skills/remotion-maps/techniques/maptiler/references/render-stability.md +64 -0
  185. package/skills/remotion-maps/techniques/maptiler/scripts/prep-geo.mjs +202 -0
  186. package/skills/remotion-maps/techniques/static-map/TECHNIQUE.md +37 -0
  187. package/skills/remotion-markup/3d.md +86 -0
  188. package/skills/remotion-markup/SKILL.md +365 -0
  189. package/skills/remotion-markup/agents/openai.yaml +7 -0
  190. package/skills/remotion-markup/assets/remotion-icon.png +0 -0
  191. package/skills/remotion-markup/audio-visualization.md +198 -0
  192. package/skills/remotion-markup/audio.md +171 -0
  193. package/skills/remotion-markup/calculate-metadata.md +136 -0
  194. package/skills/remotion-markup/compositions.md +117 -0
  195. package/skills/remotion-markup/cropping.md +34 -0
  196. package/skills/remotion-markup/effects.md +251 -0
  197. package/skills/remotion-markup/embedding-videos.md +173 -0
  198. package/skills/remotion-markup/ffmpeg.md +38 -0
  199. package/skills/remotion-markup/gifs.md +187 -0
  200. package/skills/remotion-markup/google-fonts.md +76 -0
  201. package/skills/remotion-markup/html-in-canvas.md +128 -0
  202. package/skills/remotion-markup/images.md +73 -0
  203. package/skills/remotion-markup/light-leaks.md +106 -0
  204. package/skills/remotion-markup/local-fonts.md +69 -0
  205. package/skills/remotion-markup/lottie.md +73 -0
  206. package/skills/remotion-markup/measuring-dom-nodes.md +38 -0
  207. package/skills/remotion-markup/measuring-text.md +146 -0
  208. package/skills/remotion-markup/multi-scene-video.md +81 -0
  209. package/skills/remotion-markup/parameters.md +111 -0
  210. package/skills/remotion-markup/remotion-maps/SKILL.md +36 -0
  211. package/skills/remotion-markup/remotion-maps/agents/openai.yaml +7 -0
  212. package/skills/remotion-markup/remotion-maps/assets/remotion-icon.png +0 -0
  213. package/skills/remotion-markup/remotion-maps/techniques/cesium/TECHNIQUE.md +89 -0
  214. package/skills/remotion-markup/remotion-maps/techniques/cesium/assets/CesiumFlythrough.tsx +284 -0
  215. package/skills/remotion-markup/remotion-maps/techniques/cesium/assets/cesium-path.json +299 -0
  216. package/skills/remotion-markup/remotion-maps/techniques/cesium/assets/city-path.json +12 -0
  217. package/skills/remotion-markup/remotion-maps/techniques/cesium/assets/example-Root.tsx +39 -0
  218. package/skills/remotion-markup/remotion-maps/techniques/cesium/assets/flight-path.ts +35 -0
  219. package/skills/remotion-markup/remotion-maps/techniques/cesium/assets/sample-river.geojson +215 -0
  220. package/skills/remotion-markup/remotion-maps/techniques/cesium/references/3d-data-sources.md +43 -0
  221. package/skills/remotion-markup/remotion-maps/techniques/cesium/references/3d-flyover-architecture.md +128 -0
  222. package/skills/remotion-markup/remotion-maps/techniques/cesium/references/3d-troubleshooting.md +57 -0
  223. package/skills/remotion-markup/remotion-maps/techniques/cesium/scripts/prep-cesium-path.mjs +161 -0
  224. package/skills/remotion-markup/remotion-maps/techniques/mapbox/TECHNIQUE.md +449 -0
  225. package/skills/remotion-markup/remotion-maps/techniques/mapbox/references/render-stability.md +64 -0
  226. package/skills/remotion-markup/remotion-maps/techniques/maplibre/TECHNIQUE.md +465 -0
  227. package/skills/remotion-markup/remotion-maps/techniques/maplibre/references/render-stability.md +64 -0
  228. package/skills/remotion-markup/remotion-maps/techniques/maptiler/TECHNIQUE.md +80 -0
  229. package/skills/remotion-markup/remotion-maps/techniques/maptiler/assets/CountryLabel.tsx +70 -0
  230. package/skills/remotion-markup/remotion-maps/techniques/maptiler/assets/MapTilerVectorElement.ts +80 -0
  231. package/skills/remotion-markup/remotion-maps/techniques/maptiler/assets/RiverReveal.tsx +363 -0
  232. package/skills/remotion-markup/remotion-maps/techniques/maptiler/assets/example-Root.tsx +22 -0
  233. package/skills/remotion-markup/remotion-maps/techniques/maptiler/assets/sample-data/country-meta.json +7535 -0
  234. package/skills/remotion-markup/remotion-maps/techniques/maptiler/assets/sample-data/yarlung-flow.json +605 -0
  235. package/skills/remotion-markup/remotion-maps/techniques/maptiler/assets/tokens.ts +34 -0
  236. package/skills/remotion-markup/remotion-maps/techniques/maptiler/references/map-data-sources.md +91 -0
  237. package/skills/remotion-markup/remotion-maps/techniques/maptiler/references/map-explainer-architecture.md +129 -0
  238. package/skills/remotion-markup/remotion-maps/techniques/maptiler/references/map-geo-prep.md +85 -0
  239. package/skills/remotion-markup/remotion-maps/techniques/maptiler/references/render-stability.md +64 -0
  240. package/skills/remotion-markup/remotion-maps/techniques/maptiler/scripts/prep-geo.mjs +202 -0
  241. package/skills/remotion-markup/remotion-maps/techniques/static-map/TECHNIQUE.md +37 -0
  242. package/skills/remotion-markup/sequencing.md +169 -0
  243. package/skills/remotion-markup/sfx.md +51 -0
  244. package/skills/remotion-markup/silence-detection.md +71 -0
  245. package/skills/remotion-markup/text-highlights.md +56 -0
  246. package/skills/remotion-markup/timing.md +111 -0
  247. package/skills/remotion-markup/transitions.md +239 -0
  248. package/skills/remotion-markup/video-editing.md +90 -0
  249. package/skills/remotion-markup/voiceover.md +99 -0
  250. package/skills/remotion-multimedia/SKILL.md +20 -0
  251. package/skills/remotion-multimedia/agents/openai.yaml +7 -0
  252. package/skills/remotion-multimedia/assets/remotion-icon.png +0 -0
  253. package/skills/remotion-multimedia/get-audio-duration.md +56 -0
  254. package/skills/remotion-multimedia/get-video-dimensions.md +66 -0
  255. package/skills/remotion-multimedia/get-video-duration.md +58 -0
  256. package/skills/remotion-render/SKILL.md +27 -0
  257. package/skills/remotion-render/agents/openai.yaml +7 -0
  258. package/skills/remotion-render/assets/remotion-icon.png +0 -0
  259. package/skills/remotion-render/transparent-videos.md +106 -0
  260. package/skills/remotion-saas/SKILL.md +33 -0
  261. package/skills/remotion-saas/agents/openai.yaml +7 -0
  262. package/skills/remotion-saas/assets/remotion-icon.png +0 -0
  263. package/skills/remotion-saas/framework.md +21 -0
  264. package/skills/remotion-saas/player.md +33 -0
  265. package/skills/remotion-saas/rendering.md +69 -0
  266. package/skills/remotion-studio/SKILL.md +24 -0
  267. package/skills/remotion-studio/agents/openai.yaml +7 -0
  268. package/skills/remotion-studio/assets/remotion-icon.png +0 -0
  269. package/skills/remotion-upgrade/SKILL.md +31 -0
  270. package/skills/remotion-upgrade/agents/openai.yaml +7 -0
  271. package/skills/remotion-upgrade/assets/remotion-icon.png +0 -0
  272. package/skills/remotion/SKILL.md +0 -95
  273. package/skills/remotion/rules/animations.md +0 -31
  274. package/skills/remotion/rules/assets.md +0 -78
  275. package/skills/remotion/rules/can-decode.md +0 -81
  276. package/skills/remotion/rules/charts.md +0 -120
  277. package/skills/remotion/rules/compositions.md +0 -154
  278. package/skills/remotion/rules/extract-frames.md +0 -229
  279. package/skills/remotion/rules/fonts.md +0 -152
  280. package/skills/remotion/rules/images.md +0 -134
  281. package/skills/remotion/rules/light-leaks.md +0 -73
  282. package/skills/remotion/rules/maps.md +0 -412
  283. package/skills/remotion/rules/sfx.md +0 -30
  284. package/skills/remotion/rules/subtitles.md +0 -36
  285. package/skills/remotion/rules/text-animations.md +0 -20
  286. package/skills/remotion/rules/timing.md +0 -136
  287. package/skills/remotion/rules/trimming.md +0 -51
  288. /package/skills/{remotion/rules → remotion-best-practices/remotion-captions}/transcribe-captions.md +0 -0
  289. /package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/3d.md +0 -0
  290. /package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/audio-visualization.md +0 -0
  291. /package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/silence-detection.md +0 -0
  292. /package/skills/{remotion/rules → remotion-best-practices/remotion-render}/transparent-videos.md +0 -0
@@ -0,0 +1,129 @@
1
+ # Map Explainer — architecture reference
2
+
3
+ Deep detail behind `TECHNIQUE.md`: the timing model, the river reveal + electric head, the per-country
4
+ sequence, and label projection. The supplied values are examples, not a production style system.
5
+ The custom-geometry example is `../assets/RiverReveal.tsx` +
6
+ `../assets/CountryLabel.tsx` +
7
+ `../assets/tokens.ts`. Provider-vector setup is in
8
+ `../assets/MapTilerVectorElement.ts`; choose between
9
+ the two modes with `data-sources.md`.
10
+
11
+ ## 1. The render harness (per frame)
12
+
13
+ Init the MapTiler map once (ref guard). On `load`: strip clutter (see `geo-prep.md`), add sources/layers,
14
+ wait for `once('idle') → continueRender`. Per frame:
15
+
16
+ ```
17
+ delayRender → setData/setPaintProperty → map.once('idle', continueRender) → triggerRepaint
18
+ ```
19
+
20
+ `preserveDrawingBuffer:true` so Remotion's screenshot captures the canvas. Render `--gl=angle`.
21
+ For an animated camera, read `render-stability.md`: the MapTiler renderer remains static and a CSS plate
22
+ transform supplies the camera choreography.
23
+
24
+ ## 2. Timing model — time-based; beat length derived from the sequences
25
+
26
+ Everything keys off **seconds** (`t = frame / fps`), not reveal-units. The river draws over a window;
27
+ each country **triggers when the river reaches it** and runs a fixed sequence. The beat is exactly as
28
+ long as the sequences need.
29
+
30
+ ```ts
31
+ const RIVER_START = 0.3, RIVER_END = 8.0; // river draws over this window
32
+ const BORDER_S = 2.5, FILL_S = 1.0, LABEL_S = 0.7; // per-country sequence (constant durations)
33
+ const trigger = (c) => RIVER_START + META[c].stop * (RIVER_END - RIVER_START); // river-arrival time
34
+ // beat length = max over c of (trigger(c) + BORDER_S + FILL_S + LABEL_S) + tail
35
+ const reveal = interpolate(t, [RIVER_START, RIVER_END], [0,1], { ...clamp, easing: Easing.bezier(0.645, 0.045, 0.355, 1) });
36
+ ```
37
+
38
+ **Constant durations matter:** drive the border draw by _time since trigger_, not a slice of the reveal —
39
+ otherwise complex or long borders flash by in a fraction of a second.
40
+
41
+ ## 3. Provider-vector animation
42
+
43
+ MapTiler Planet elements can be animated directly in place. Filter an exact `source-layer` feature,
44
+ initialize its paint in the hidden or neutral state, then update paint properties from the Remotion frame.
45
+ This works for line, fill, circle, and symbol layers without copying provider geometry into the project.
46
+
47
+ Do not assume tiled geometry has a global order. Provider features are split at tile boundaries: opacity,
48
+ colour, width, blur, radius, fill, and feature-state changes are reliable; semantic start-to-end line
49
+ draws are not. Bake ordered GeoJSON when the direction of the draw carries meaning.
50
+
51
+ ## 4. Custom line animation — reveal + electric draw-head
52
+
53
+ The "electricity" is a **white-hot head** leading the draw — the last few % of the drawn line in its own
54
+ bright + glow layers, faded out once the river completes.
55
+
56
+ ```ts
57
+ const riverDrawnKm = lineKm * reveal;
58
+ map.getSource("river").setData(turf.lineSliceAlong(line, 0, Math.max(0.001, riverDrawnKm)));
59
+ const headKm = lineKm * 0.03;
60
+ map.getSource("river-head").setData(turf.lineSliceAlong(line, Math.max(0, riverDrawnKm - headKm), Math.max(0.001, riverDrawnKm)));
61
+ let headFade = 0;
62
+ if (reveal > 0.002 && reveal < 0.999) headFade = 1;
63
+ else if (reveal >= 0.999) headFade = 1 - clamp01((t - RIVER_END) / 0.5); // fade out at the mouth
64
+ map.setPaintProperty("river-headglow", "line-opacity", 0.85 * headFade);
65
+ map.setPaintProperty("river-head", "line-opacity", headFade);
66
+ ```
67
+
68
+ Layers, bottom→top: `river-glow` (electric blue `#49C6FF`, w11, op0.32, blur6) → `river-line`
69
+ (icy core `#E8F7FF`, w3) → `river-headglow` (`rgba(120,225,255,.95)`, w16, blur9) → `river-head`
70
+ (white `#FFFFFF`, w4.5). **No dark casing** — the bright icy core reads over every fill on its own.
71
+
72
+ ## 5. Country animation — border draws → fill blooms → label rises
73
+
74
+ Triggered by river arrival, each country runs three sequential phases. The border is a **darker shade**
75
+ of the country colour (the electricity is on the river, not here).
76
+
77
+ ```ts
78
+ const lt = t - trigger(c); // local seconds since trigger
79
+ // 1) complete source border draws on over a constant BORDER_S, multi-segment-safe
80
+ const bp = interpolate(clamp01(lt / BORDER_S), [0,1], [0,1], { easing: Easing.bezier(0.645, 0.045, 0.355, 1) });
81
+ map.getSource(`trail-${c}`).setData(sliceBorder(DRAW[c], 0, DRAW[c].total * bp)); // COUNTRY_DARK line
82
+ // 2) fill blooms in (opacity overshoots, then settles) after the border completes
83
+ const fp = clamp01((lt - BORDER_S) / FILL_S);
84
+ const fo = interpolate(fp, [0, 0.6, 1], [0, FILL_OPACITY * 1.25, FILL_OPACITY], { ...clamp, easing: Easing.bezier(0.3333333333333333, 1, 0.6666666666666666, 1) });
85
+ map.setPaintProperty(`fill-${c}`, "fill-opacity", fp <= 0 ? 0 : fo);
86
+ // 3) label rises in after the fill
87
+ const lp = clamp01((lt - BORDER_S - FILL_S) / LABEL_S);
88
+ ```
89
+
90
+ `sliceBorder(d, fromKm, toKm)` reveals a portion of a complete (possibly multi-segment) border as a
91
+ MultiLineString, slicing each segment by cumulative length — no joins across gaps and no viewport crop:
92
+
93
+ ```ts
94
+ const sliceBorder = (d, fromKm, toKm) => {
95
+ const out = [];
96
+ for (let i = 0; i < d.segLines.length; i++) {
97
+ const start = d.cum[i], end = start + d.segLen[i];
98
+ const a = Math.max(fromKm, start), b = Math.min(toKm, end);
99
+ if (b - a <= 0.0008) continue;
100
+ out.push(turf.lineSliceAlong(d.segLines[i], a - start, b - start).geometry.coordinates);
101
+ }
102
+ return { type:"Feature", properties:{}, geometry:{ type:"MultiLineString", coordinates: out } };
103
+ };
104
+ ```
105
+
106
+ Choose fill, border, and river colours in the production's local token file. The bundled token values are
107
+ examples only; do not carry a source project's palette into another production.
108
+
109
+ ## 6. Labels — HTML overlay, projected each frame
110
+
111
+ Labels are React, not map symbols (full typography control). `CountryLabel` is an example accent-rule,
112
+ rise-and-fade treatment; select the typeface and final values in the production.
113
+ Positioned by projecting the anchor to screen pixels **every frame**, stored in state:
114
+
115
+ ```ts
116
+ const p = map.project(META[c].anchor); // lngLat → screen px (respects the live camera)
117
+ pos[c] = { x: p.x, y: p.y, reveal: lp };
118
+ setLabels(pos); // re-render the overlay; effect deps exclude `labels`
119
+ ```
120
+
121
+ `CountryLabel` shows the mechanics: uppercase region name, short accent divider, rise/fade entrance,
122
+ and `pointerEvents:none`. Select font, weight, size, spacing, contrast, and colour from the production's
123
+ own type and palette system.
124
+
125
+ ## 7. Camera — fixed map plate for any movement
126
+
127
+ Read `render-stability.md`. Do not use per-frame `map.jumpTo()` for a moving 2D shot; it can shimmer in
128
+ headless renders even on satellite imagery. Interpolate the intended camera for the CSS plate transform,
129
+ while keeping the MapTiler renderer static.
@@ -0,0 +1,85 @@
1
+ # Map Explainer — basemap & geo prep
2
+
3
+ How the basemap is cleaned and how `../scripts/prep-geo.mjs` bakes the per-country data the component reads.
4
+
5
+ ## Basemap styling — strip the clutter
6
+
7
+ On `load`, remove the basemap's labels and inner admin borders so only your geography reads:
8
+
9
+ ```ts
10
+ for (const l of m.getStyle().layers as any[])
11
+ if (l.type === "symbol" || /other border/i.test(l.id)) m.removeLayer(l.id);
12
+ ```
13
+
14
+ - `type === "symbol"` → every place/water/road **label** (the "MapTiler labels"). Gone.
15
+ - Inner admin-border layer IDs vary by style. Inspect the loaded style, remove state/province/district
16
+ layers as needed, and retain only the context borders the production requires.
17
+ - Logo/attribution: `maptilerLogo:false` + `attributionControl:false` aren't always enough — also hide
18
+ via CSS in the component:
19
+ ```tsx
20
+ <style>
21
+ {`
22
+ .maplibregl-ctrl-bottom-left,
23
+ .maplibregl-ctrl-bottom-right,
24
+ .maplibregl-ctrl-attrib,
25
+ .maptiler-logo {
26
+ display: none !important;
27
+ }
28
+ `}
29
+ </style>
30
+ ```
31
+
32
+ ## `../scripts/prep-geo.mjs` → outputs
33
+
34
+ Reads a routed river GeoJSON + country polygon GeoJSONs; writes:
35
+
36
+ - **River line** — simplified for a smooth draw. For a braided river, route one source→mouth path through
37
+ the network first: greedy endpoint-chaining bounces between parallel channels. → `src/geo/river-flow.json`.
38
+ - **`public/geo/borders.geojson`** — each country's polygon tagged `{country: name}` (one source,
39
+ filtered per country for the fills).
40
+ - **`src/geo/country-meta.json`** — per country `{ stop, anchor, border }`.
41
+
42
+ ### `stop` — when a country lights up
43
+
44
+ Walk the river points; first point inside a country (`turf.booleanPointInPolygon`) = the arc-length
45
+ fraction where the river **enters** it. Drives the trigger time. The headwaters country = 0.
46
+
47
+ ### `anchor` — label centre via pole of inaccessibility
48
+
49
+ The most-interior point of the country (clipped to a per-country **story bbox** so a big country
50
+ centres in the relevant region, not its far bulge), then a small operator **nudge**. Pole = grid-sample
51
+ inside the polygon, keep the point with max distance to the boundary. **Centroids get pulled to edges —
52
+ don't use them.**
53
+
54
+ ```js
55
+ const pole = (poly) => {
56
+ const bb = turf.bbox(poly), edge = turf.polygonToLine(poly), N = 46;
57
+ let best = null, bestD = -1;
58
+ for (let i = 0; i <= N; i++) for (let j = 0; j <= N; j++) {
59
+ const p = turf.point([bb[0]+(bb[2]-bb[0])*i/N, bb[1]+(bb[3]-bb[1])*j/N]);
60
+ if (!turf.booleanPointInPolygon(p, poly)) continue;
61
+ const d = turf.pointToLineDistance(p, edge);
62
+ if (d > bestD) { bestD = d; best = p.geometry.coordinates; }
63
+ }
64
+ return best;
65
+ };
66
+ const ANCHOR_BBOX = { china:[82,27,96,32], india:[76,14,99,31], bangladesh:[86,20,93,27] }; // story regions
67
+ const NUDGE = { china:[0,0.6], india:[-1.0,0], bangladesh:[0,-0.6] }; // operator-directed
68
+ ```
69
+
70
+ ### `border` — complete source geometry
71
+
72
+ Preserve every exterior ring from the named country source. Never clip a country or bilateral border to
73
+ the framed bbox and never discard an off-screen segment: the geometry may leave the frame naturally.
74
+ The renderer handles a MultiLineString by cumulative length, so it remains one timed reveal without
75
+ inventing joins across gaps.
76
+
77
+ ## Tuning the geo prep for a new scenario
78
+
79
+ | Want | Knob |
80
+ | --------------------------------- | -------------------------------------------------------------------- |
81
+ | Which countries | the country list in `prep-geo.mjs` (+ supply their polygon GeoJSONs) |
82
+ | Label centred in the right region | `ANCHOR_BBOX[country]` (the story bbox) |
83
+ | Nudge a label | `NUDGE[country]` (lng, lat offset) |
84
+ | What border is drawn | the complete named source geometry; never the visible extent |
85
+ | When each lights up | derived from `stop` — depends on the river geometry |
@@ -0,0 +1,64 @@
1
+ # Moving Map Render Stability
2
+
3
+ Read this reference before building a moving 2D MapTiler scene or diagnosing a wavering Remotion render.
4
+
5
+ ## Symptom and cause
6
+
7
+ If basemap detail shimmers or jitters during a pan/zoom, the likely cause is per-frame `map.jumpTo()`.
8
+ Headless MapTiler capture can resample both vector hillshade and satellite imagery differently frame to
9
+ frame. Tile retries, easing changes, and label changes do not solve that renderer effect.
10
+
11
+ ## Required pattern: fixed map plate
12
+
13
+ For any 2D pan/zoom:
14
+
15
+ 1. Render the MapTiler canvas once at the largest required zoom in an oversized container. Size it from the camera route and keep each dimension below the browser's reliable WebGL render-buffer limit (commonly 4096 px). Do **not** blindly use 3×: a 1920×1080 composition becomes 5760 px wide and Chromium may silently downsample it, causing visible pixelation during the CSS zoom.
16
+ 2. Keep the map's camera static.
17
+ 3. For each frame, calculate the approved target centre/zoom, then move the canvas with CSS `translate` + `scale`.
18
+ 4. Apply the same transform to every projected HTML overlay.
19
+ 5. Continue to animate GeoJSON data and paint properties imperatively; only the renderer camera is frozen.
20
+
21
+ Keep pitch and bearing constant. Use a 3D engine such as Cesium for genuine changing pitch/bearing or a terrain flythrough.
22
+
23
+ ```ts
24
+ const baseZoom = Math.max(start.zoom, end.zoom);
25
+ const map = new maptilersdk.Map({
26
+ container,
27
+ style,
28
+ center: end.center,
29
+ zoom: baseZoom,
30
+ pitch: end.pitch ?? 0,
31
+ bearing: end.bearing ?? 0,
32
+ interactive: false,
33
+ fadeDuration: 0,
34
+ canvasContextAttributes: {preserveDrawingBuffer: true},
35
+ });
36
+
37
+ // Per Remotion frame. `camera` is the approved centre/zoom interpolation.
38
+ const projected = map.project(camera.center);
39
+ const scale = 2 ** (camera.zoom - baseZoom);
40
+ const plate = {
41
+ transform: `translate(${width / 2 - projected.x * scale}px, ${height / 2 - projected.y * scale}px) scale(${scale})`,
42
+ transformOrigin: "0 0",
43
+ };
44
+
45
+ // Convert label projection with exactly the same plate transform.
46
+ const labelX = labelPoint.x * scale + width / 2 - projected.x * scale;
47
+ const labelY = labelPoint.y * scale + height / 2 - projected.y * scale;
48
+ ```
49
+
50
+ ### Plate sizing and sharpness
51
+
52
+ - Render at the maximum zoom reached by **any** camera waypoint, including intermediate or hold cameras. The CSS scale should never exceed `1`; otherwise the plate is being enlarged.
53
+ - Centre the frozen map on the midpoint of the camera route's geographic extent, not automatically on the final camera. This minimizes required overscan.
54
+ - Keep the largest canvas dimension at or below 4096 px unless the actual render environment has been tested with a larger `MAX_RENDERBUFFER_SIZE`.
55
+ - For 1920×1080, a 3840×2160 plate is a safe default. For 1080×1920, use approximately 2700×3840 when the route needs extra horizontal pan room.
56
+ - If the route cannot fit within that plate at the required zoom, split the shot into two fixed plates with a deliberate editorial transition. Do not trade sharpness for one enormous canvas.
57
+ - Distinguish failure modes: repeating shimmer means the live renderer is moving; steadily soft tiles during a CSS push means the fixed plate is underspecified, internally downsampled, or being scaled above `1`.
58
+
59
+ ## Verification
60
+
61
+ - Render a short MP4, not only a Studio preview.
62
+ - Inspect static terrain texture and satellite detail while the camera moves.
63
+ - If any underlying map detail wavers, use the fixed map plate. Do not approve it as a minor preview artefact.
64
+ - Render WebGL with `--gl=angle`, `preserveDrawingBuffer:true`, and conservative concurrency (`1`) while validating.
@@ -0,0 +1,202 @@
1
+ // Geo prep for the map-explainer. Bakes the data the component reads:
2
+ // out/river-flow.json -> the river draw-on line (→ copy to your Remotion project's src/geo/)
3
+ // out/country-meta.json -> per-country { stop, anchor, border } (→ src/geo/)
4
+ // out/borders.geojson -> country polygons, each tagged {country} (→ public/geo/ — loaded via staticFile)
5
+ //
6
+ // RUN: node prep-geo.mjs (needs YOUR geodata — see CONFIG; the source polygons are too large to ship,
7
+ // so the skill ships the OUTPUTS in assets/sample-data/ instead.)
8
+ //
9
+ // RIVER INPUT MUST BE ONE CLEAN LINESTRING, source → mouth (features[0].geometry is a LineString). If your
10
+ // OSM river comes as many ways / braided channels, ROUTE it into a single line FIRST — a graph
11
+ // shortest-path from source node to mouth node. Do NOT greedily chain by nearest endpoint: it bounces
12
+ // between parallel channels. (That routing step is a prerequisite, not part of this script.)
13
+
14
+ import {readFileSync, writeFileSync, mkdirSync} from 'fs';
15
+ import {dirname, resolve} from 'path';
16
+ import {fileURLToPath} from 'url';
17
+
18
+ if (process.argv.includes('--help')) {
19
+ console.log(
20
+ 'Configure COUNTRIES, RIVER, BORDER, label bounds, and output paths in this script, then run: bun scripts/prep-geo.mjs',
21
+ );
22
+ process.exit(0);
23
+ }
24
+
25
+ const turf = await import('@turf/turf');
26
+
27
+ const __dir = dirname(fileURLToPath(import.meta.url));
28
+ const root = resolve(__dir, '..');
29
+ const geo = resolve(root, '../geodata'); // ADAPT: where your input GeoJSON lives
30
+ const read = (p) => JSON.parse(readFileSync(p, 'utf8'));
31
+
32
+ // ===== CONFIG — edit for your river + countries =====
33
+ const COUNTRIES = ['china', 'india', 'bangladesh']; // ORDERED headwaters → mouth; first = source (stop 0)
34
+ const RIVER = resolve(geo, 'focus-rivers/yarlung-brahmaputra-full-osm.geojson'); // a single clean source→mouth LineString
35
+ const BORDER = (name) => resolve(geo, `project-borders/${name}.geojson`); // one polygon file per country, named <country>.geojson
36
+ const FRAME_BBOX = [76, 14, 104, 33.5]; // [W,S,E,N] visible extent — fallback for label anchoring only
37
+ const ANCHOR_BBOX = {
38
+ china: [82, 27, 96, 32],
39
+ india: [76, 14, 99, 31],
40
+ bangladesh: [86, 20, 93, 27],
41
+ }; // [W,S,E,N] per-country label "story region"
42
+ const NUDGE = {china: [0, 0.6], india: [-1.0, 0], bangladesh: [0, -0.6]}; // [lng,lat] label nudge
43
+ const RIVER_SIMPLIFY_TOL = 0.006; // degrees — smooths the draw-on (bigger = simpler)
44
+ const OUT_RIVER = resolve(root, 'out/river-flow.json');
45
+ const OUT_META = resolve(root, 'out/country-meta.json');
46
+ const OUT_BORDERS = resolve(root, 'out/borders.geojson');
47
+ // =====================================================
48
+
49
+ const havKm = (a, b) => {
50
+ const R = 6371,
51
+ r = Math.PI / 180;
52
+ const dLat = (b[1] - a[1]) * r,
53
+ dLng = (b[0] - a[0]) * r;
54
+ const h =
55
+ Math.sin(dLat / 2) ** 2 +
56
+ Math.cos(a[1] * r) * Math.cos(b[1] * r) * Math.sin(dLng / 2) ** 2;
57
+ return 2 * R * Math.asin(Math.sqrt(h));
58
+ };
59
+
60
+ // --- River draw-on line: take the clean routed LineString, strip a dangling final hop, simplify so the
61
+ // wide-zoom draw-on reads as one smooth thread (no bezier — meander overshoot on a long river). ---
62
+ const routed = read(RIVER).features[0].geometry.coordinates;
63
+ let end = routed.length;
64
+ while (end > 2 && havKm(routed[end - 2], routed[end - 1]) > 15) end--; // drop a final cross-braid jump if present
65
+ const flow = turf.simplify(turf.lineString(routed.slice(0, end)), {
66
+ tolerance: RIVER_SIMPLIFY_TOL,
67
+ highQuality: true,
68
+ }).geometry.coordinates;
69
+
70
+ // --- Borders + country fills (one source, filtered per country in the component) ---
71
+ const borders = {type: 'FeatureCollection', features: []};
72
+ const polys = {};
73
+ for (const name of COUNTRIES) {
74
+ const fc = read(BORDER(name));
75
+ polys[name] = fc;
76
+ for (const f of fc.features) {
77
+ f.properties = {...(f.properties || {}), country: name};
78
+ borders.features.push(f);
79
+ }
80
+ }
81
+
82
+ // --- Reveal stops: arc-length fraction of `flow` where the river first ENTERS each country. The first
83
+ // country (headwaters) is the source, so its stop is 0; the rest are computed. ---
84
+ const flowKm = turf.length(turf.lineString(flow));
85
+ const insideCountry = (pt, name) =>
86
+ polys[name].features.some((f) => turf.booleanPointInPolygon(pt, f));
87
+ const stops = {};
88
+ COUNTRIES.forEach((c, i) => {
89
+ stops[c] = i === 0 ? 0 : 1;
90
+ }); // 0 = headwaters; 1 = sentinel until entered
91
+ let acc = 0;
92
+ for (let i = 0; i < flow.length; i++) {
93
+ if (i > 0) acc += havKm(flow[i - 1], flow[i]);
94
+ const frac = acc / (flowKm || 1);
95
+ const pt = turf.point(flow[i]);
96
+ for (const c of COUNTRIES)
97
+ if (stops[c] === 1 && insideCountry(pt, c)) stops[c] = frac;
98
+ }
99
+
100
+ // --- Per-country meta: anchor = pole of inaccessibility of the visible landmass (centred, away from
101
+ // borders/edges) within the country's story region + a NUDGE; border = every exterior ring from the
102
+ // complete named source. Never crop a country or bilateral boundary to the viewport. ---
103
+ const biggestPoly = (geom) => {
104
+ const rings =
105
+ geom.type === 'MultiPolygon' ? geom.coordinates : [geom.coordinates];
106
+ let best = null,
107
+ bestA = -1;
108
+ for (const c of rings) {
109
+ const p = turf.polygon(c);
110
+ const a = turf.area(p);
111
+ if (a > bestA) {
112
+ bestA = a;
113
+ best = p;
114
+ }
115
+ }
116
+ return best;
117
+ };
118
+ const largestPolygon = (fc) => {
119
+ let best = null,
120
+ bestA = -1;
121
+ for (const f of fc.features) {
122
+ const p = biggestPoly(f.geometry),
123
+ a = turf.area(p);
124
+ if (a > bestA) {
125
+ bestA = a;
126
+ best = p;
127
+ }
128
+ }
129
+ return best;
130
+ };
131
+ const completeExteriorSegments = (fc) => {
132
+ const segments = [];
133
+ for (const feature of fc.features) {
134
+ const polygons =
135
+ feature.geometry.type === 'MultiPolygon'
136
+ ? feature.geometry.coordinates
137
+ : [feature.geometry.coordinates];
138
+ for (const polygon of polygons)
139
+ if (polygon[0]?.length > 1) segments.push(polygon[0]);
140
+ }
141
+ return segments;
142
+ };
143
+ const poleOfInaccessibility = (poly) => {
144
+ const bb = turf.bbox(poly),
145
+ boundary = turf.polygonToLine(poly),
146
+ N = 46;
147
+ let best = null,
148
+ bestD = -1;
149
+ for (let i = 0; i <= N; i++)
150
+ for (let j = 0; j <= N; j++) {
151
+ const lng = bb[0] + ((bb[2] - bb[0]) * i) / N,
152
+ lat = bb[1] + ((bb[3] - bb[1]) * j) / N;
153
+ const pt = turf.point([lng, lat]);
154
+ if (!turf.booleanPointInPolygon(pt, poly)) continue;
155
+ const d = turf.pointToLineDistance(pt, boundary);
156
+ if (d > bestD) {
157
+ bestD = d;
158
+ best = [lng, lat];
159
+ }
160
+ }
161
+ return best;
162
+ };
163
+ const countryMeta = {};
164
+ for (const name of COUNTRIES) {
165
+ const poly = largestPolygon(polys[name]);
166
+ const storyRegion = biggestPoly(
167
+ turf.bboxClip(poly, ANCHOR_BBOX[name] || FRAME_BBOX).geometry,
168
+ );
169
+ const pole = poleOfInaccessibility(storyRegion);
170
+ const segs = completeExteriorSegments(polys[name]);
171
+ const nudge = NUDGE[name] || [0, 0];
172
+ countryMeta[name] = {
173
+ stop: stops[name],
174
+ anchor: [pole[0] + nudge[0], pole[1] + nudge[1]],
175
+ border: segs,
176
+ };
177
+ }
178
+
179
+ mkdirSync(dirname(OUT_RIVER), {recursive: true});
180
+ writeFileSync(OUT_RIVER, JSON.stringify(flow));
181
+ writeFileSync(OUT_META, JSON.stringify(countryMeta));
182
+ writeFileSync(OUT_BORDERS, JSON.stringify(borders));
183
+ console.log(
184
+ 'river:',
185
+ flow.length,
186
+ 'pts ·',
187
+ flowKm.toFixed(0),
188
+ 'km · entry stops',
189
+ JSON.stringify(stops),
190
+ );
191
+ for (const n of COUNTRIES) {
192
+ const km = countryMeta[n].border.reduce(
193
+ (s, seg) => s + turf.length(turf.lineString(seg)),
194
+ 0,
195
+ );
196
+ console.log(
197
+ ` ${n}: anchor ${countryMeta[n].anchor.map((v) => v.toFixed(2)).join(',')} · border ${km.toFixed(0)} km`,
198
+ );
199
+ }
200
+ console.log(
201
+ "\nNext: copy out/river-flow.json + out/country-meta.json → your project's src/geo/ ; out/borders.geojson → public/geo/",
202
+ );
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: remotion-maps-static
3
+ description: Create a deterministic static locator map in Remotion when neither the camera nor geographic data animates.
4
+ ---
5
+
6
+ # Static map
7
+
8
+ Use a static image when the map only provides location context. This is the smallest, fastest, and
9
+ most deterministic map technique.
10
+
11
+ ## Build
12
+
13
+ 1. Export or request a map image at the composition's final aspect ratio and at least its rendered
14
+ pixel dimensions.
15
+ 2. Store the image in the Remotion project's `public/` directory.
16
+ 3. Render it with `CanvasImage` and `staticFile()`.
17
+ 4. Add labels or markers as ordinary Remotion elements if they remain fixed.
18
+
19
+ ```tsx
20
+ import React from 'react';
21
+ import {AbsoluteFill, CanvasImage, staticFile} from 'remotion';
22
+
23
+ export const StaticMap: React.FC = () => {
24
+ return (
25
+ <>
26
+ <CanvasImage
27
+ src={staticFile('locator-map.png')}
28
+ style={{width: '100%', height: '100%', objectFit: 'cover'}}
29
+ />
30
+ </>
31
+ );
32
+ };
33
+ ```
34
+
35
+ ## Overlays and Interactivity
36
+
37
+ Follow [Remotion Interactivity](../../../remotion-interactivity/SKILL.md) best practices and [Remotion Markup Best practices](../../../remotion-markup/SKILL.md) for elements.
@@ -0,0 +1,86 @@
1
+ ---
2
+ name: 3d
3
+ description: 3D content in Remotion using Three.js and React Three Fiber.
4
+ metadata:
5
+ tags: 3d, three, threejs
6
+ ---
7
+
8
+ # Using Three.js and React Three Fiber in Remotion
9
+
10
+ Follow React Three Fiber and Three.js best practices.
11
+ Only the following Remotion-specific rules need to be followed:
12
+
13
+ ## Prerequisites
14
+
15
+ First, the `@remotion/three` package needs to be installed.
16
+ If it is not, use the following command:
17
+
18
+ ```bash
19
+ npx remotion add @remotion/three # If project uses npm
20
+ bunx remotion add @remotion/three # If project uses bun
21
+ yarn remotion add @remotion/three # If project uses yarn
22
+ pnpm exec remotion add @remotion/three # If project uses pnpm
23
+ ```
24
+
25
+ ## Using ThreeCanvas
26
+
27
+ You MUST wrap 3D content in `<ThreeCanvas>` and include proper lighting.
28
+ `<ThreeCanvas>` MUST have a `width` and `height` prop.
29
+
30
+ ```tsx
31
+ import { ThreeCanvas } from "@remotion/three";
32
+ import { useVideoConfig } from "remotion";
33
+
34
+ const { width, height } = useVideoConfig();
35
+
36
+ <ThreeCanvas width={width} height={height}>
37
+ <ambientLight intensity={0.4} />
38
+ <directionalLight position={[5, 5, 5]} intensity={0.8} />
39
+ <mesh>
40
+ <sphereGeometry args={[1, 32, 32]} />
41
+ <meshStandardMaterial color="red" />
42
+ </mesh>
43
+ </ThreeCanvas>;
44
+ ```
45
+
46
+ ## No animations not driven by `useCurrentFrame()`
47
+
48
+ Shaders, models etc MUST NOT animate by themselves.
49
+ No animations are allowed unless they are driven by `useCurrentFrame()`.
50
+ Otherwise, it will cause flickering during rendering.
51
+
52
+ Using `useFrame()` from `@react-three/fiber` is forbidden.
53
+
54
+ ## Animate using `useCurrentFrame()`
55
+
56
+ Use `useCurrentFrame()` to perform animations.
57
+
58
+ ```tsx
59
+ const frame = useCurrentFrame();
60
+ const rotationY = frame * 0.02;
61
+
62
+ <mesh rotation={[0, rotationY, 0]}>
63
+ <boxGeometry args={[2, 2, 2]} />
64
+ <meshStandardMaterial color="#4a9eff" />
65
+ </mesh>;
66
+ ```
67
+
68
+ ## Using `<Sequence>` inside `<ThreeCanvas>`
69
+
70
+ The `layout` prop of any `<Sequence>` inside a `<ThreeCanvas>` must be set to `none`.
71
+
72
+ ```tsx
73
+ import { Sequence } from "remotion";
74
+ import { ThreeCanvas } from "@remotion/three";
75
+
76
+ const { width, height } = useVideoConfig();
77
+
78
+ <ThreeCanvas width={width} height={height}>
79
+ <Sequence layout="none">
80
+ <mesh>
81
+ <boxGeometry args={[2, 2, 2]} />
82
+ <meshStandardMaterial color="#4a9eff" />
83
+ </mesh>
84
+ </Sequence>
85
+ </ThreeCanvas>;
86
+ ```