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.
- package/README.en.md +7 -5
- package/README.md +3 -3
- package/lib/index.d.ts +2 -2
- package/lib/index.js +15 -2
- package/package.json +1 -1
- package/skills/remotion-best-practices/SKILL.md +59 -0
- package/skills/remotion-best-practices/agents/openai.yaml +7 -0
- package/skills/remotion-best-practices/assets/remotion-icon.png +0 -0
- package/skills/remotion-best-practices/remotion-captions/SKILL.md +36 -0
- package/skills/remotion-best-practices/remotion-captions/agents/openai.yaml +7 -0
- package/skills/remotion-best-practices/remotion-captions/assets/remotion-icon.png +0 -0
- package/skills/{remotion/rules → remotion-best-practices/remotion-captions}/display-captions.md +9 -3
- package/skills/{remotion/rules → remotion-best-practices/remotion-captions}/import-srt-captions.md +5 -1
- package/skills/remotion-best-practices/remotion-create/SKILL.md +68 -0
- package/skills/remotion-best-practices/remotion-create/agents/openai.yaml +7 -0
- package/skills/remotion-best-practices/remotion-create/assets/remotion-icon.png +0 -0
- package/skills/{remotion/rules → remotion-best-practices/remotion-create}/tailwind.md +1 -1
- package/skills/remotion-best-practices/remotion-create/video-layout.md +9 -0
- package/skills/remotion-best-practices/remotion-docs/SKILL.md +46 -0
- package/skills/remotion-best-practices/remotion-docs/agents/openai.yaml +7 -0
- package/skills/remotion-best-practices/remotion-docs/assets/remotion-icon.png +0 -0
- package/skills/remotion-best-practices/remotion-interactivity/SKILL.md +247 -0
- package/skills/remotion-best-practices/remotion-interactivity/agents/openai.yaml +7 -0
- package/skills/remotion-best-practices/remotion-interactivity/assets/remotion-icon.png +0 -0
- package/skills/remotion-best-practices/remotion-maps/SKILL.md +36 -0
- package/skills/remotion-best-practices/remotion-maps/agents/openai.yaml +7 -0
- package/skills/remotion-best-practices/remotion-maps/assets/remotion-icon.png +0 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/cesium/TECHNIQUE.md +89 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/cesium/assets/CesiumFlythrough.tsx +284 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/cesium/assets/cesium-path.json +299 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/cesium/assets/city-path.json +12 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/cesium/assets/example-Root.tsx +39 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/cesium/assets/flight-path.ts +35 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/cesium/assets/sample-river.geojson +215 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/cesium/references/3d-data-sources.md +43 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/cesium/references/3d-flyover-architecture.md +128 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/cesium/references/3d-troubleshooting.md +57 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/cesium/scripts/prep-cesium-path.mjs +161 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/mapbox/TECHNIQUE.md +449 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/mapbox/references/render-stability.md +64 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/maplibre/TECHNIQUE.md +465 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/maplibre/references/render-stability.md +64 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/TECHNIQUE.md +80 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/assets/CountryLabel.tsx +70 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/assets/MapTilerVectorElement.ts +80 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/assets/RiverReveal.tsx +363 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/assets/example-Root.tsx +22 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/assets/sample-data/country-meta.json +7535 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/assets/sample-data/yarlung-flow.json +605 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/assets/tokens.ts +34 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/references/map-data-sources.md +91 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/references/map-explainer-architecture.md +129 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/references/map-geo-prep.md +85 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/references/render-stability.md +64 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/scripts/prep-geo.mjs +202 -0
- package/skills/remotion-best-practices/remotion-maps/techniques/static-map/TECHNIQUE.md +37 -0
- package/skills/remotion-best-practices/remotion-markup/SKILL.md +365 -0
- package/skills/remotion-best-practices/remotion-markup/agents/openai.yaml +7 -0
- package/skills/remotion-best-practices/remotion-markup/assets/remotion-icon.png +0 -0
- package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/audio.md +4 -2
- package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/calculate-metadata.md +4 -2
- package/skills/remotion-best-practices/remotion-markup/compositions.md +117 -0
- package/skills/remotion-best-practices/remotion-markup/cropping.md +34 -0
- package/skills/remotion-best-practices/remotion-markup/effects.md +251 -0
- package/skills/{remotion/rules/videos.md → remotion-best-practices/remotion-markup/embedding-videos.md} +6 -4
- package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/ffmpeg.md +5 -1
- package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/gifs.md +55 -9
- package/skills/remotion-best-practices/remotion-markup/google-fonts.md +76 -0
- package/skills/remotion-best-practices/remotion-markup/html-in-canvas.md +128 -0
- package/skills/remotion-best-practices/remotion-markup/images.md +73 -0
- package/skills/remotion-best-practices/remotion-markup/light-leaks.md +106 -0
- package/skills/remotion-best-practices/remotion-markup/local-fonts.md +69 -0
- package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/lottie.md +4 -1
- package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/measuring-dom-nodes.md +5 -1
- package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/measuring-text.md +8 -2
- package/skills/remotion-best-practices/remotion-markup/multi-scene-video.md +81 -0
- package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/parameters.md +3 -1
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/SKILL.md +36 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/agents/openai.yaml +7 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/assets/remotion-icon.png +0 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/TECHNIQUE.md +89 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/assets/CesiumFlythrough.tsx +284 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/assets/cesium-path.json +299 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/assets/city-path.json +12 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/assets/example-Root.tsx +39 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/assets/flight-path.ts +35 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/assets/sample-river.geojson +215 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/references/3d-data-sources.md +43 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/references/3d-flyover-architecture.md +128 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/references/3d-troubleshooting.md +57 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/cesium/scripts/prep-cesium-path.mjs +161 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/mapbox/TECHNIQUE.md +449 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/mapbox/references/render-stability.md +64 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maplibre/TECHNIQUE.md +465 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maplibre/references/render-stability.md +64 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/TECHNIQUE.md +80 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/assets/CountryLabel.tsx +70 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/assets/MapTilerVectorElement.ts +80 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/assets/RiverReveal.tsx +363 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/assets/example-Root.tsx +22 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/assets/sample-data/country-meta.json +7535 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/assets/sample-data/yarlung-flow.json +605 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/assets/tokens.ts +34 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/references/map-data-sources.md +91 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/references/map-explainer-architecture.md +129 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/references/map-geo-prep.md +85 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/references/render-stability.md +64 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/maptiler/scripts/prep-geo.mjs +202 -0
- package/skills/remotion-best-practices/remotion-markup/remotion-maps/techniques/static-map/TECHNIQUE.md +37 -0
- package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/sequencing.md +63 -12
- package/skills/remotion-best-practices/remotion-markup/sfx.md +51 -0
- package/skills/remotion-best-practices/remotion-markup/text-highlights.md +56 -0
- package/skills/remotion-best-practices/remotion-markup/timing.md +111 -0
- package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/transitions.md +49 -7
- package/skills/remotion-best-practices/remotion-markup/video-editing.md +90 -0
- package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/voiceover.md +2 -2
- package/skills/remotion-best-practices/remotion-multimedia/SKILL.md +20 -0
- package/skills/remotion-best-practices/remotion-multimedia/agents/openai.yaml +7 -0
- package/skills/remotion-best-practices/remotion-multimedia/assets/remotion-icon.png +0 -0
- package/skills/{remotion/rules → remotion-best-practices/remotion-multimedia}/get-audio-duration.md +1 -3
- package/skills/{remotion/rules → remotion-best-practices/remotion-multimedia}/get-video-dimensions.md +1 -3
- package/skills/{remotion/rules → remotion-best-practices/remotion-multimedia}/get-video-duration.md +1 -3
- package/skills/remotion-best-practices/remotion-render/SKILL.md +27 -0
- package/skills/remotion-best-practices/remotion-render/agents/openai.yaml +7 -0
- package/skills/remotion-best-practices/remotion-render/assets/remotion-icon.png +0 -0
- package/skills/remotion-best-practices/remotion-saas/SKILL.md +33 -0
- package/skills/remotion-best-practices/remotion-saas/agents/openai.yaml +7 -0
- package/skills/remotion-best-practices/remotion-saas/assets/remotion-icon.png +0 -0
- package/skills/remotion-best-practices/remotion-saas/framework.md +21 -0
- package/skills/remotion-best-practices/remotion-saas/player.md +33 -0
- package/skills/remotion-best-practices/remotion-saas/rendering.md +69 -0
- package/skills/remotion-best-practices/remotion-studio/SKILL.md +24 -0
- package/skills/remotion-best-practices/remotion-studio/agents/openai.yaml +7 -0
- package/skills/remotion-best-practices/remotion-studio/assets/remotion-icon.png +0 -0
- package/skills/remotion-best-practices/remotion-upgrade/SKILL.md +31 -0
- package/skills/remotion-best-practices/remotion-upgrade/agents/openai.yaml +7 -0
- package/skills/remotion-best-practices/remotion-upgrade/assets/remotion-icon.png +0 -0
- package/skills/remotion-captions/SKILL.md +36 -0
- package/skills/remotion-captions/agents/openai.yaml +7 -0
- package/skills/remotion-captions/assets/remotion-icon.png +0 -0
- package/skills/remotion-captions/display-captions.md +190 -0
- package/skills/remotion-captions/import-srt-captions.md +73 -0
- package/skills/remotion-captions/transcribe-captions.md +70 -0
- package/skills/remotion-create/SKILL.md +68 -0
- package/skills/remotion-create/agents/openai.yaml +7 -0
- package/skills/remotion-create/assets/remotion-icon.png +0 -0
- package/skills/remotion-create/tailwind.md +11 -0
- package/skills/remotion-create/video-layout.md +9 -0
- package/skills/remotion-docs/SKILL.md +46 -0
- package/skills/remotion-docs/agents/openai.yaml +7 -0
- package/skills/remotion-docs/assets/remotion-icon.png +0 -0
- package/skills/remotion-interactivity/SKILL.md +247 -0
- package/skills/remotion-interactivity/agents/openai.yaml +7 -0
- package/skills/remotion-interactivity/assets/remotion-icon.png +0 -0
- package/skills/remotion-maps/SKILL.md +36 -0
- package/skills/remotion-maps/agents/openai.yaml +7 -0
- package/skills/remotion-maps/assets/remotion-icon.png +0 -0
- package/skills/remotion-maps/techniques/cesium/TECHNIQUE.md +89 -0
- package/skills/remotion-maps/techniques/cesium/assets/CesiumFlythrough.tsx +284 -0
- package/skills/remotion-maps/techniques/cesium/assets/cesium-path.json +299 -0
- package/skills/remotion-maps/techniques/cesium/assets/city-path.json +12 -0
- package/skills/remotion-maps/techniques/cesium/assets/example-Root.tsx +39 -0
- package/skills/remotion-maps/techniques/cesium/assets/flight-path.ts +35 -0
- package/skills/remotion-maps/techniques/cesium/assets/sample-river.geojson +215 -0
- package/skills/remotion-maps/techniques/cesium/references/3d-data-sources.md +43 -0
- package/skills/remotion-maps/techniques/cesium/references/3d-flyover-architecture.md +128 -0
- package/skills/remotion-maps/techniques/cesium/references/3d-troubleshooting.md +57 -0
- package/skills/remotion-maps/techniques/cesium/scripts/prep-cesium-path.mjs +161 -0
- package/skills/remotion-maps/techniques/mapbox/TECHNIQUE.md +449 -0
- package/skills/remotion-maps/techniques/mapbox/references/render-stability.md +64 -0
- package/skills/remotion-maps/techniques/maplibre/TECHNIQUE.md +465 -0
- package/skills/remotion-maps/techniques/maplibre/references/render-stability.md +64 -0
- package/skills/remotion-maps/techniques/maptiler/TECHNIQUE.md +80 -0
- package/skills/remotion-maps/techniques/maptiler/assets/CountryLabel.tsx +70 -0
- package/skills/remotion-maps/techniques/maptiler/assets/MapTilerVectorElement.ts +80 -0
- package/skills/remotion-maps/techniques/maptiler/assets/RiverReveal.tsx +363 -0
- package/skills/remotion-maps/techniques/maptiler/assets/example-Root.tsx +22 -0
- package/skills/remotion-maps/techniques/maptiler/assets/sample-data/country-meta.json +7535 -0
- package/skills/remotion-maps/techniques/maptiler/assets/sample-data/yarlung-flow.json +605 -0
- package/skills/remotion-maps/techniques/maptiler/assets/tokens.ts +34 -0
- package/skills/remotion-maps/techniques/maptiler/references/map-data-sources.md +91 -0
- package/skills/remotion-maps/techniques/maptiler/references/map-explainer-architecture.md +129 -0
- package/skills/remotion-maps/techniques/maptiler/references/map-geo-prep.md +85 -0
- package/skills/remotion-maps/techniques/maptiler/references/render-stability.md +64 -0
- package/skills/remotion-maps/techniques/maptiler/scripts/prep-geo.mjs +202 -0
- package/skills/remotion-maps/techniques/static-map/TECHNIQUE.md +37 -0
- package/skills/remotion-markup/3d.md +86 -0
- package/skills/remotion-markup/SKILL.md +365 -0
- package/skills/remotion-markup/agents/openai.yaml +7 -0
- package/skills/remotion-markup/assets/remotion-icon.png +0 -0
- package/skills/remotion-markup/audio-visualization.md +198 -0
- package/skills/remotion-markup/audio.md +171 -0
- package/skills/remotion-markup/calculate-metadata.md +136 -0
- package/skills/remotion-markup/compositions.md +117 -0
- package/skills/remotion-markup/cropping.md +34 -0
- package/skills/remotion-markup/effects.md +251 -0
- package/skills/remotion-markup/embedding-videos.md +173 -0
- package/skills/remotion-markup/ffmpeg.md +38 -0
- package/skills/remotion-markup/gifs.md +187 -0
- package/skills/remotion-markup/google-fonts.md +76 -0
- package/skills/remotion-markup/html-in-canvas.md +128 -0
- package/skills/remotion-markup/images.md +73 -0
- package/skills/remotion-markup/light-leaks.md +106 -0
- package/skills/remotion-markup/local-fonts.md +69 -0
- package/skills/remotion-markup/lottie.md +73 -0
- package/skills/remotion-markup/measuring-dom-nodes.md +38 -0
- package/skills/remotion-markup/measuring-text.md +146 -0
- package/skills/remotion-markup/multi-scene-video.md +81 -0
- package/skills/remotion-markup/parameters.md +111 -0
- package/skills/remotion-markup/remotion-maps/SKILL.md +36 -0
- package/skills/remotion-markup/remotion-maps/agents/openai.yaml +7 -0
- package/skills/remotion-markup/remotion-maps/assets/remotion-icon.png +0 -0
- package/skills/remotion-markup/remotion-maps/techniques/cesium/TECHNIQUE.md +89 -0
- package/skills/remotion-markup/remotion-maps/techniques/cesium/assets/CesiumFlythrough.tsx +284 -0
- package/skills/remotion-markup/remotion-maps/techniques/cesium/assets/cesium-path.json +299 -0
- package/skills/remotion-markup/remotion-maps/techniques/cesium/assets/city-path.json +12 -0
- package/skills/remotion-markup/remotion-maps/techniques/cesium/assets/example-Root.tsx +39 -0
- package/skills/remotion-markup/remotion-maps/techniques/cesium/assets/flight-path.ts +35 -0
- package/skills/remotion-markup/remotion-maps/techniques/cesium/assets/sample-river.geojson +215 -0
- package/skills/remotion-markup/remotion-maps/techniques/cesium/references/3d-data-sources.md +43 -0
- package/skills/remotion-markup/remotion-maps/techniques/cesium/references/3d-flyover-architecture.md +128 -0
- package/skills/remotion-markup/remotion-maps/techniques/cesium/references/3d-troubleshooting.md +57 -0
- package/skills/remotion-markup/remotion-maps/techniques/cesium/scripts/prep-cesium-path.mjs +161 -0
- package/skills/remotion-markup/remotion-maps/techniques/mapbox/TECHNIQUE.md +449 -0
- package/skills/remotion-markup/remotion-maps/techniques/mapbox/references/render-stability.md +64 -0
- package/skills/remotion-markup/remotion-maps/techniques/maplibre/TECHNIQUE.md +465 -0
- package/skills/remotion-markup/remotion-maps/techniques/maplibre/references/render-stability.md +64 -0
- package/skills/remotion-markup/remotion-maps/techniques/maptiler/TECHNIQUE.md +80 -0
- package/skills/remotion-markup/remotion-maps/techniques/maptiler/assets/CountryLabel.tsx +70 -0
- package/skills/remotion-markup/remotion-maps/techniques/maptiler/assets/MapTilerVectorElement.ts +80 -0
- package/skills/remotion-markup/remotion-maps/techniques/maptiler/assets/RiverReveal.tsx +363 -0
- package/skills/remotion-markup/remotion-maps/techniques/maptiler/assets/example-Root.tsx +22 -0
- package/skills/remotion-markup/remotion-maps/techniques/maptiler/assets/sample-data/country-meta.json +7535 -0
- package/skills/remotion-markup/remotion-maps/techniques/maptiler/assets/sample-data/yarlung-flow.json +605 -0
- package/skills/remotion-markup/remotion-maps/techniques/maptiler/assets/tokens.ts +34 -0
- package/skills/remotion-markup/remotion-maps/techniques/maptiler/references/map-data-sources.md +91 -0
- package/skills/remotion-markup/remotion-maps/techniques/maptiler/references/map-explainer-architecture.md +129 -0
- package/skills/remotion-markup/remotion-maps/techniques/maptiler/references/map-geo-prep.md +85 -0
- package/skills/remotion-markup/remotion-maps/techniques/maptiler/references/render-stability.md +64 -0
- package/skills/remotion-markup/remotion-maps/techniques/maptiler/scripts/prep-geo.mjs +202 -0
- package/skills/remotion-markup/remotion-maps/techniques/static-map/TECHNIQUE.md +37 -0
- package/skills/remotion-markup/sequencing.md +169 -0
- package/skills/remotion-markup/sfx.md +51 -0
- package/skills/remotion-markup/silence-detection.md +71 -0
- package/skills/remotion-markup/text-highlights.md +56 -0
- package/skills/remotion-markup/timing.md +111 -0
- package/skills/remotion-markup/transitions.md +239 -0
- package/skills/remotion-markup/video-editing.md +90 -0
- package/skills/remotion-markup/voiceover.md +99 -0
- package/skills/remotion-multimedia/SKILL.md +20 -0
- package/skills/remotion-multimedia/agents/openai.yaml +7 -0
- package/skills/remotion-multimedia/assets/remotion-icon.png +0 -0
- package/skills/remotion-multimedia/get-audio-duration.md +56 -0
- package/skills/remotion-multimedia/get-video-dimensions.md +66 -0
- package/skills/remotion-multimedia/get-video-duration.md +58 -0
- package/skills/remotion-render/SKILL.md +27 -0
- package/skills/remotion-render/agents/openai.yaml +7 -0
- package/skills/remotion-render/assets/remotion-icon.png +0 -0
- package/skills/remotion-render/transparent-videos.md +106 -0
- package/skills/remotion-saas/SKILL.md +33 -0
- package/skills/remotion-saas/agents/openai.yaml +7 -0
- package/skills/remotion-saas/assets/remotion-icon.png +0 -0
- package/skills/remotion-saas/framework.md +21 -0
- package/skills/remotion-saas/player.md +33 -0
- package/skills/remotion-saas/rendering.md +69 -0
- package/skills/remotion-studio/SKILL.md +24 -0
- package/skills/remotion-studio/agents/openai.yaml +7 -0
- package/skills/remotion-studio/assets/remotion-icon.png +0 -0
- package/skills/remotion-upgrade/SKILL.md +31 -0
- package/skills/remotion-upgrade/agents/openai.yaml +7 -0
- package/skills/remotion-upgrade/assets/remotion-icon.png +0 -0
- package/skills/remotion/SKILL.md +0 -95
- package/skills/remotion/rules/animations.md +0 -31
- package/skills/remotion/rules/assets.md +0 -78
- package/skills/remotion/rules/can-decode.md +0 -81
- package/skills/remotion/rules/charts.md +0 -120
- package/skills/remotion/rules/compositions.md +0 -154
- package/skills/remotion/rules/extract-frames.md +0 -229
- package/skills/remotion/rules/fonts.md +0 -152
- package/skills/remotion/rules/images.md +0 -134
- package/skills/remotion/rules/light-leaks.md +0 -73
- package/skills/remotion/rules/maps.md +0 -412
- package/skills/remotion/rules/sfx.md +0 -30
- package/skills/remotion/rules/subtitles.md +0 -36
- package/skills/remotion/rules/text-animations.md +0 -20
- package/skills/remotion/rules/timing.md +0 -136
- package/skills/remotion/rules/trimming.md +0 -51
- /package/skills/{remotion/rules → remotion-best-practices/remotion-captions}/transcribe-captions.md +0 -0
- /package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/3d.md +0 -0
- /package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/audio-visualization.md +0 -0
- /package/skills/{remotion/rules → remotion-best-practices/remotion-markup}/silence-detection.md +0 -0
- /package/skills/{remotion/rules → remotion-best-practices/remotion-render}/transparent-videos.md +0 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Surface an existing MapTiler Planet feature without maintaining duplicate GeoJSON.
|
|
2
|
+
// Paint animation is deterministic; geometry slicing is not. For a source-to-end line draw,
|
|
3
|
+
// bake the selected feature to ordered GeoJSON and use RiverReveal.tsx instead.
|
|
4
|
+
|
|
5
|
+
type VectorLayerType = 'fill' | 'line' | 'circle' | 'symbol';
|
|
6
|
+
|
|
7
|
+
export type MapTilerVectorElement = {
|
|
8
|
+
id: string;
|
|
9
|
+
sourceLayer: string;
|
|
10
|
+
type: VectorLayerType;
|
|
11
|
+
filter?: unknown[];
|
|
12
|
+
minzoom?: number;
|
|
13
|
+
maxzoom?: number;
|
|
14
|
+
layout?: Record<string, unknown>;
|
|
15
|
+
paint: Record<string, unknown>;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const SOURCE_ID = 'maptiler-planet';
|
|
19
|
+
|
|
20
|
+
export const addMapTilerVectorElement = (
|
|
21
|
+
map: any,
|
|
22
|
+
apiKey: string,
|
|
23
|
+
element: MapTilerVectorElement,
|
|
24
|
+
beforeId?: string,
|
|
25
|
+
) => {
|
|
26
|
+
if (!map.getSource(SOURCE_ID)) {
|
|
27
|
+
map.addSource(SOURCE_ID, {
|
|
28
|
+
type: 'vector',
|
|
29
|
+
url: `https://api.maptiler.com/tiles/v3/tiles.json?key=${apiKey}`,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (map.getLayer(element.id)) return;
|
|
34
|
+
|
|
35
|
+
map.addLayer(
|
|
36
|
+
{
|
|
37
|
+
id: element.id,
|
|
38
|
+
type: element.type,
|
|
39
|
+
source: SOURCE_ID,
|
|
40
|
+
'source-layer': element.sourceLayer,
|
|
41
|
+
...(element.filter ? {filter: element.filter} : {}),
|
|
42
|
+
...(element.minzoom === undefined ? {} : {minzoom: element.minzoom}),
|
|
43
|
+
...(element.maxzoom === undefined ? {} : {maxzoom: element.maxzoom}),
|
|
44
|
+
...(element.layout ? {layout: element.layout} : {}),
|
|
45
|
+
paint: element.paint,
|
|
46
|
+
},
|
|
47
|
+
beforeId,
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const setVectorElementPaint = (
|
|
52
|
+
map: any,
|
|
53
|
+
layerId: string,
|
|
54
|
+
paint: Record<string, unknown>,
|
|
55
|
+
) => {
|
|
56
|
+
for (const [property, value] of Object.entries(paint)) {
|
|
57
|
+
map.setPaintProperty(layerId, property, value);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Example:
|
|
62
|
+
//
|
|
63
|
+
// addMapTilerVectorElement(map, process.env.REMOTION_MAPTILER_KEY!, {
|
|
64
|
+
// id: "story-river",
|
|
65
|
+
// sourceLayer: "waterway",
|
|
66
|
+
// type: "line",
|
|
67
|
+
// filter: [
|
|
68
|
+
// "all",
|
|
69
|
+
// ["==", ["get", "class"], "river"],
|
|
70
|
+
// ["==", ["coalesce", ["get", "name_en"], ["get", "name"]], "Yarlung Tsangpo"],
|
|
71
|
+
// ],
|
|
72
|
+
// layout: {"line-cap": "round", "line-join": "round"},
|
|
73
|
+
// paint: {"line-color": "#E8F7FF", "line-width": 3, "line-opacity": 0},
|
|
74
|
+
// });
|
|
75
|
+
//
|
|
76
|
+
// Per Remotion frame:
|
|
77
|
+
// setVectorElementPaint(map, "story-river", {
|
|
78
|
+
// "line-opacity": reveal,
|
|
79
|
+
// "line-width": 2 + reveal * 2,
|
|
80
|
+
// });
|
package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/assets/RiverReveal.tsx
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import * as maptilersdk from '@maptiler/sdk';
|
|
2
|
+
import * as turf from '@turf/turf';
|
|
3
|
+
import React, {useEffect, useRef, useState} from 'react';
|
|
4
|
+
import '@maptiler/sdk/dist/maptiler-sdk.css';
|
|
5
|
+
import {
|
|
6
|
+
AbsoluteFill,
|
|
7
|
+
Easing,
|
|
8
|
+
continueRender,
|
|
9
|
+
delayRender,
|
|
10
|
+
interpolate,
|
|
11
|
+
useCurrentFrame,
|
|
12
|
+
useVideoConfig,
|
|
13
|
+
} from 'remotion';
|
|
14
|
+
import {CountryLabel} from './CountryLabel';
|
|
15
|
+
import countryMeta from './sample-data/country-meta.json';
|
|
16
|
+
import flowCoords from './sample-data/yarlung-flow.json';
|
|
17
|
+
import {COLORS, COUNTRY, COUNTRY_DARK, FILL_OPACITY} from './tokens';
|
|
18
|
+
|
|
19
|
+
// Sample route reveal. Replace the imported sample geometry, names, timing, and visual tokens in the
|
|
20
|
+
// consuming production. The renderer stays static; approved centre/zoom motion is a CSS plate transform.
|
|
21
|
+
|
|
22
|
+
maptilersdk.config.apiKey = process.env.REMOTION_MAPTILER_KEY as string;
|
|
23
|
+
|
|
24
|
+
const line = turf.lineString(flowCoords as [number, number][]);
|
|
25
|
+
const lineKm = turf.length(line);
|
|
26
|
+
|
|
27
|
+
const START = {
|
|
28
|
+
center: [89.6, 27.7] as [number, number],
|
|
29
|
+
zoom: 4.75,
|
|
30
|
+
pitch: 0,
|
|
31
|
+
bearing: 0,
|
|
32
|
+
};
|
|
33
|
+
const END = {
|
|
34
|
+
center: [90.2, 27.0] as [number, number],
|
|
35
|
+
zoom: 5.05,
|
|
36
|
+
pitch: 0,
|
|
37
|
+
bearing: 0,
|
|
38
|
+
};
|
|
39
|
+
const lerp = (a: number, b: number, t: number) => a + (b - a) * t;
|
|
40
|
+
const clamp01 = (v: number) => Math.max(0, Math.min(1, v));
|
|
41
|
+
|
|
42
|
+
const ORDER = ['china', 'india', 'bangladesh'] as const;
|
|
43
|
+
type Country = (typeof ORDER)[number];
|
|
44
|
+
const META = countryMeta as Record<
|
|
45
|
+
Country,
|
|
46
|
+
{stop: number; anchor: [number, number]; border: [number, number][][]}
|
|
47
|
+
>;
|
|
48
|
+
const countryPolygons = {
|
|
49
|
+
type: 'FeatureCollection' as const,
|
|
50
|
+
features: ORDER.map((country) => ({
|
|
51
|
+
type: 'Feature' as const,
|
|
52
|
+
properties: {country},
|
|
53
|
+
geometry: {
|
|
54
|
+
type: 'MultiPolygon' as const,
|
|
55
|
+
coordinates: META[country].border.map((ring) => [ring]),
|
|
56
|
+
},
|
|
57
|
+
})),
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Pre-build each country's border as ordered segments with cumulative lengths (for the multi-segment draw).
|
|
61
|
+
const DRAW = Object.fromEntries(
|
|
62
|
+
ORDER.map((c) => {
|
|
63
|
+
const segLines = META[c].border.map((s) => turf.lineString(s));
|
|
64
|
+
const segLen = segLines.map((l) => turf.length(l));
|
|
65
|
+
const cum: number[] = [];
|
|
66
|
+
let acc = 0;
|
|
67
|
+
for (const L of segLen) {
|
|
68
|
+
cum.push(acc);
|
|
69
|
+
acc += L;
|
|
70
|
+
}
|
|
71
|
+
return [c, {segLines, segLen, cum, total: acc}];
|
|
72
|
+
}),
|
|
73
|
+
) as Record<
|
|
74
|
+
Country,
|
|
75
|
+
{segLines: any[]; segLen: number[]; cum: number[]; total: number}
|
|
76
|
+
>;
|
|
77
|
+
|
|
78
|
+
// Reveal the portion of the border between fromKm and toKm as a MultiLineString (no joins across gaps).
|
|
79
|
+
const sliceBorder = (
|
|
80
|
+
d: (typeof DRAW)[Country],
|
|
81
|
+
fromKm: number,
|
|
82
|
+
toKm: number,
|
|
83
|
+
) => {
|
|
84
|
+
const out: number[][][] = [];
|
|
85
|
+
for (let i = 0; i < d.segLines.length; i++) {
|
|
86
|
+
const start = d.cum[i],
|
|
87
|
+
end = start + d.segLen[i];
|
|
88
|
+
const a = Math.max(fromKm, start),
|
|
89
|
+
b = Math.min(toKm, end);
|
|
90
|
+
if (b - a <= 0.0008) continue;
|
|
91
|
+
out.push(
|
|
92
|
+
turf.lineSliceAlong(d.segLines[i], a - start, b - start).geometry
|
|
93
|
+
.coordinates,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
type: 'Feature' as const,
|
|
98
|
+
properties: {},
|
|
99
|
+
geometry: {type: 'MultiLineString' as const, coordinates: out},
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
const EMPTY = {
|
|
103
|
+
type: 'Feature' as const,
|
|
104
|
+
properties: {},
|
|
105
|
+
geometry: {type: 'MultiLineString' as const, coordinates: [] as number[][][]},
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// --- Timing (seconds). River draws over [RIVER_START, RIVER_END]; each country triggers when the river
|
|
109
|
+
// reaches it (stop · span), then runs border → fill → label. Beat length is derived from these. ---
|
|
110
|
+
const RIVER_START = 0.3;
|
|
111
|
+
const RIVER_END = 8.0;
|
|
112
|
+
const BORDER_S = 2.5;
|
|
113
|
+
const FILL_S = 1.0;
|
|
114
|
+
const LABEL_S = 0.7;
|
|
115
|
+
const trigger = (c: Country) =>
|
|
116
|
+
RIVER_START + META[c].stop * (RIVER_END - RIVER_START);
|
|
117
|
+
|
|
118
|
+
export const RiverReveal: React.FC = () => {
|
|
119
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
120
|
+
const started = useRef(false);
|
|
121
|
+
const frame = useCurrentFrame();
|
|
122
|
+
const {fps, durationInFrames, width, height} = useVideoConfig();
|
|
123
|
+
const [map, setMap] = useState<any>(null);
|
|
124
|
+
const [labels, setLabels] = useState<
|
|
125
|
+
Record<string, {x: number; y: number; reveal: number}>
|
|
126
|
+
>({});
|
|
127
|
+
const [plate, setPlate] = useState({x: 0, y: 0, scale: 1});
|
|
128
|
+
const [handle] = useState(() => delayRender('maptiler init A'));
|
|
129
|
+
|
|
130
|
+
useEffect(() => {
|
|
131
|
+
if (!ref.current || started.current) return;
|
|
132
|
+
started.current = true;
|
|
133
|
+
const m = new maptilersdk.Map({
|
|
134
|
+
container: ref.current,
|
|
135
|
+
style: maptilersdk.MapStyle.BASIC,
|
|
136
|
+
center: END.center,
|
|
137
|
+
zoom: Math.max(START.zoom, END.zoom),
|
|
138
|
+
pitch: END.pitch,
|
|
139
|
+
bearing: END.bearing,
|
|
140
|
+
interactive: false,
|
|
141
|
+
attributionControl: true,
|
|
142
|
+
navigationControl: false,
|
|
143
|
+
geolocateControl: false,
|
|
144
|
+
maptilerLogo: true,
|
|
145
|
+
fadeDuration: 0,
|
|
146
|
+
canvasContextAttributes: {preserveDrawingBuffer: true},
|
|
147
|
+
} as any);
|
|
148
|
+
|
|
149
|
+
m.on('load', () => {
|
|
150
|
+
// Strip basemap labels (symbols) AND the inner admin-1 borders ('Other border[ dash]',
|
|
151
|
+
// admin_level 3–10) to cut basemap clutter. Keep country + disputed borders.
|
|
152
|
+
for (const l of m.getStyle().layers as any[])
|
|
153
|
+
if (l.type === 'symbol' || /other border/i.test(l.id))
|
|
154
|
+
m.removeLayer(l.id);
|
|
155
|
+
|
|
156
|
+
m.addSource('countries', {type: 'geojson', data: countryPolygons});
|
|
157
|
+
for (const c of ORDER) {
|
|
158
|
+
m.addLayer({
|
|
159
|
+
id: `fill-${c}`,
|
|
160
|
+
type: 'fill',
|
|
161
|
+
source: 'countries',
|
|
162
|
+
filter: ['==', ['get', 'country'], c],
|
|
163
|
+
paint: {'fill-color': COUNTRY[c], 'fill-opacity': 0},
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
// Per country: just the border that draws on, settled to a darker shade of the country colour
|
|
167
|
+
// (the electricity now lives on the river, not the borders).
|
|
168
|
+
for (const c of ORDER) {
|
|
169
|
+
m.addSource(`trail-${c}`, {type: 'geojson', data: EMPTY});
|
|
170
|
+
m.addLayer({
|
|
171
|
+
id: `trail-${c}`,
|
|
172
|
+
type: 'line',
|
|
173
|
+
source: `trail-${c}`,
|
|
174
|
+
layout: {'line-cap': 'round', 'line-join': 'round'},
|
|
175
|
+
paint: {
|
|
176
|
+
'line-color': COUNTRY_DARK[c],
|
|
177
|
+
'line-width': 2,
|
|
178
|
+
'line-opacity': 0.95,
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const seed = turf.lineSliceAlong(
|
|
184
|
+
line,
|
|
185
|
+
0,
|
|
186
|
+
Math.max(0.001, lineKm * 0.001),
|
|
187
|
+
);
|
|
188
|
+
m.addSource('river', {type: 'geojson', data: seed});
|
|
189
|
+
m.addSource('river-head', {type: 'geojson', data: seed});
|
|
190
|
+
// Electric water: soft blue glow → icy core → white-hot leading head with its own glow.
|
|
191
|
+
m.addLayer({
|
|
192
|
+
id: 'river-glow',
|
|
193
|
+
type: 'line',
|
|
194
|
+
source: 'river',
|
|
195
|
+
layout: {'line-cap': 'round', 'line-join': 'round'},
|
|
196
|
+
paint: {
|
|
197
|
+
'line-color': '#49C6FF',
|
|
198
|
+
'line-width': 11,
|
|
199
|
+
'line-opacity': 0.32,
|
|
200
|
+
'line-blur': 6,
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
m.addLayer({
|
|
204
|
+
id: 'river-line',
|
|
205
|
+
type: 'line',
|
|
206
|
+
source: 'river',
|
|
207
|
+
layout: {'line-cap': 'round', 'line-join': 'round'},
|
|
208
|
+
paint: {'line-color': COLORS.river, 'line-width': 3},
|
|
209
|
+
});
|
|
210
|
+
m.addLayer({
|
|
211
|
+
id: 'river-headglow',
|
|
212
|
+
type: 'line',
|
|
213
|
+
source: 'river-head',
|
|
214
|
+
layout: {'line-cap': 'round', 'line-join': 'round'},
|
|
215
|
+
paint: {
|
|
216
|
+
'line-color': COLORS.riverHeadGlow,
|
|
217
|
+
'line-width': 16,
|
|
218
|
+
'line-opacity': 0,
|
|
219
|
+
'line-blur': 9,
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
m.addLayer({
|
|
223
|
+
id: 'river-head',
|
|
224
|
+
type: 'line',
|
|
225
|
+
source: 'river-head',
|
|
226
|
+
layout: {'line-cap': 'round', 'line-join': 'round'},
|
|
227
|
+
paint: {
|
|
228
|
+
'line-color': COLORS.riverHead,
|
|
229
|
+
'line-width': 4.5,
|
|
230
|
+
'line-opacity': 0,
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
m.once('idle', () => {
|
|
235
|
+
setMap(m);
|
|
236
|
+
continueRender(handle);
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
}, [handle]);
|
|
240
|
+
|
|
241
|
+
useEffect(() => {
|
|
242
|
+
if (!map) return;
|
|
243
|
+
const h = delayRender(`frame A ${frame}`);
|
|
244
|
+
const t = frame / fps; // seconds
|
|
245
|
+
const tt = interpolate(frame, [0, durationInFrames - 1], [0, 1], {
|
|
246
|
+
extrapolateLeft: 'clamp',
|
|
247
|
+
extrapolateRight: 'clamp',
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// River draw
|
|
251
|
+
const reveal = interpolate(t, [RIVER_START, RIVER_END], [0, 1], {
|
|
252
|
+
extrapolateLeft: 'clamp',
|
|
253
|
+
extrapolateRight: 'clamp',
|
|
254
|
+
easing: Easing.bezier(0.645, 0.045, 0.355, 1),
|
|
255
|
+
});
|
|
256
|
+
const riverDrawnKm = lineKm * reveal;
|
|
257
|
+
(map.getSource('river') as any)?.setData(
|
|
258
|
+
turf.lineSliceAlong(line, 0, Math.max(0.001, riverDrawnKm)),
|
|
259
|
+
);
|
|
260
|
+
// Electric draw-head leading the river: white-hot core + glow, fading out once the river completes.
|
|
261
|
+
const riverHeadKm = lineKm * 0.03;
|
|
262
|
+
(map.getSource('river-head') as any)?.setData(
|
|
263
|
+
turf.lineSliceAlong(
|
|
264
|
+
line,
|
|
265
|
+
Math.max(0, riverDrawnKm - riverHeadKm),
|
|
266
|
+
Math.max(0.001, riverDrawnKm),
|
|
267
|
+
),
|
|
268
|
+
);
|
|
269
|
+
let riverHeadFade = 0;
|
|
270
|
+
if (reveal > 0.002 && reveal < 0.999) riverHeadFade = 1;
|
|
271
|
+
else if (reveal >= 0.999)
|
|
272
|
+
riverHeadFade = 1 - clamp01((t - RIVER_END) / 0.5);
|
|
273
|
+
map.setPaintProperty(
|
|
274
|
+
'river-headglow',
|
|
275
|
+
'line-opacity',
|
|
276
|
+
0.85 * riverHeadFade,
|
|
277
|
+
);
|
|
278
|
+
map.setPaintProperty('river-head', 'line-opacity', riverHeadFade);
|
|
279
|
+
|
|
280
|
+
const camera = {
|
|
281
|
+
center: [
|
|
282
|
+
lerp(START.center[0], END.center[0], tt),
|
|
283
|
+
lerp(START.center[1], END.center[1], tt),
|
|
284
|
+
] as [number, number],
|
|
285
|
+
zoom: lerp(START.zoom, END.zoom, tt),
|
|
286
|
+
};
|
|
287
|
+
const cameraPoint = map.project(camera.center);
|
|
288
|
+
const plateScale = 2 ** (camera.zoom - Math.max(START.zoom, END.zoom));
|
|
289
|
+
const plateX = width / 2 - cameraPoint.x * plateScale;
|
|
290
|
+
const plateY = height / 2 - cameraPoint.y * plateScale;
|
|
291
|
+
|
|
292
|
+
const pos: Record<string, {x: number; y: number; reveal: number}> = {};
|
|
293
|
+
for (const c of ORDER) {
|
|
294
|
+
const d = DRAW[c];
|
|
295
|
+
const lt = t - trigger(c); // local seconds since this country triggered
|
|
296
|
+
|
|
297
|
+
// 1) border draws on (constant duration), settling to a darker shade — no electric head
|
|
298
|
+
const bp = interpolate(clamp01(lt / BORDER_S), [0, 1], [0, 1], {
|
|
299
|
+
easing: Easing.bezier(0.645, 0.045, 0.355, 1),
|
|
300
|
+
});
|
|
301
|
+
(map.getSource(`trail-${c}`) as any)?.setData(
|
|
302
|
+
bp <= 0 ? EMPTY : sliceBorder(d, 0, d.total * bp),
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
// 2) fill blooms in (overshoot then settle) after the border completes
|
|
306
|
+
const fp = clamp01((lt - BORDER_S) / FILL_S);
|
|
307
|
+
const fo = interpolate(
|
|
308
|
+
fp,
|
|
309
|
+
[0, 0.6, 1],
|
|
310
|
+
[0, FILL_OPACITY * 1.25, FILL_OPACITY],
|
|
311
|
+
{
|
|
312
|
+
extrapolateLeft: 'clamp',
|
|
313
|
+
extrapolateRight: 'clamp',
|
|
314
|
+
easing: Easing.bezier(0.3333333333333333, 1, 0.6666666666666666, 1),
|
|
315
|
+
},
|
|
316
|
+
);
|
|
317
|
+
map.setPaintProperty(`fill-${c}`, 'fill-opacity', fp <= 0 ? 0 : fo);
|
|
318
|
+
|
|
319
|
+
// 3) label rises in after the fill
|
|
320
|
+
const lp = clamp01((lt - BORDER_S - FILL_S) / LABEL_S);
|
|
321
|
+
const p = map.project(META[c].anchor);
|
|
322
|
+
pos[c] = {
|
|
323
|
+
x: p.x * plateScale + plateX,
|
|
324
|
+
y: p.y * plateScale + plateY,
|
|
325
|
+
reveal: lp,
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
setLabels(pos);
|
|
329
|
+
|
|
330
|
+
setPlate({x: plateX, y: plateY, scale: plateScale});
|
|
331
|
+
map.once('idle', () => continueRender(h));
|
|
332
|
+
map.triggerRepaint();
|
|
333
|
+
}, [map, frame, fps, durationInFrames, width, height]);
|
|
334
|
+
|
|
335
|
+
return (
|
|
336
|
+
<AbsoluteFill style={{backgroundColor: COLORS.bg}}>
|
|
337
|
+
<div
|
|
338
|
+
ref={ref}
|
|
339
|
+
style={{
|
|
340
|
+
width: width * 2,
|
|
341
|
+
height: height * 2,
|
|
342
|
+
position: 'absolute',
|
|
343
|
+
transform: `translate(${plate.x}px, ${plate.y}px) scale(${plate.scale})`,
|
|
344
|
+
transformOrigin: '0 0',
|
|
345
|
+
}}
|
|
346
|
+
/>
|
|
347
|
+
<AbsoluteFill style={{pointerEvents: 'none'}}>
|
|
348
|
+
{ORDER.map((c) =>
|
|
349
|
+
labels[c] ? (
|
|
350
|
+
<CountryLabel
|
|
351
|
+
key={c}
|
|
352
|
+
name={c.toUpperCase()}
|
|
353
|
+
color={COUNTRY[c]}
|
|
354
|
+
reveal={labels[c].reveal}
|
|
355
|
+
x={labels[c].x}
|
|
356
|
+
y={labels[c].y}
|
|
357
|
+
/>
|
|
358
|
+
) : null,
|
|
359
|
+
)}
|
|
360
|
+
</AbsoluteFill>
|
|
361
|
+
</AbsoluteFill>
|
|
362
|
+
);
|
|
363
|
+
};
|
package/skills/remotion-best-practices/remotion-maps/techniques/maptiler/assets/example-Root.tsx
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Minimal Remotion scaffold for the map explainer. In a Remotion project (`bunx create-video@latest`,
|
|
2
|
+
// blank template), this is `src/Root.tsx`; `src/index.ts` is just `registerRoot(RemotionRoot)`.
|
|
3
|
+
//
|
|
4
|
+
// The Composition sets DURATION (the beat) and dimensions. The component reads durationInFrames / width /
|
|
5
|
+
// height from useVideoConfig(). The beat must be long enough for the last country's full sequence after
|
|
6
|
+
// the river reaches it. See references/map-explainer-architecture.md §2.
|
|
7
|
+
// Render with: bunx remotion render src/index.ts MapExplainer out.mp4 --gl=angle --concurrency=1 --timeout=120000
|
|
8
|
+
|
|
9
|
+
import React from 'react';
|
|
10
|
+
import {Composition} from 'remotion';
|
|
11
|
+
import {RiverReveal} from './RiverReveal'; // → src/components/RiverReveal.tsx in your project
|
|
12
|
+
|
|
13
|
+
export const RemotionRoot: React.FC = () => (
|
|
14
|
+
<Composition
|
|
15
|
+
id="MapExplainer"
|
|
16
|
+
component={RiverReveal}
|
|
17
|
+
durationInFrames={12 * 30} // 12 s @ 30 fps — raise if a later country needs more room after the river arrives
|
|
18
|
+
fps={30}
|
|
19
|
+
width={1920}
|
|
20
|
+
height={1080}
|
|
21
|
+
/>
|
|
22
|
+
);
|