├── .babelrc ├── .eslintrc ├── .gitattributes ├── .github └── workflows │ ├── render-video.yml │ └── test.yml ├── .gitignore ├── .prettierrc ├── .vscode └── settings.json ├── Dockerfile ├── README.md ├── out.mp4 ├── package-lock.json ├── package.json ├── remotion.config.ts ├── src ├── BestQualities.tsx ├── Blue.tsx ├── Cascadia.woff2 ├── CodeFrame.tsx ├── Cpu.tsx ├── EndCard.tsx ├── EndCardRepo.tsx ├── EndCardWebsite.tsx ├── EndCardYarn.tsx ├── FG_Virgil.woff2 ├── FadeTransition.tsx ├── FastRefreshDemo.tsx ├── Feature.tsx ├── Fork.tsx ├── GlowingStroke.tsx ├── GoToGithub.tsx ├── HowTo.tsx ├── Inspect.tsx ├── InspectAndRefactor.tsx ├── Install.tsx ├── InstallFrame.tsx ├── Intro │ ├── Arc.tsx │ └── Intro.tsx ├── JustWhite.tsx ├── Logo │ ├── Logo.tsx │ └── Triangle.tsx ├── Main.tsx ├── MultiThreaded.tsx ├── OpenSource.tsx ├── Pricing.tsx ├── PricingFree.tsx ├── PricingRight.tsx ├── PullRequest.tsx ├── Qualities.tsx ├── RemotionPlayerDemo.tsx ├── SSRMultithreaded.tsx ├── TeaseCodeFrame.tsx ├── Terminal.tsx ├── TerminalRender.tsx ├── Trailer.tsx ├── Transition.tsx ├── Video.tsx ├── WebTechnologies.tsx ├── Website.tsx ├── YesThisWorks.tsx ├── excalidraw-fonts.css ├── fast-refresh-demo.webm ├── fork-trimmed.webm ├── github.png ├── index.tsx ├── inspect-and-refactor.png ├── inspect.png ├── prism.css ├── pull-request.png ├── remotion-logo.png ├── remotion-player.webm ├── remotion-website.png ├── videothumbnail.png └── voiceover-no-music.mp3 ├── trailer.mp4 └── tsconfig.json /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | [ 4 | "prismjs", 5 | { 6 | "languages": ["javascript", "css", "markup", "tsx"], 7 | "plugins": ["line-numbers", "line-highlight"], 8 | "css": false 9 | } 10 | ] 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@remotion" 3 | } 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/workflows/render-video.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | workflow_dispatch: 4 | inputs: 5 | titleText: 6 | description: "Which text should it say?" 7 | required: true 8 | default: "Welcome to Remotion" 9 | titleColor: 10 | description: "Which color should it be in?" 11 | required: true 12 | default: "black" 13 | name: Render video 14 | jobs: 15 | render: 16 | name: Render video 17 | runs-on: macos-latest 18 | steps: 19 | - uses: actions/checkout@main 20 | - uses: actions/setup-node@main 21 | - run: brew install ffmpeg 22 | - run: npm i 23 | - run: npm run build -- --props="$WORKFLOW_INPUT" 24 | env: 25 | WORKFLOW_INPUT: ${{ toJson(github.event.inputs) }} 26 | - run: ffmpeg -y -i out.mp4 -i src/voiceover-no-music.mp3 -c:v copy -c:a aac trailer.mp4 27 | - uses: actions/upload-artifact@v2 28 | with: 29 | name: trailer.mp4 30 | path: trailer.mp4 31 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | name: Install and Test 4 | jobs: 5 | render: 6 | name: Install and Test 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@main 10 | - uses: actions/setup-node@main 11 | - run: npm i 12 | - run: npm test 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "bracketSpacing": false, 4 | "jsxBracketSameLine": false, 5 | "useTabs": true, 6 | "overrides": [ 7 | { 8 | "files": ["*.yml"], 9 | "options": { 10 | "singleQuote": false 11 | } 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.tabSize": 2, 3 | "java.configuration.updateBuildConfiguration": "disabled", 4 | "typescript.tsdk": "node_modules/typescript/lib", 5 | "editor.codeActionsOnSave": { 6 | "source.organizeImports": false, 7 | "source.fixAll": true 8 | }, 9 | "typescript.enablePromptUseWorkspaceTsdk": true 10 | } 11 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # This is a dockerized version of a server that you can easily deploy somewhere. 2 | # If you don't want server rendering, you can safely delete this file. 3 | 4 | FROM node:alpine 5 | 6 | # Installs latest Chromium (85) package. 7 | RUN apk add --no-cache \ 8 | chromium \ 9 | nss \ 10 | freetype \ 11 | freetype-dev \ 12 | harfbuzz \ 13 | ca-certificates \ 14 | ttf-freefont \ 15 | ffmpeg 16 | 17 | # Tell Puppeteer to skip installing Chrome. We'll be using the installed package. 18 | ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \ 19 | PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser 20 | 21 | COPY package*.json ./ 22 | COPY tsconfig.json ./ 23 | COPY src src 24 | COPY *.ts . 25 | COPY *.tsx . 26 | 27 | RUN npm i 28 | 29 | # Add user so we don't need --no-sandbox. 30 | RUN addgroup -S pptruser && adduser -S -g pptruser pptruser \ 31 | && mkdir -p /home/pptruser/Downloads /app \ 32 | && chown -R pptruser:pptruser /home/pptruser \ 33 | && chown -R pptruser:pptruser /app 34 | # Run everything after as non-privileged user. 35 | USER pptruser 36 | 37 | EXPOSE 8000 38 | 39 | CMD ["npm", "run", "server"] 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## [Watch the video](https://youtu.be/gwlDorikqgY) 2 | 3 | # Remotion video 4 | 5 |

6 | 7 | 8 | 9 |

10 | 11 | Welcome to your Remotion project! 12 | 13 | ## Commands 14 | 15 | **Start Preview** 16 | 17 | ```console 18 | npm start 19 | ``` 20 | 21 | **Render video** 22 | 23 | ```console 24 | npm run build 25 | ``` 26 | 27 | **Upgrade Remotion** 28 | 29 | ```console 30 | npm run upgrade 31 | ``` 32 | 33 | ## Docs 34 | 35 | Get started with Remotion by reading the [fundamentals page](https://www.remotion.dev/docs/the-fundamentals). 36 | 37 | ## Issues 38 | 39 | Found an issue with Remotion? [File an issue here](https://github.com/remotion-dev/remotion/issues/new). 40 | 41 | ## License 42 | 43 | Notice that a company license is needed. Read [the terms here](https://github.com/remotion-dev/remotion/blob/main/LICENSE.md). 44 | -------------------------------------------------------------------------------- /out.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/remotion-dev/trailer/63c2a66f2c7780f64c85c26e5f872daa31d9545c/out.mp4 -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "remotion-template", 3 | "version": "1.0.0", 4 | "description": "My Remotion video", 5 | "scripts": { 6 | "start": "remotion preview src/index.tsx", 7 | "build": "remotion render src/index.tsx Main out.mp4", 8 | "build-trailer": "remotion render src/index.tsx Trailer trailer.mp4", 9 | "upgrade": "remotion upgrade", 10 | "test": "eslint src --ext ts,tsx && tsc && ts-unused-exports tsconfig.json" 11 | }, 12 | "repository": {}, 13 | "license": "UNLICENSED", 14 | "dependencies": { 15 | "@remotion/bundler": "^3.0.0", 16 | "@remotion/cli": "^3.0.0", 17 | "@remotion/eslint-config": "^3.0.0", 18 | "@remotion/renderer": "^3.0.0", 19 | "@types/lodash": "^4.14.167", 20 | "@types/prismjs": "^1.16.2", 21 | "@types/react": "^18.0.6", 22 | "@types/styled-components": "^5.1.7", 23 | "babel-plugin-prismjs": "^2.0.1", 24 | "eslint": "^8.14.0", 25 | "hack-font": "^3.3.0", 26 | "lodash": "^4.17.20", 27 | "polished": "^4.0.5", 28 | "prettier": "^2.2.1", 29 | "prettier-plugin-organize-imports": "^2.3.4", 30 | "prism-react-renderer": "^1.1.1", 31 | "prismjs": "^1.23.0", 32 | "react": "^18.0.0", 33 | "react-dom": "^18.0.0", 34 | "react-is": "^18.0.0", 35 | "remotion": "^3.0.0", 36 | "styled-components": "^5.2.1", 37 | "ts-unused-exports": "^7.0.1", 38 | "typescript": "^4.6.3" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /remotion.config.ts: -------------------------------------------------------------------------------- 1 | import {Config} from 'remotion'; 2 | 3 | Config.Output.setOverwriteOutput(true); 4 | Config.Bundling.setCachingEnabled(false); 5 | -------------------------------------------------------------------------------- /src/BestQualities.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | AbsoluteFill, 3 | Img, 4 | spring, 5 | useCurrentFrame, 6 | useVideoConfig, 7 | } from 'remotion'; 8 | import styled from 'styled-components'; 9 | import {Feature} from './Qualities'; 10 | import remotionLogo from './remotion-logo.png'; 11 | 12 | const Container = styled(AbsoluteFill)` 13 | background-color: white; 14 | flex-direction: row; 15 | justify-content: center; 16 | align-items: center; 17 | `; 18 | 19 | const Left = styled.div``; 20 | 21 | const Right = styled.div` 22 | padding-right: 100px; 23 | `; 24 | 25 | const Spacer = styled.div` 26 | width: 500px; 27 | `; 28 | 29 | const Row = styled.div` 30 | flex-direction: row; 31 | display: flex; 32 | `; 33 | 34 | const programmingFeatures = [ 35 | 'Benefits of\nprogramming', 36 | 'Type safety', 37 | 'Testability', 38 | 'Server-side rendering', 39 | 'Continuous rendering', 40 | 'Continuous delivery', 41 | 'Git version control', 42 | 'Parametrization', 43 | 'Fast Refresh', 44 | 'Package ecosystem', 45 | ]; 46 | 47 | export const BestQualities: React.FC = () => { 48 | const frame = useCurrentFrame(); 49 | const {fps} = useVideoConfig(); 50 | 51 | const logoProgress = spring({ 52 | frame: frame - 180, 53 | fps, 54 | config: { 55 | damping: 200, 56 | }, 57 | }); 58 | 59 | return ( 60 | 61 | 62 | 63 | {programmingFeatures.map((f, index) => { 64 | return ( 65 | 73 | {f} 74 | 75 | ); 76 | })} 77 | 78 | 79 | 80 | {[ 81 | 'Video editing\nfeatures', 82 | 'Visual Preview', 83 | 'Timeline Scrubbing', 84 | 'Video footage export', 85 | 'Animation primitives', 86 | 'Composition primitives', 87 | 'Layers', 88 | 'Dynamic FPS', 89 | 'Audio support (Alpha)', 90 | 'MP4 export', 91 | ].map((f, index) => { 92 | return ( 93 | 101 | {f} 102 | 103 | ); 104 | })} 105 | 106 | 107 | 108 | 116 | 117 | 118 | ); 119 | }; 120 | -------------------------------------------------------------------------------- /src/Blue.tsx: -------------------------------------------------------------------------------- 1 | import {AbsoluteFill} from 'remotion'; 2 | 3 | export const Blue: React.FC = () => { 4 | return ( 5 | 11 | ); 12 | }; 13 | -------------------------------------------------------------------------------- /src/Cascadia.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/remotion-dev/trailer/63c2a66f2c7780f64c85c26e5f872daa31d9545c/src/Cascadia.woff2 -------------------------------------------------------------------------------- /src/CodeFrame.tsx: -------------------------------------------------------------------------------- 1 | import 'hack-font/build/web/hack.css'; 2 | import Highlight, {defaultProps} from 'prism-react-renderer'; 3 | import {interpolate, spring, useCurrentFrame, useVideoConfig} from 'remotion'; 4 | import styled from 'styled-components'; 5 | import './prism.css'; 6 | 7 | const Pre = styled.pre<{ 8 | width: number; 9 | }>` 10 | text-align: left; 11 | margin: 1em 0; 12 | font-size: 40px; 13 | width: ${(props) => props.width}px; 14 | `; 15 | 16 | const Line = styled.div` 17 | display: table-row; 18 | `; 19 | 20 | const LineContent = styled.span` 21 | display: table-cell; 22 | `; 23 | 24 | const Container = styled.div` 25 | flex: 1; 26 | justify-content: center; 27 | align-items: center; 28 | display: flex; 29 | `; 30 | 31 | const Frame = styled.div` 32 | border: 2px solid rgba(0, 0, 0, 0.14); 33 | border-radius: 20px; 34 | background-color: white; 35 | 36 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, 37 | Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 38 | `; 39 | 40 | const Title = styled.div` 41 | padding: 20px; 42 | text-align: center; 43 | font-size: 28px; 44 | `; 45 | 46 | const getProgressOfLine = ({ 47 | line, 48 | frame, 49 | fps, 50 | timing, 51 | }: { 52 | line: number; 53 | frame: number; 54 | fps: number; 55 | timing: Timing[]; 56 | }) => { 57 | const segment = timing.find((t) => t.line === line); 58 | if (!segment) { 59 | return 1; 60 | } 61 | return spring({ 62 | fps, 63 | frame: frame - segment.from, 64 | config: { 65 | stiffness: 200, 66 | damping: 100, 67 | mass: 0.5, 68 | overshootClamping: true, 69 | }, 70 | }); 71 | }; 72 | 73 | type Timing = { 74 | line: number; 75 | from: number; 76 | }; 77 | 78 | export const CodeFrame: React.FC<{ 79 | code: string; 80 | timing: Timing[]; 81 | title: string; 82 | width: number; 83 | }> = ({code, timing, title, width}) => { 84 | const frame = useCurrentFrame(); 85 | const {fps} = useVideoConfig(); 86 | 87 | return ( 88 | 89 | 90 | {title} 91 |
92 | 98 | {({className, style, tokens, getLineProps, getTokenProps}) => ( 99 |
100 | 								{tokens.map((line, i) => {
101 | 									return (
102 | 										
132 | 											
133 | 												{line.map((token, key) => {
134 | 													const props = getTokenProps({token, key});
135 | 													return (
136 | 														
145 | 													);
146 | 												})}
147 | 											
148 | 										
149 | 									);
150 | 								})}
151 | 							
152 | )} 153 |
154 |
155 | 156 |
157 | ); 158 | }; 159 | -------------------------------------------------------------------------------- /src/Cpu.tsx: -------------------------------------------------------------------------------- 1 | import {mix} from 'polished'; 2 | import {interpolate, spring, useCurrentFrame, useVideoConfig} from 'remotion'; 3 | import styled from 'styled-components'; 4 | 5 | const colors = ['#42e9f5', '#4290f5']; 6 | 7 | const Container = styled.div` 8 | height: 350px; 9 | width: 350px; 10 | border: 10px solid ${colors[1]}; 11 | border-radius: 20px; 12 | display: flex; 13 | padding: 5px; 14 | `; 15 | 16 | const Column = styled.div` 17 | display: flex; 18 | flex-direction: column; 19 | flex: 1; 20 | `; 21 | 22 | const Row = styled.div` 23 | display: flex; 24 | flex-direction: row; 25 | flex: 1; 26 | `; 27 | 28 | const Core = styled.div<{ 29 | x: number; 30 | y: number; 31 | }>` 32 | flex: 1; 33 | background-color: ${(props) => { 34 | const g = interpolate(props.x + props.y, [0, 6], [0, 1]); 35 | return mix(g, colors[0], colors[1]); 36 | }}; 37 | margin: 5px; 38 | border-radius: 6px; 39 | `; 40 | 41 | const CoreContainer: React.FC<{ 42 | x: number; 43 | y: number; 44 | }> = ({x, y}) => { 45 | const frame = useCurrentFrame(); 46 | const {fps} = useVideoConfig(); 47 | const offset = x * 4 + y; 48 | const progress = spring({ 49 | fps, 50 | frame: frame - Number(offset), 51 | }); 52 | return ; 53 | }; 54 | 55 | export const Cpu: React.FC = () => { 56 | return ( 57 | 58 | 59 | {new Array(4).fill(true).map((k, i) => { 60 | return ( 61 | 62 | {new Array(4).fill(true).map((x, j) => { 63 | return ; 64 | })} 65 | 66 | ); 67 | })} 68 | 69 | 70 | ); 71 | }; 72 | -------------------------------------------------------------------------------- /src/EndCard.tsx: -------------------------------------------------------------------------------- 1 | import {AbsoluteFill, spring, useCurrentFrame, useVideoConfig} from 'remotion'; 2 | import styled from 'styled-components'; 3 | import {EndCardRepo} from './EndCardRepo'; 4 | import {EndCardWebsite} from './EndCardWebsite'; 5 | import {EndCardYarn} from './EndCardYarn'; 6 | import {GlowingStroke} from './GlowingStroke'; 7 | 8 | const Outer = styled(AbsoluteFill)` 9 | background-color: white; 10 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.4); 11 | `; 12 | 13 | const Container = styled.div` 14 | background-color: rgba(0, 0, 0, 0.04); 15 | display: flex; 16 | flex: 1; 17 | flex-direction: row; 18 | padding: 40px; 19 | `; 20 | 21 | const Left = styled.div` 22 | flex: 1; 23 | display: flex; 24 | `; 25 | 26 | const Right = styled.div` 27 | flex: 1; 28 | display: flex; 29 | flex-direction: column; 30 | `; 31 | 32 | const RADIUS = 30; 33 | 34 | const Panel = styled.div` 35 | position: absolute; 36 | background-color: white; 37 | border-radius: ${RADIUS}px; 38 | display: flex; 39 | justify-content: center; 40 | align-items: center; 41 | box-shadow: 0 15px 20px rgba(0, 0, 0, 0.07); 42 | `; 43 | 44 | const Centered = styled(AbsoluteFill)` 45 | justify-content: center; 46 | align-items: center; 47 | `; 48 | 49 | export const EndCard: React.FC = () => { 50 | const {fps, width, height} = useVideoConfig(); 51 | 52 | const PADDING = 40; 53 | const SPACING = 30; 54 | const PANEL_WIDTH = (width - PADDING * 2 - SPACING) / 2; 55 | const BIG_PANEL_HEIGHT = height - PADDING * 2; 56 | const SMALL_PANEL_HEIGHT = (height - PADDING * 2 - SPACING) / 2; 57 | const frame = useCurrentFrame(); 58 | const progress = (i: number) => 59 | spring({ 60 | fps, 61 | frame: frame - i * 10 - 15, 62 | config: { 63 | damping: 100, 64 | mass: 2, 65 | }, 66 | }); 67 | 68 | return ( 69 | 70 | 71 | 72 | 79 | 80 | 88 | 89 | 90 | 91 | 92 |
93 | 94 | 101 | 102 | 110 | 111 | 112 | 113 |
114 | 122 | 123 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | ); 138 | }; 139 | -------------------------------------------------------------------------------- /src/EndCardRepo.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Container = styled.div` 4 | display: flex; 5 | justify-content: center; 6 | align-items: center; 7 | flex-direction: column; 8 | `; 9 | 10 | const Title = styled.div` 11 | font-weight: 700; 12 | font-family: -apple-system, BlinkMacSystemFont; 13 | font-size: 30px; 14 | margin-bottom: 7px; 15 | `; 16 | 17 | const Link = styled.div` 18 | font-weight: 700; 19 | font-size: 40px; 20 | font-family: -apple-system, BlinkMacSystemFont; 21 | background: linear-gradient(to right, #f5ad43, #fd764a); 22 | -webkit-background-clip: text; 23 | -moz-background-clip: text; 24 | background-clip: text; 25 | -webkit-text-fill-color: transparent; 26 | -moz-text-fill-color: transparent; 27 | text-fill-color: transparent; 28 | `; 29 | 30 | export const EndCardRepo: React.FC = () => { 31 | return ( 32 | 33 | This video is open source: 34 | 41 | github.com/remotion-dev/trailer 42 | 43 | 44 | ); 45 | }; 46 | -------------------------------------------------------------------------------- /src/EndCardWebsite.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Container = styled.div` 4 | display: flex; 5 | justify-content: center; 6 | align-items: center; 7 | flex-direction: column; 8 | `; 9 | 10 | const Title = styled.div` 11 | font-weight: 700; 12 | font-family: -apple-system, BlinkMacSystemFont; 13 | font-size: 30px; 14 | margin-bottom: 5px; 15 | `; 16 | 17 | const Link = styled.div` 18 | font-weight: 700; 19 | font-size: 60px; 20 | font-family: -apple-system, BlinkMacSystemFont; 21 | background: linear-gradient(to right, #e01d67, #79367a); 22 | -webkit-background-clip: text; 23 | -moz-background-clip: text; 24 | background-clip: text; 25 | -webkit-text-fill-color: transparent; 26 | -moz-text-fill-color: transparent; 27 | text-fill-color: transparent; 28 | `; 29 | 30 | export const EndCardWebsite: React.FC = () => { 31 | return ( 32 | 33 | Read the documentation: 34 | 41 | remotion.dev 42 | 43 | 44 | ); 45 | }; 46 | -------------------------------------------------------------------------------- /src/EndCardYarn.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import {Triangle} from './Logo/Triangle'; 3 | 4 | const Container = styled.div` 5 | justify-content: center; 6 | align-items: center; 7 | display: flex; 8 | flex-direction: column; 9 | `; 10 | 11 | const Title = styled.div` 12 | font-weight: 700; 13 | font-family: -apple-system, BlinkMacSystemFont; 14 | font-size: 30px; 15 | margin-bottom: 5px; 16 | `; 17 | 18 | const YarnCreateVideo = styled.div` 19 | font-weight: 700; 20 | font-size: 60px; 21 | font-family: -apple-system, BlinkMacSystemFont; 22 | background: linear-gradient(to right, #4290f5, #42e9f5); 23 | -webkit-background-clip: text; 24 | -moz-background-clip: text; 25 | background-clip: text; 26 | -webkit-text-fill-color: transparent; 27 | -moz-text-fill-color: transparent; 28 | text-fill-color: transparent; 29 | `; 30 | 31 | export const EndCardYarn: React.FC = () => { 32 | return ( 33 | 34 |
35 | 36 |
37 |
38 |
39 | Create your first video: 40 | yarn create video 41 |
42 | ); 43 | }; 44 | -------------------------------------------------------------------------------- /src/FG_Virgil.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/remotion-dev/trailer/63c2a66f2c7780f64c85c26e5f872daa31d9545c/src/FG_Virgil.woff2 -------------------------------------------------------------------------------- /src/FadeTransition.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | AbsoluteFill, 4 | interpolate, 5 | useCurrentFrame, 6 | useVideoConfig, 7 | } from 'remotion'; 8 | 9 | export const FadeTransition: React.FC<{ 10 | type: 'in' | 'out'; 11 | duration: number; 12 | children: React.ReactNode; 13 | }> = ({type, children, duration}) => { 14 | const frame = useCurrentFrame(); 15 | const videoConfig = useVideoConfig(); 16 | 17 | const firstFrame = videoConfig.durationInFrames - duration; 18 | 19 | const progress = 20 | type === 'in' 21 | ? interpolate(frame, [0, duration], [0, 1], { 22 | extrapolateRight: 'clamp', 23 | extrapolateLeft: 'clamp', 24 | }) 25 | : interpolate( 26 | frame, 27 | [firstFrame, videoConfig.durationInFrames - 1], 28 | [1, 0], 29 | { 30 | extrapolateLeft: 'clamp', 31 | extrapolateRight: 'clamp', 32 | } 33 | ); 34 | 35 | return ( 36 | 41 | {children} 42 | 43 | ); 44 | }; 45 | -------------------------------------------------------------------------------- /src/FastRefreshDemo.tsx: -------------------------------------------------------------------------------- 1 | import {useVideoConfig, Video} from 'remotion'; 2 | import fastRefreshDemo from './fast-refresh-demo.webm'; 3 | 4 | export const FastRefreshDemo: React.FC = () => { 5 | const {height} = useVideoConfig(); 6 | return