jfl 0.0.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/LICENSE +21 -0
- package/README.md +313 -0
- package/clawdbot-skill/README.md +328 -0
- package/clawdbot-skill/SKILL.md +362 -0
- package/clawdbot-skill/index.ts +486 -0
- package/clawdbot-skill/package.json +28 -0
- package/clawdbot-skill/skill.json +28 -0
- package/dist/commands/agents.d.ts +5 -0
- package/dist/commands/agents.d.ts.map +1 -0
- package/dist/commands/agents.js +399 -0
- package/dist/commands/agents.js.map +1 -0
- package/dist/commands/context-hub.d.ts +12 -0
- package/dist/commands/context-hub.d.ts.map +1 -0
- package/dist/commands/context-hub.js +642 -0
- package/dist/commands/context-hub.js.map +1 -0
- package/dist/commands/deploy.d.ts +5 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +370 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/feedback.d.ts +2 -0
- package/dist/commands/feedback.d.ts.map +1 -0
- package/dist/commands/feedback.js +178 -0
- package/dist/commands/feedback.js.map +1 -0
- package/dist/commands/hud.d.ts +4 -0
- package/dist/commands/hud.d.ts.map +1 -0
- package/dist/commands/hud.js +262 -0
- package/dist/commands/hud.js.map +1 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +553 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +23 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +818 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/ralph.d.ts +9 -0
- package/dist/commands/ralph.d.ts.map +1 -0
- package/dist/commands/ralph.js +67 -0
- package/dist/commands/ralph.js.map +1 -0
- package/dist/commands/repair.d.ts +7 -0
- package/dist/commands/repair.d.ts.map +1 -0
- package/dist/commands/repair.js +283 -0
- package/dist/commands/repair.js.map +1 -0
- package/dist/commands/session-mgmt.d.ts +33 -0
- package/dist/commands/session-mgmt.d.ts.map +1 -0
- package/dist/commands/session-mgmt.js +404 -0
- package/dist/commands/session-mgmt.js.map +1 -0
- package/dist/commands/session.d.ts +2 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +639 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/skills.d.ts +31 -0
- package/dist/commands/skills.d.ts.map +1 -0
- package/dist/commands/skills.js +314 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +127 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/synopsis.d.ts +10 -0
- package/dist/commands/synopsis.d.ts.map +1 -0
- package/dist/commands/synopsis.js +277 -0
- package/dist/commands/synopsis.js.map +1 -0
- package/dist/commands/update.d.ts +10 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +165 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/voice.d.ts +410 -0
- package/dist/commands/voice.d.ts.map +1 -0
- package/dist/commands/voice.js +4763 -0
- package/dist/commands/voice.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +512 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/context-hub-mcp.d.ts +11 -0
- package/dist/mcp/context-hub-mcp.d.ts.map +1 -0
- package/dist/mcp/context-hub-mcp.js +548 -0
- package/dist/mcp/context-hub-mcp.js.map +1 -0
- package/dist/telegram/voice.d.ts +146 -0
- package/dist/telegram/voice.d.ts.map +1 -0
- package/dist/telegram/voice.js +351 -0
- package/dist/telegram/voice.js.map +1 -0
- package/dist/types/skills.d.ts +44 -0
- package/dist/types/skills.d.ts.map +1 -0
- package/dist/types/skills.js +5 -0
- package/dist/types/skills.js.map +1 -0
- package/dist/ui/banner.d.ts +18 -0
- package/dist/ui/banner.d.ts.map +1 -0
- package/dist/ui/banner.js +323 -0
- package/dist/ui/banner.js.map +1 -0
- package/dist/ui/index.d.ts +8 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +8 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/prompts.d.ts +52 -0
- package/dist/ui/prompts.d.ts.map +1 -0
- package/dist/ui/prompts.js +72 -0
- package/dist/ui/prompts.js.map +1 -0
- package/dist/ui/theme.d.ts +82 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +142 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/utils/auth-guard.d.ts +66 -0
- package/dist/utils/auth-guard.d.ts.map +1 -0
- package/dist/utils/auth-guard.js +348 -0
- package/dist/utils/auth-guard.js.map +1 -0
- package/dist/utils/ensure-project.d.ts +11 -0
- package/dist/utils/ensure-project.d.ts.map +1 -0
- package/dist/utils/ensure-project.js +70 -0
- package/dist/utils/ensure-project.js.map +1 -0
- package/dist/utils/git.d.ts +73 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +219 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/github-auth.d.ts +54 -0
- package/dist/utils/github-auth.d.ts.map +1 -0
- package/dist/utils/github-auth.js +375 -0
- package/dist/utils/github-auth.js.map +1 -0
- package/dist/utils/github-repo.d.ts +30 -0
- package/dist/utils/github-repo.d.ts.map +1 -0
- package/dist/utils/github-repo.js +219 -0
- package/dist/utils/github-repo.js.map +1 -0
- package/dist/utils/platform-auth.d.ts +81 -0
- package/dist/utils/platform-auth.d.ts.map +1 -0
- package/dist/utils/platform-auth.js +191 -0
- package/dist/utils/platform-auth.js.map +1 -0
- package/dist/utils/project-config.d.ts +43 -0
- package/dist/utils/project-config.d.ts.map +1 -0
- package/dist/utils/project-config.js +97 -0
- package/dist/utils/project-config.js.map +1 -0
- package/dist/utils/skill-registry.d.ts +49 -0
- package/dist/utils/skill-registry.d.ts.map +1 -0
- package/dist/utils/skill-registry.js +192 -0
- package/dist/utils/skill-registry.js.map +1 -0
- package/dist/utils/wallet.d.ts +62 -0
- package/dist/utils/wallet.d.ts.map +1 -0
- package/dist/utils/wallet.js +252 -0
- package/dist/utils/wallet.js.map +1 -0
- package/dist/utils/x402-client.d.ts +86 -0
- package/dist/utils/x402-client.d.ts.map +1 -0
- package/dist/utils/x402-client.js +265 -0
- package/dist/utils/x402-client.js.map +1 -0
- package/package.json +76 -0
- package/scripts/postinstall.js +116 -0
- package/scripts/test-onboarding.sh +121 -0
- package/scripts/voice-start.sh +128 -0
- package/scripts/voice-stop.sh +33 -0
- package/template/.claude/settings.json +92 -0
- package/template/.claude/skills/agent-browser/SKILL.md +116 -0
- package/template/.claude/skills/brand-architect/SKILL.md +240 -0
- package/template/.claude/skills/brand-architect/config.yaml +137 -0
- package/template/.claude/skills/campaign-hud/config.yaml +112 -0
- package/template/.claude/skills/content-creator/SKILL.md +294 -0
- package/template/.claude/skills/debug/MULTI_AGENT.md +360 -0
- package/template/.claude/skills/debug/SKILL.md +549 -0
- package/template/.claude/skills/fly-deploy/SKILL.md +676 -0
- package/template/.claude/skills/founder-video/SKILL.md +467 -0
- package/template/.claude/skills/hud/SKILL.md +157 -0
- package/template/.claude/skills/ralph-tui/SKILL.md +210 -0
- package/template/.claude/skills/react-best-practices/AGENTS.md +2249 -0
- package/template/.claude/skills/react-best-practices/README.md +123 -0
- package/template/.claude/skills/react-best-practices/SKILL.md +125 -0
- package/template/.claude/skills/react-best-practices/metadata.json +15 -0
- package/template/.claude/skills/react-best-practices/rules/_sections.md +46 -0
- package/template/.claude/skills/react-best-practices/rules/_template.md +28 -0
- package/template/.claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/template/.claude/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
- package/template/.claude/skills/react-best-practices/rules/async-api-routes.md +38 -0
- package/template/.claude/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/template/.claude/skills/react-best-practices/rules/async-dependencies.md +36 -0
- package/template/.claude/skills/react-best-practices/rules/async-parallel.md +28 -0
- package/template/.claude/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/template/.claude/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/template/.claude/skills/react-best-practices/rules/bundle-conditional.md +31 -0
- package/template/.claude/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/template/.claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/template/.claude/skills/react-best-practices/rules/bundle-preload.md +50 -0
- package/template/.claude/skills/react-best-practices/rules/client-event-listeners.md +74 -0
- package/template/.claude/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/template/.claude/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
- package/template/.claude/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/template/.claude/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/template/.claude/skills/react-best-practices/rules/js-cache-storage.md +70 -0
- package/template/.claude/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/template/.claude/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/template/.claude/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/template/.claude/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/template/.claude/skills/react-best-practices/rules/js-length-check-first.md +49 -0
- package/template/.claude/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/template/.claude/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/template/.claude/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/template/.claude/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/template/.claude/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/template/.claude/skills/react-best-practices/rules/server-cache-react.md +26 -0
- package/template/.claude/skills/react-best-practices/rules/server-parallel-fetching.md +79 -0
- package/template/.claude/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/template/.claude/skills/remotion-best-practices/SKILL.md +43 -0
- package/template/.claude/skills/remotion-best-practices/rules/3d.md +86 -0
- package/template/.claude/skills/remotion-best-practices/rules/animations.md +29 -0
- package/template/.claude/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
- package/template/.claude/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
- package/template/.claude/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
- package/template/.claude/skills/remotion-best-practices/rules/assets.md +78 -0
- package/template/.claude/skills/remotion-best-practices/rules/audio.md +172 -0
- package/template/.claude/skills/remotion-best-practices/rules/calculate-metadata.md +104 -0
- package/template/.claude/skills/remotion-best-practices/rules/can-decode.md +75 -0
- package/template/.claude/skills/remotion-best-practices/rules/charts.md +58 -0
- package/template/.claude/skills/remotion-best-practices/rules/compositions.md +146 -0
- package/template/.claude/skills/remotion-best-practices/rules/display-captions.md +126 -0
- package/template/.claude/skills/remotion-best-practices/rules/extract-frames.md +229 -0
- package/template/.claude/skills/remotion-best-practices/rules/fonts.md +152 -0
- package/template/.claude/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
- package/template/.claude/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
- package/template/.claude/skills/remotion-best-practices/rules/get-video-duration.md +58 -0
- package/template/.claude/skills/remotion-best-practices/rules/gifs.md +138 -0
- package/template/.claude/skills/remotion-best-practices/rules/images.md +130 -0
- package/template/.claude/skills/remotion-best-practices/rules/import-srt-captions.md +67 -0
- package/template/.claude/skills/remotion-best-practices/rules/lottie.md +68 -0
- package/template/.claude/skills/remotion-best-practices/rules/measuring-dom-nodes.md +35 -0
- package/template/.claude/skills/remotion-best-practices/rules/measuring-text.md +143 -0
- package/template/.claude/skills/remotion-best-practices/rules/sequencing.md +106 -0
- package/template/.claude/skills/remotion-best-practices/rules/tailwind.md +11 -0
- package/template/.claude/skills/remotion-best-practices/rules/text-animations.md +20 -0
- package/template/.claude/skills/remotion-best-practices/rules/timing.md +179 -0
- package/template/.claude/skills/remotion-best-practices/rules/transcribe-captions.md +19 -0
- package/template/.claude/skills/remotion-best-practices/rules/transitions.md +122 -0
- package/template/.claude/skills/remotion-best-practices/rules/trimming.md +53 -0
- package/template/.claude/skills/remotion-best-practices/rules/videos.md +171 -0
- package/template/.claude/skills/search/SKILL.md +220 -0
- package/template/.claude/skills/spec/SKILL.md +377 -0
- package/template/.claude/skills/startup/SKILL.md +310 -0
- package/template/.claude/skills/web-architect/SKILL.md +309 -0
- package/template/.claude/skills/x-algorithm/SKILL.md +305 -0
- package/template/.jfl/config.json +8 -0
- package/template/.mcp.json +11 -0
- package/template/CLAUDE.md +960 -0
- package/template/content/.gitkeep +0 -0
- package/template/context-hub +3 -0
- package/template/knowledge/BRAND_BRIEF.md +124 -0
- package/template/knowledge/BRAND_DECISIONS.md +168 -0
- package/template/knowledge/NARRATIVE.md +114 -0
- package/template/knowledge/ROADMAP.md +128 -0
- package/template/knowledge/THESIS.md +108 -0
- package/template/knowledge/VISION.md +74 -0
- package/template/knowledge/VOICE_AND_TONE.md +146 -0
- package/template/previews/.gitkeep +0 -0
- package/template/scripts/session/auto-commit.sh +245 -0
- package/template/scripts/session/auto-merge.sh +325 -0
- package/template/scripts/session/jfl-doctor.sh +587 -0
- package/template/scripts/session/session-end.sh +194 -0
- package/template/scripts/session/session-init.sh +163 -0
- package/template/scripts/session/session-sync.sh +167 -0
- package/template/scripts/session/test-context-preservation.sh +160 -0
- package/template/skills/agent-browser/SKILL.md +116 -0
- package/template/skills/brand-architect/SKILL.md +240 -0
- package/template/skills/brand-architect/config.yaml +137 -0
- package/template/skills/campaign-hud/config.yaml +112 -0
- package/template/skills/content-creator/SKILL.md +294 -0
- package/template/skills/debug/MULTI_AGENT.md +360 -0
- package/template/skills/debug/SKILL.md +549 -0
- package/template/skills/fly-deploy/SKILL.md +676 -0
- package/template/skills/founder-video/SKILL.md +467 -0
- package/template/skills/hud/SKILL.md +204 -0
- package/template/skills/ralph-tui/SKILL.md +210 -0
- package/template/skills/react-best-practices/AGENTS.md +2249 -0
- package/template/skills/react-best-practices/README.md +123 -0
- package/template/skills/react-best-practices/SKILL.md +125 -0
- package/template/skills/react-best-practices/metadata.json +15 -0
- package/template/skills/react-best-practices/rules/_sections.md +46 -0
- package/template/skills/react-best-practices/rules/_template.md +28 -0
- package/template/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/template/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
- package/template/skills/react-best-practices/rules/async-api-routes.md +38 -0
- package/template/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/template/skills/react-best-practices/rules/async-dependencies.md +36 -0
- package/template/skills/react-best-practices/rules/async-parallel.md +28 -0
- package/template/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/template/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/template/skills/react-best-practices/rules/bundle-conditional.md +31 -0
- package/template/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/template/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/template/skills/react-best-practices/rules/bundle-preload.md +50 -0
- package/template/skills/react-best-practices/rules/client-event-listeners.md +74 -0
- package/template/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/template/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
- package/template/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/template/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/template/skills/react-best-practices/rules/js-cache-storage.md +70 -0
- package/template/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/template/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/template/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/template/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/template/skills/react-best-practices/rules/js-length-check-first.md +49 -0
- package/template/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/template/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/template/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/template/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/template/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/template/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/template/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/template/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/template/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/template/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/template/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/template/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/template/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/template/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/template/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/template/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/template/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/template/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/template/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/template/skills/react-best-practices/rules/server-cache-react.md +26 -0
- package/template/skills/react-best-practices/rules/server-parallel-fetching.md +79 -0
- package/template/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/template/skills/remotion-best-practices/SKILL.md +43 -0
- package/template/skills/remotion-best-practices/rules/3d.md +86 -0
- package/template/skills/remotion-best-practices/rules/animations.md +29 -0
- package/template/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
- package/template/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
- package/template/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
- package/template/skills/remotion-best-practices/rules/assets.md +78 -0
- package/template/skills/remotion-best-practices/rules/audio.md +172 -0
- package/template/skills/remotion-best-practices/rules/calculate-metadata.md +104 -0
- package/template/skills/remotion-best-practices/rules/can-decode.md +75 -0
- package/template/skills/remotion-best-practices/rules/charts.md +58 -0
- package/template/skills/remotion-best-practices/rules/compositions.md +146 -0
- package/template/skills/remotion-best-practices/rules/display-captions.md +126 -0
- package/template/skills/remotion-best-practices/rules/extract-frames.md +229 -0
- package/template/skills/remotion-best-practices/rules/fonts.md +152 -0
- package/template/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
- package/template/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
- package/template/skills/remotion-best-practices/rules/get-video-duration.md +58 -0
- package/template/skills/remotion-best-practices/rules/gifs.md +138 -0
- package/template/skills/remotion-best-practices/rules/images.md +130 -0
- package/template/skills/remotion-best-practices/rules/import-srt-captions.md +67 -0
- package/template/skills/remotion-best-practices/rules/lottie.md +68 -0
- package/template/skills/remotion-best-practices/rules/measuring-dom-nodes.md +35 -0
- package/template/skills/remotion-best-practices/rules/measuring-text.md +143 -0
- package/template/skills/remotion-best-practices/rules/sequencing.md +106 -0
- package/template/skills/remotion-best-practices/rules/tailwind.md +11 -0
- package/template/skills/remotion-best-practices/rules/text-animations.md +20 -0
- package/template/skills/remotion-best-practices/rules/timing.md +179 -0
- package/template/skills/remotion-best-practices/rules/transcribe-captions.md +19 -0
- package/template/skills/remotion-best-practices/rules/transitions.md +122 -0
- package/template/skills/remotion-best-practices/rules/trimming.md +53 -0
- package/template/skills/remotion-best-practices/rules/videos.md +171 -0
- package/template/skills/search/SKILL.md +220 -0
- package/template/skills/spec/SKILL.md +377 -0
- package/template/skills/startup/SKILL.md +310 -0
- package/template/skills/web-architect/SKILL.md +309 -0
- package/template/skills/x-algorithm/SKILL.md +305 -0
- package/template/suggestions/.gitkeep +0 -0
- package/template/templates/QUICKSTART_SKILL_TO_PRODUCT.md +242 -0
- package/template/templates/brand/BRAND_BRIEF.md +124 -0
- package/template/templates/brand/BRAND_DECISIONS.md +168 -0
- package/template/templates/brand/BRAND_GUIDELINES.md +251 -0
- package/template/templates/brand/VOICE_AND_TONE.md +146 -0
- package/template/templates/brand/global.css +240 -0
- package/template/templates/collaboration/CONTRIBUTOR.md +74 -0
- package/template/templates/collaboration/CRM.md +97 -0
- package/template/templates/collaboration/TASKS.md +83 -0
- package/template/templates/strategic/NARRATIVE.md +114 -0
- package/template/templates/strategic/ROADMAP.md +128 -0
- package/template/templates/strategic/THESIS.md +108 -0
- package/template/templates/strategic/VISION.md +74 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Minimize Serialization at RSC Boundaries
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: reduces data transfer size
|
|
5
|
+
tags: server, rsc, serialization, props
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Minimize Serialization at RSC Boundaries
|
|
9
|
+
|
|
10
|
+
The React Server/Client boundary serializes all object properties into strings and embeds them in the HTML response and subsequent RSC requests. This serialized data directly impacts page weight and load time, so **size matters a lot**. Only pass fields that the client actually uses.
|
|
11
|
+
|
|
12
|
+
**Incorrect (serializes all 50 fields):**
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
async function Page() {
|
|
16
|
+
const user = await fetchUser() // 50 fields
|
|
17
|
+
return <Profile user={user} />
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
'use client'
|
|
21
|
+
function Profile({ user }: { user: User }) {
|
|
22
|
+
return <div>{user.name}</div> // uses 1 field
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Correct (serializes only 1 field):**
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
async function Page() {
|
|
30
|
+
const user = await fetchUser()
|
|
31
|
+
return <Profile name={user.name} />
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
'use client'
|
|
35
|
+
function Profile({ name }: { name: string }) {
|
|
36
|
+
return <div>{name}</div>
|
|
37
|
+
}
|
|
38
|
+
```
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: remotion-best-practices
|
|
3
|
+
description: Best practices for Remotion - Video creation in React
|
|
4
|
+
metadata:
|
|
5
|
+
tags: remotion, video, react, animation, composition
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## When to use
|
|
9
|
+
|
|
10
|
+
Use this skills whenever you are dealing with Remotion code to obtain the domain-specific knowledge.
|
|
11
|
+
|
|
12
|
+
## How to use
|
|
13
|
+
|
|
14
|
+
Read individual rule files for detailed explanations and code examples:
|
|
15
|
+
|
|
16
|
+
- [rules/3d.md](rules/3d.md) - 3D content in Remotion using Three.js and React Three Fiber
|
|
17
|
+
- [rules/animations.md](rules/animations.md) - Fundamental animation skills for Remotion
|
|
18
|
+
- [rules/assets.md](rules/assets.md) - Importing images, videos, audio, and fonts into Remotion
|
|
19
|
+
- [rules/audio.md](rules/audio.md) - Using audio and sound in Remotion - importing, trimming, volume, speed, pitch
|
|
20
|
+
- [rules/calculate-metadata.md](rules/calculate-metadata.md) - Dynamically set composition duration, dimensions, and props
|
|
21
|
+
- [rules/can-decode.md](rules/can-decode.md) - Check if a video can be decoded by the browser using Mediabunny
|
|
22
|
+
- [rules/charts.md](rules/charts.md) - Chart and data visualization patterns for Remotion
|
|
23
|
+
- [rules/compositions.md](rules/compositions.md) - Defining compositions, stills, folders, default props and dynamic metadata
|
|
24
|
+
- [rules/display-captions.md](rules/display-captions.md) - Displaying captions in Remotion with TikTok-style pages and word highlighting
|
|
25
|
+
- [rules/extract-frames.md](rules/extract-frames.md) - Extract frames from videos at specific timestamps using Mediabunny
|
|
26
|
+
- [rules/fonts.md](rules/fonts.md) - Loading Google Fonts and local fonts in Remotion
|
|
27
|
+
- [rules/get-audio-duration.md](rules/get-audio-duration.md) - Getting the duration of an audio file in seconds with Mediabunny
|
|
28
|
+
- [rules/get-video-dimensions.md](rules/get-video-dimensions.md) - Getting the width and height of a video file with Mediabunny
|
|
29
|
+
- [rules/get-video-duration.md](rules/get-video-duration.md) - Getting the duration of a video file in seconds with Mediabunny
|
|
30
|
+
- [rules/gifs.md](rules/gifs.md) - Displaying GIFs synchronized with Remotion's timeline
|
|
31
|
+
- [rules/images.md](rules/images.md) - Embedding images in Remotion using the Img component
|
|
32
|
+
- [rules/import-srt-captions.md](rules/import-srt-captions.md) - Importing .srt subtitle files into Remotion using @remotion/captions
|
|
33
|
+
- [rules/lottie.md](rules/lottie.md) - Embedding Lottie animations in Remotion
|
|
34
|
+
- [rules/measuring-dom-nodes.md](rules/measuring-dom-nodes.md) - Measuring DOM element dimensions in Remotion
|
|
35
|
+
- [rules/measuring-text.md](rules/measuring-text.md) - Measuring text dimensions, fitting text to containers, and checking overflow
|
|
36
|
+
- [rules/sequencing.md](rules/sequencing.md) - Sequencing patterns for Remotion - delay, trim, limit duration of items
|
|
37
|
+
- [rules/tailwind.md](rules/tailwind.md) - Using TailwindCSS in Remotion
|
|
38
|
+
- [rules/text-animations.md](rules/text-animations.md) - Typography and text animation patterns for Remotion
|
|
39
|
+
- [rules/timing.md](rules/timing.md) - Interpolation curves in Remotion - linear, easing, spring animations
|
|
40
|
+
- [rules/transcribe-captions.md](rules/transcribe-captions.md) - Transcribing audio to generate captions in Remotion
|
|
41
|
+
- [rules/transitions.md](rules/transitions.md) - Scene transition patterns for Remotion
|
|
42
|
+
- [rules/trimming.md](rules/trimming.md) - Trimming patterns for Remotion - cut the beginning or end of animations
|
|
43
|
+
- [rules/videos.md](rules/videos.md) - Embedding videos in Remotion - trimming, volume, speed, looping, pitch
|
|
@@ -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
|
+
```
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: animations
|
|
3
|
+
description: Fundamental animation skills for Remotion
|
|
4
|
+
metadata:
|
|
5
|
+
tags: animations, transitions, frames, useCurrentFrame
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
All animations MUST be driven by the `useCurrentFrame()` hook.
|
|
9
|
+
Write animations in seconds and multiply them by the `fps` value from `useVideoConfig()`.
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { useCurrentFrame } from "remotion";
|
|
13
|
+
|
|
14
|
+
export const FadeIn = () => {
|
|
15
|
+
const frame = useCurrentFrame();
|
|
16
|
+
const { fps } = useVideoConfig();
|
|
17
|
+
|
|
18
|
+
const opacity = interpolate(frame, [0, 2 * fps], [0, 1], {
|
|
19
|
+
extrapolateRight: 'clamp',
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<div style={{ opacity }}>Hello World!</div>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
CSS transitions or animations are FORBIDDEN - they will not render correctly.
|
|
29
|
+
Tailwind animation class names are FORBIDDEN - they will not render correctly.
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import {loadFont} from '@remotion/google-fonts/Inter';
|
|
2
|
+
import {AbsoluteFill, spring, useCurrentFrame, useVideoConfig} from 'remotion';
|
|
3
|
+
|
|
4
|
+
const {fontFamily} = loadFont();
|
|
5
|
+
|
|
6
|
+
const COLOR_BAR = '#D4AF37';
|
|
7
|
+
const COLOR_TEXT = '#ffffff';
|
|
8
|
+
const COLOR_MUTED = '#888888';
|
|
9
|
+
const COLOR_BG = '#0a0a0a';
|
|
10
|
+
const COLOR_AXIS = '#333333';
|
|
11
|
+
|
|
12
|
+
// Ideal composition size: 1280x720
|
|
13
|
+
|
|
14
|
+
const Title: React.FC<{children: React.ReactNode}> = ({children}) => (
|
|
15
|
+
<div style={{textAlign: 'center', marginBottom: 40}}>
|
|
16
|
+
<div style={{color: COLOR_TEXT, fontSize: 48, fontWeight: 600}}>
|
|
17
|
+
{children}
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
const YAxis: React.FC<{steps: number[]; height: number}> = ({
|
|
23
|
+
steps,
|
|
24
|
+
height,
|
|
25
|
+
}) => (
|
|
26
|
+
<div
|
|
27
|
+
style={{
|
|
28
|
+
display: 'flex',
|
|
29
|
+
flexDirection: 'column',
|
|
30
|
+
justifyContent: 'space-between',
|
|
31
|
+
height,
|
|
32
|
+
paddingRight: 16,
|
|
33
|
+
}}
|
|
34
|
+
>
|
|
35
|
+
{steps
|
|
36
|
+
.slice()
|
|
37
|
+
.reverse()
|
|
38
|
+
.map((step) => (
|
|
39
|
+
<div
|
|
40
|
+
key={step}
|
|
41
|
+
style={{
|
|
42
|
+
color: COLOR_MUTED,
|
|
43
|
+
fontSize: 20,
|
|
44
|
+
textAlign: 'right',
|
|
45
|
+
}}
|
|
46
|
+
>
|
|
47
|
+
{step.toLocaleString()}
|
|
48
|
+
</div>
|
|
49
|
+
))}
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const Bar: React.FC<{
|
|
54
|
+
height: number;
|
|
55
|
+
progress: number;
|
|
56
|
+
}> = ({height, progress}) => (
|
|
57
|
+
<div
|
|
58
|
+
style={{
|
|
59
|
+
flex: 1,
|
|
60
|
+
display: 'flex',
|
|
61
|
+
flexDirection: 'column',
|
|
62
|
+
justifyContent: 'flex-end',
|
|
63
|
+
}}
|
|
64
|
+
>
|
|
65
|
+
<div
|
|
66
|
+
style={{
|
|
67
|
+
width: '100%',
|
|
68
|
+
height,
|
|
69
|
+
backgroundColor: COLOR_BAR,
|
|
70
|
+
borderRadius: '8px 8px 0 0',
|
|
71
|
+
opacity: progress,
|
|
72
|
+
}}
|
|
73
|
+
/>
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
const XAxis: React.FC<{
|
|
78
|
+
children: React.ReactNode;
|
|
79
|
+
labels: string[];
|
|
80
|
+
height: number;
|
|
81
|
+
}> = ({children, labels, height}) => (
|
|
82
|
+
<div style={{flex: 1, display: 'flex', flexDirection: 'column'}}>
|
|
83
|
+
<div
|
|
84
|
+
style={{
|
|
85
|
+
display: 'flex',
|
|
86
|
+
alignItems: 'flex-end',
|
|
87
|
+
gap: 16,
|
|
88
|
+
height,
|
|
89
|
+
borderLeft: `2px solid ${COLOR_AXIS}`,
|
|
90
|
+
borderBottom: `2px solid ${COLOR_AXIS}`,
|
|
91
|
+
paddingLeft: 16,
|
|
92
|
+
}}
|
|
93
|
+
>
|
|
94
|
+
{children}
|
|
95
|
+
</div>
|
|
96
|
+
<div
|
|
97
|
+
style={{
|
|
98
|
+
display: 'flex',
|
|
99
|
+
gap: 16,
|
|
100
|
+
paddingLeft: 16,
|
|
101
|
+
marginTop: 12,
|
|
102
|
+
}}
|
|
103
|
+
>
|
|
104
|
+
{labels.map((label) => (
|
|
105
|
+
<div
|
|
106
|
+
key={label}
|
|
107
|
+
style={{
|
|
108
|
+
flex: 1,
|
|
109
|
+
textAlign: 'center',
|
|
110
|
+
color: COLOR_MUTED,
|
|
111
|
+
fontSize: 20,
|
|
112
|
+
}}
|
|
113
|
+
>
|
|
114
|
+
{label}
|
|
115
|
+
</div>
|
|
116
|
+
))}
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
export const MyAnimation = () => {
|
|
122
|
+
const frame = useCurrentFrame();
|
|
123
|
+
const {fps, height} = useVideoConfig();
|
|
124
|
+
|
|
125
|
+
const data = [
|
|
126
|
+
{month: 'Jan', price: 2039},
|
|
127
|
+
{month: 'Mar', price: 2160},
|
|
128
|
+
{month: 'May', price: 2327},
|
|
129
|
+
{month: 'Jul', price: 2426},
|
|
130
|
+
{month: 'Sep', price: 2634},
|
|
131
|
+
{month: 'Nov', price: 2672},
|
|
132
|
+
];
|
|
133
|
+
|
|
134
|
+
const minPrice = 2000;
|
|
135
|
+
const maxPrice = 2800;
|
|
136
|
+
const priceRange = maxPrice - minPrice;
|
|
137
|
+
const chartHeight = height - 280;
|
|
138
|
+
const yAxisSteps = [2000, 2400, 2800];
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<AbsoluteFill
|
|
142
|
+
style={{
|
|
143
|
+
backgroundColor: COLOR_BG,
|
|
144
|
+
padding: 60,
|
|
145
|
+
display: 'flex',
|
|
146
|
+
flexDirection: 'column',
|
|
147
|
+
fontFamily,
|
|
148
|
+
}}
|
|
149
|
+
>
|
|
150
|
+
<Title>Gold Price 2024</Title>
|
|
151
|
+
|
|
152
|
+
<div style={{display: 'flex', flex: 1}}>
|
|
153
|
+
<YAxis steps={yAxisSteps} height={chartHeight} />
|
|
154
|
+
<XAxis height={chartHeight} labels={data.map((d) => d.month)}>
|
|
155
|
+
{data.map((item, i) => {
|
|
156
|
+
const progress = spring({
|
|
157
|
+
frame: frame - i * 5 - 10,
|
|
158
|
+
fps,
|
|
159
|
+
config: {damping: 18, stiffness: 80},
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const barHeight =
|
|
163
|
+
((item.price - minPrice) / priceRange) * chartHeight * progress;
|
|
164
|
+
|
|
165
|
+
return (
|
|
166
|
+
<Bar key={item.month} height={barHeight} progress={progress} />
|
|
167
|
+
);
|
|
168
|
+
})}
|
|
169
|
+
</XAxis>
|
|
170
|
+
</div>
|
|
171
|
+
</AbsoluteFill>
|
|
172
|
+
);
|
|
173
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AbsoluteFill,
|
|
3
|
+
interpolate,
|
|
4
|
+
useCurrentFrame,
|
|
5
|
+
useVideoConfig,
|
|
6
|
+
} from 'remotion';
|
|
7
|
+
|
|
8
|
+
const COLOR_BG = '#ffffff';
|
|
9
|
+
const COLOR_TEXT = '#000000';
|
|
10
|
+
const FULL_TEXT = 'From prompt to motion graphics. This is Remotion.';
|
|
11
|
+
const PAUSE_AFTER = 'From prompt to motion graphics.';
|
|
12
|
+
const FONT_SIZE = 72;
|
|
13
|
+
const FONT_WEIGHT = 700;
|
|
14
|
+
const CHAR_FRAMES = 2;
|
|
15
|
+
const CURSOR_BLINK_FRAMES = 16;
|
|
16
|
+
const PAUSE_SECONDS = 1;
|
|
17
|
+
|
|
18
|
+
// Ideal composition size: 1280x720
|
|
19
|
+
|
|
20
|
+
const getTypedText = ({
|
|
21
|
+
frame,
|
|
22
|
+
fullText,
|
|
23
|
+
pauseAfter,
|
|
24
|
+
charFrames,
|
|
25
|
+
pauseFrames,
|
|
26
|
+
}: {
|
|
27
|
+
frame: number;
|
|
28
|
+
fullText: string;
|
|
29
|
+
pauseAfter: string;
|
|
30
|
+
charFrames: number;
|
|
31
|
+
pauseFrames: number;
|
|
32
|
+
}): string => {
|
|
33
|
+
const pauseIndex = fullText.indexOf(pauseAfter);
|
|
34
|
+
const preLen =
|
|
35
|
+
pauseIndex >= 0 ? pauseIndex + pauseAfter.length : fullText.length;
|
|
36
|
+
|
|
37
|
+
let typedChars = 0;
|
|
38
|
+
if (frame < preLen * charFrames) {
|
|
39
|
+
typedChars = Math.floor(frame / charFrames);
|
|
40
|
+
} else if (frame < preLen * charFrames + pauseFrames) {
|
|
41
|
+
typedChars = preLen;
|
|
42
|
+
} else {
|
|
43
|
+
const postPhase = frame - preLen * charFrames - pauseFrames;
|
|
44
|
+
typedChars = Math.min(
|
|
45
|
+
fullText.length,
|
|
46
|
+
preLen + Math.floor(postPhase / charFrames),
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return fullText.slice(0, typedChars);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const Cursor: React.FC<{
|
|
53
|
+
frame: number;
|
|
54
|
+
blinkFrames: number;
|
|
55
|
+
symbol?: string;
|
|
56
|
+
}> = ({frame, blinkFrames, symbol = '\u258C'}) => {
|
|
57
|
+
const opacity = interpolate(
|
|
58
|
+
frame % blinkFrames,
|
|
59
|
+
[0, blinkFrames / 2, blinkFrames],
|
|
60
|
+
[1, 0, 1],
|
|
61
|
+
{extrapolateLeft: 'clamp', extrapolateRight: 'clamp'},
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
return <span style={{opacity}}>{symbol}</span>;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const MyAnimation = () => {
|
|
68
|
+
const frame = useCurrentFrame();
|
|
69
|
+
const {fps} = useVideoConfig();
|
|
70
|
+
|
|
71
|
+
const pauseFrames = Math.round(fps * PAUSE_SECONDS);
|
|
72
|
+
|
|
73
|
+
const typedText = getTypedText({
|
|
74
|
+
frame,
|
|
75
|
+
fullText: FULL_TEXT,
|
|
76
|
+
pauseAfter: PAUSE_AFTER,
|
|
77
|
+
charFrames: CHAR_FRAMES,
|
|
78
|
+
pauseFrames,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<AbsoluteFill
|
|
83
|
+
style={{
|
|
84
|
+
backgroundColor: COLOR_BG,
|
|
85
|
+
}}
|
|
86
|
+
>
|
|
87
|
+
<div
|
|
88
|
+
style={{
|
|
89
|
+
color: COLOR_TEXT,
|
|
90
|
+
fontSize: FONT_SIZE,
|
|
91
|
+
fontWeight: FONT_WEIGHT,
|
|
92
|
+
fontFamily: 'sans-serif',
|
|
93
|
+
}}
|
|
94
|
+
>
|
|
95
|
+
<span>{typedText}</span>
|
|
96
|
+
<Cursor frame={frame} blinkFrames={CURSOR_BLINK_FRAMES} />
|
|
97
|
+
</div>
|
|
98
|
+
</AbsoluteFill>
|
|
99
|
+
);
|
|
100
|
+
};
|
package/template/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import {loadFont} from '@remotion/google-fonts/Inter';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import {
|
|
4
|
+
AbsoluteFill,
|
|
5
|
+
spring,
|
|
6
|
+
useCurrentFrame,
|
|
7
|
+
useVideoConfig,
|
|
8
|
+
} from 'remotion';
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* Highlight a word in a sentence with a spring-animated wipe effect.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// Ideal composition size: 1280x720
|
|
15
|
+
|
|
16
|
+
const COLOR_BG = '#ffffff';
|
|
17
|
+
const COLOR_TEXT = '#000000';
|
|
18
|
+
const COLOR_HIGHLIGHT = '#A7C7E7';
|
|
19
|
+
const FULL_TEXT = 'This is Remotion.';
|
|
20
|
+
const HIGHLIGHT_WORD = 'Remotion';
|
|
21
|
+
const FONT_SIZE = 72;
|
|
22
|
+
const FONT_WEIGHT = 700;
|
|
23
|
+
const HIGHLIGHT_START_FRAME = 30;
|
|
24
|
+
const HIGHLIGHT_WIPE_DURATION = 18;
|
|
25
|
+
|
|
26
|
+
const {fontFamily} = loadFont();
|
|
27
|
+
|
|
28
|
+
const Highlight: React.FC<{
|
|
29
|
+
word: string;
|
|
30
|
+
color: string;
|
|
31
|
+
delay: number;
|
|
32
|
+
durationInFrames: number;
|
|
33
|
+
}> = ({word, color, delay, durationInFrames}) => {
|
|
34
|
+
const frame = useCurrentFrame();
|
|
35
|
+
const {fps} = useVideoConfig();
|
|
36
|
+
|
|
37
|
+
const highlightProgress = spring({
|
|
38
|
+
fps,
|
|
39
|
+
frame,
|
|
40
|
+
config: {damping: 200},
|
|
41
|
+
delay,
|
|
42
|
+
durationInFrames,
|
|
43
|
+
});
|
|
44
|
+
const scaleX = Math.max(0, Math.min(1, highlightProgress));
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<span style={{position: 'relative', display: 'inline-block'}}>
|
|
48
|
+
<span
|
|
49
|
+
style={{
|
|
50
|
+
position: 'absolute',
|
|
51
|
+
left: 0,
|
|
52
|
+
right: 0,
|
|
53
|
+
top: '50%',
|
|
54
|
+
height: '1.05em',
|
|
55
|
+
transform: `translateY(-50%) scaleX(${scaleX})`,
|
|
56
|
+
transformOrigin: 'left center',
|
|
57
|
+
backgroundColor: color,
|
|
58
|
+
borderRadius: '0.18em',
|
|
59
|
+
zIndex: 0,
|
|
60
|
+
}}
|
|
61
|
+
/>
|
|
62
|
+
<span style={{position: 'relative', zIndex: 1}}>{word}</span>
|
|
63
|
+
</span>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const MyAnimation = () => {
|
|
68
|
+
const highlightIndex = FULL_TEXT.indexOf(HIGHLIGHT_WORD);
|
|
69
|
+
const hasHighlight = highlightIndex >= 0;
|
|
70
|
+
const preText = hasHighlight ? FULL_TEXT.slice(0, highlightIndex) : FULL_TEXT;
|
|
71
|
+
const postText = hasHighlight
|
|
72
|
+
? FULL_TEXT.slice(highlightIndex + HIGHLIGHT_WORD.length)
|
|
73
|
+
: '';
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<AbsoluteFill
|
|
77
|
+
style={{
|
|
78
|
+
backgroundColor: COLOR_BG,
|
|
79
|
+
alignItems: 'center',
|
|
80
|
+
justifyContent: 'center',
|
|
81
|
+
fontFamily,
|
|
82
|
+
}}
|
|
83
|
+
>
|
|
84
|
+
<div
|
|
85
|
+
style={{
|
|
86
|
+
color: COLOR_TEXT,
|
|
87
|
+
fontSize: FONT_SIZE,
|
|
88
|
+
fontWeight: FONT_WEIGHT,
|
|
89
|
+
}}
|
|
90
|
+
>
|
|
91
|
+
{hasHighlight ? (
|
|
92
|
+
<>
|
|
93
|
+
<span>{preText}</span>
|
|
94
|
+
<Highlight
|
|
95
|
+
word={HIGHLIGHT_WORD}
|
|
96
|
+
color={COLOR_HIGHLIGHT}
|
|
97
|
+
delay={HIGHLIGHT_START_FRAME}
|
|
98
|
+
durationInFrames={HIGHLIGHT_WIPE_DURATION}
|
|
99
|
+
/>
|
|
100
|
+
<span>{postText}</span>
|
|
101
|
+
</>
|
|
102
|
+
) : (
|
|
103
|
+
<span>{FULL_TEXT}</span>
|
|
104
|
+
)}
|
|
105
|
+
</div>
|
|
106
|
+
</AbsoluteFill>
|
|
107
|
+
);
|
|
108
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: assets
|
|
3
|
+
description: Importing images, videos, audio, and fonts into Remotion
|
|
4
|
+
metadata:
|
|
5
|
+
tags: assets, staticFile, images, fonts, public
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Importing assets in Remotion
|
|
9
|
+
|
|
10
|
+
## The public folder
|
|
11
|
+
|
|
12
|
+
Place assets in the `public/` folder at your project root.
|
|
13
|
+
|
|
14
|
+
## Using staticFile()
|
|
15
|
+
|
|
16
|
+
You MUST use `staticFile()` to reference files from the `public/` folder:
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
import {Img, staticFile} from 'remotion';
|
|
20
|
+
|
|
21
|
+
export const MyComposition = () => {
|
|
22
|
+
return <Img src={staticFile('logo.png')} />;
|
|
23
|
+
};
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The function returns an encoded URL that works correctly when deploying to subdirectories.
|
|
27
|
+
|
|
28
|
+
## Using with components
|
|
29
|
+
|
|
30
|
+
**Images:**
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
import {Img, staticFile} from 'remotion';
|
|
34
|
+
|
|
35
|
+
<Img src={staticFile('photo.png')} />;
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Videos:**
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
import {Video} from '@remotion/media';
|
|
42
|
+
import {staticFile} from 'remotion';
|
|
43
|
+
|
|
44
|
+
<Video src={staticFile('clip.mp4')} />;
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Audio:**
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
import {Audio} from '@remotion/media';
|
|
51
|
+
import {staticFile} from 'remotion';
|
|
52
|
+
|
|
53
|
+
<Audio src={staticFile('music.mp3')} />;
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Fonts:**
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
import {staticFile} from 'remotion';
|
|
60
|
+
|
|
61
|
+
const fontFamily = new FontFace('MyFont', `url(${staticFile('font.woff2')})`);
|
|
62
|
+
await fontFamily.load();
|
|
63
|
+
document.fonts.add(fontFamily);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Remote URLs
|
|
67
|
+
|
|
68
|
+
Remote URLs can be used directly without `staticFile()`:
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
<Img src="https://example.com/image.png" />
|
|
72
|
+
<Video src="https://remotion.media/video.mp4" />
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Important notes
|
|
76
|
+
|
|
77
|
+
- Remotion components (`<Img>`, `<Video>`, `<Audio>`) ensure assets are fully loaded before rendering
|
|
78
|
+
- Special characters in filenames (`#`, `?`, `&`) are automatically encoded
|