@remotion/promo-pages 4.0.315 → 4.0.317
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/.turbo/turbo-make.log +2 -2
- package/dist/Homepage.js +11850 -12153
- package/dist/components/Homepage.js +4 -4
- package/dist/components/homepage/CommunityStats.js +1 -1
- package/dist/components/homepage/Counter.d.ts +1 -0
- package/dist/components/homepage/Counter.js +15 -7
- package/dist/components/homepage/Demo/DemoRender.d.ts +16 -16
- package/dist/components/homepage/Demo/DisplayedEmoji.js +17 -3
- package/dist/components/homepage/Demo/math.d.ts +1 -1
- package/dist/components/homepage/FreePricing.js +20 -25
- package/dist/components/homepage/IconForTemplate.js +4 -0
- package/dist/components/homepage/IfYouKnowReact.js +5 -2
- package/dist/components/homepage/NewsletterButton.js +3 -2
- package/dist/components/homepage/ParameterizeAndEdit.d.ts +2 -0
- package/dist/components/homepage/ParameterizeAndEdit.js +22 -0
- package/dist/components/homepage/RealMp4Videos.js +10 -1
- package/dist/components/homepage/VideoAppsShowcase.js +6 -3
- package/dist/components/homepage/VideoAppsTitle.d.ts +0 -1
- package/dist/components/homepage/VideoAppsTitle.js +1 -4
- package/dist/components/icons/recorder.d.ts +3 -0
- package/dist/components/icons/recorder.js +4 -0
- package/dist/homepage/Pricing.js +131 -90
- package/dist/tailwind.css +74 -61
- package/package.json +10 -10
- package/public/img/editing-safari.mp4 +0 -0
- package/public/img/editing-vp9-chrome.webm +0 -0
- package/src/components/Homepage.tsx +7 -13
- package/src/components/homepage/CommunityStats.tsx +1 -1
- package/src/components/homepage/Counter.tsx +17 -7
- package/src/components/homepage/Demo/DisplayedEmoji.tsx +22 -4
- package/src/components/homepage/FreePricing.tsx +88 -65
- package/src/components/homepage/IconForTemplate.tsx +5 -0
- package/src/components/homepage/IfYouKnowReact.tsx +26 -14
- package/src/components/homepage/NewsletterButton.tsx +5 -4
- package/src/components/homepage/ParameterizeAndEdit.tsx +89 -0
- package/src/components/homepage/RealMp4Videos.tsx +55 -13
- package/src/components/homepage/VideoAppsShowcase.tsx +21 -10
- package/src/components/homepage/VideoAppsTitle.tsx +0 -13
- package/src/components/icons/recorder.tsx +23 -0
- package/dist/components/homepage/Editor.d.ts +0 -2
- package/dist/components/homepage/Editor.js +0 -37
- package/public/img/player-demo.mp4 +0 -0
- package/src/components/homepage/Editor.tsx +0 -67
|
@@ -4,19 +4,18 @@ import React from 'react';
|
|
|
4
4
|
import {BackgroundAnimation} from './homepage/BackgroundAnimation';
|
|
5
5
|
import CommunityStats from './homepage/CommunityStats';
|
|
6
6
|
import {Demo} from './homepage/Demo';
|
|
7
|
-
import {LightningFastEditor} from './homepage/Editor';
|
|
8
7
|
import EvaluateRemotionSection from './homepage/EvaluateRemotion';
|
|
9
8
|
import {IfYouKnowReact} from './homepage/IfYouKnowReact';
|
|
10
9
|
import type {ColorMode} from './homepage/layout/use-color-mode';
|
|
11
10
|
import {ColorModeProvider} from './homepage/layout/use-color-mode';
|
|
12
11
|
import {MoreVideoPowerSection} from './homepage/MoreVideoPowerSection';
|
|
13
12
|
import {NewsletterButton} from './homepage/NewsletterButton';
|
|
13
|
+
import {ParameterizeAndEdit} from './homepage/ParameterizeAndEdit';
|
|
14
14
|
import {Pricing} from './homepage/Pricing';
|
|
15
15
|
import {RealMP4Videos} from './homepage/RealMp4Videos';
|
|
16
16
|
import TrustedByBanner from './homepage/TrustedByBanner';
|
|
17
|
-
import {VideoApps} from './homepage/VideoApps';
|
|
18
17
|
import VideoAppsShowcase from './homepage/VideoAppsShowcase';
|
|
19
|
-
import {SectionTitle
|
|
18
|
+
import {SectionTitle} from './homepage/VideoAppsTitle';
|
|
20
19
|
import {WriteInReact} from './homepage/WriteInReact';
|
|
21
20
|
|
|
22
21
|
export const NewLanding: React.FC<{
|
|
@@ -38,19 +37,11 @@ export const NewLanding: React.FC<{
|
|
|
38
37
|
<WriteInReact />
|
|
39
38
|
<br />
|
|
40
39
|
<IfYouKnowReact />
|
|
40
|
+
<ParameterizeAndEdit />
|
|
41
41
|
<RealMP4Videos />
|
|
42
42
|
<br />
|
|
43
43
|
<br />
|
|
44
44
|
<br />
|
|
45
|
-
<br />
|
|
46
|
-
<LightningFastEditor />
|
|
47
|
-
<br />
|
|
48
|
-
<br />
|
|
49
|
-
<br />
|
|
50
|
-
<VideoAppsTitle />
|
|
51
|
-
<VideoApps active="remotion" />
|
|
52
|
-
<br />
|
|
53
|
-
<br />
|
|
54
45
|
<VideoAppsShowcase />
|
|
55
46
|
<br />
|
|
56
47
|
<br />
|
|
@@ -70,7 +61,10 @@ export const NewLanding: React.FC<{
|
|
|
70
61
|
<br />
|
|
71
62
|
<br />
|
|
72
63
|
<br />
|
|
73
|
-
<SectionTitle>Even more
|
|
64
|
+
<SectionTitle>Even more power to developers</SectionTitle>
|
|
65
|
+
<div className={'fontbrand text-center mb-10 -mt-4'}>
|
|
66
|
+
Innovative video products that you might enjoy.
|
|
67
|
+
</div>
|
|
74
68
|
<MoreVideoPowerSection />
|
|
75
69
|
<br />
|
|
76
70
|
<br />
|
|
@@ -25,7 +25,7 @@ const SectionLink: React.FC<{
|
|
|
25
25
|
const CommunityStats: React.FC = () => (
|
|
26
26
|
<div className={'m-auto max-w-[700px] text-center'}>
|
|
27
27
|
<SectionTitle>Never build alone</SectionTitle>
|
|
28
|
-
<div className={'fontbrand text-center mb-10'}>
|
|
28
|
+
<div className={'fontbrand text-center mb-10 -mt-4'}>
|
|
29
29
|
Join a thriving community of developers.
|
|
30
30
|
</div>
|
|
31
31
|
<div className={'flex flex-wrap justify-between gap-4 w-full items-center'}>
|
|
@@ -47,40 +47,50 @@ interface CounterProps {
|
|
|
47
47
|
readonly count: number;
|
|
48
48
|
readonly setCount: (count: number) => void;
|
|
49
49
|
readonly minCount?: number;
|
|
50
|
+
readonly step?: number;
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
export const Counter: React.FC<CounterProps> = ({
|
|
53
54
|
count,
|
|
54
55
|
setCount,
|
|
55
56
|
minCount = 0,
|
|
57
|
+
step = 1,
|
|
56
58
|
}) => {
|
|
57
59
|
const decrement = () => {
|
|
58
60
|
if (count > minCount) {
|
|
59
|
-
setCount(count -
|
|
61
|
+
setCount(Math.max(minCount, count - step));
|
|
60
62
|
}
|
|
61
63
|
};
|
|
62
64
|
|
|
63
65
|
const increment = () => {
|
|
64
|
-
setCount(count +
|
|
66
|
+
setCount(count + step);
|
|
65
67
|
};
|
|
66
68
|
|
|
67
69
|
return (
|
|
68
|
-
<div style={container} className={cn('border-effect w-[
|
|
70
|
+
<div style={container} className={cn('border-effect w-[140px] text-text')}>
|
|
69
71
|
<input
|
|
70
72
|
className={
|
|
71
|
-
'fontbrand text-2xl font-medium min-w-[
|
|
73
|
+
'fontbrand text-2xl font-medium min-w-[80px] border-0 text-end bg-transparent outline-0 text-text'
|
|
72
74
|
}
|
|
73
75
|
type="number"
|
|
74
76
|
onClick={(e) => e.currentTarget.select()}
|
|
75
77
|
value={count}
|
|
76
78
|
onChange={(e: ChangeEvent<HTMLInputElement>) => {
|
|
77
79
|
if (e.target.value.trim() === '') {
|
|
78
|
-
setCount(1);
|
|
80
|
+
setCount(step === 1 ? 1 : minCount);
|
|
79
81
|
return;
|
|
80
82
|
}
|
|
81
83
|
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
+
const inputValue = parseInt(e.target.value, 10);
|
|
85
|
+
const validValue = Math.max(inputValue, minCount);
|
|
86
|
+
|
|
87
|
+
// For steps > 1, round to the nearest valid step
|
|
88
|
+
if (step > 1) {
|
|
89
|
+
const roundedValue = Math.round(validValue / step) * step;
|
|
90
|
+
setCount(Math.max(roundedValue, minCount));
|
|
91
|
+
} else {
|
|
92
|
+
setCount(validValue);
|
|
93
|
+
}
|
|
84
94
|
}}
|
|
85
95
|
/>
|
|
86
96
|
<div className="flex flex-col ml-3 h-full">
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type {EmojiName} from '@remotion/animated-emoji';
|
|
2
|
-
import type {LottieAnimationData} from '@remotion/lottie';
|
|
3
|
-
import {Lottie, getLottieMetadata} from '@remotion/lottie';
|
|
2
|
+
import type {Lottie, LottieAnimationData} from '@remotion/lottie';
|
|
4
3
|
import React, {useEffect, useMemo, useState} from 'react';
|
|
5
4
|
import {
|
|
6
5
|
cancelRender,
|
|
@@ -20,6 +19,9 @@ export const DisplayedEmoji: React.FC<{
|
|
|
20
19
|
}> = ({emoji}) => {
|
|
21
20
|
const [data, setData] = useState<Data | null>(null);
|
|
22
21
|
const {durationInFrames, fps} = useVideoConfig();
|
|
22
|
+
const [browser, setBrowser] = useState<boolean>(
|
|
23
|
+
typeof document !== 'undefined',
|
|
24
|
+
);
|
|
23
25
|
|
|
24
26
|
const src = useMemo(() => {
|
|
25
27
|
if (emoji === 'melting') {
|
|
@@ -40,8 +42,14 @@ export const DisplayedEmoji: React.FC<{
|
|
|
40
42
|
const [handle] = useState(() => delayRender());
|
|
41
43
|
|
|
42
44
|
useEffect(() => {
|
|
43
|
-
Promise.all([
|
|
44
|
-
.then((
|
|
45
|
+
Promise.all([
|
|
46
|
+
fetch(src).then((res) => res.json()),
|
|
47
|
+
import('@remotion/lottie').then(({Lottie, getLottieMetadata}) => ({
|
|
48
|
+
Lottie,
|
|
49
|
+
getLottieMetadata,
|
|
50
|
+
})),
|
|
51
|
+
])
|
|
52
|
+
.then(([json, {Lottie, getLottieMetadata}]) => {
|
|
45
53
|
setData({
|
|
46
54
|
Lottie,
|
|
47
55
|
duration: getLottieMetadata(json)?.durationInSeconds as number,
|
|
@@ -54,6 +62,16 @@ export const DisplayedEmoji: React.FC<{
|
|
|
54
62
|
});
|
|
55
63
|
}, [handle, src]);
|
|
56
64
|
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (typeof document !== 'undefined') {
|
|
67
|
+
setBrowser(true);
|
|
68
|
+
}
|
|
69
|
+
}, []);
|
|
70
|
+
|
|
71
|
+
if (!browser) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
57
75
|
if (!data) {
|
|
58
76
|
return null;
|
|
59
77
|
}
|
|
@@ -65,7 +65,7 @@ const SmallPriceTag: React.FC<{
|
|
|
65
65
|
return (
|
|
66
66
|
<div
|
|
67
67
|
className={
|
|
68
|
-
'fontbrand text-2xl font-medium w-auto min-w-[80px] text-right shrink-0
|
|
68
|
+
'fontbrand text-2xl font-medium w-auto min-w-[80px] text-right shrink-0'
|
|
69
69
|
}
|
|
70
70
|
>
|
|
71
71
|
{children}
|
|
@@ -137,10 +137,15 @@ const SEAT_PRICE = 25;
|
|
|
137
137
|
const RENDER_UNIT_PRICE = 10;
|
|
138
138
|
const WEBCODECS_UNIT_PRICE = 10;
|
|
139
139
|
|
|
140
|
+
const icon: React.CSSProperties = {
|
|
141
|
+
height: 16,
|
|
142
|
+
marginLeft: 4,
|
|
143
|
+
};
|
|
144
|
+
|
|
140
145
|
export const CompanyPricing: React.FC = () => {
|
|
141
146
|
const [devSeatCount, setDevSeatCount] = React.useState(1);
|
|
142
|
-
const [
|
|
143
|
-
const [
|
|
147
|
+
const [cloudRenders, setCloudRenders] = React.useState(1000);
|
|
148
|
+
const [creations, setCreations] = React.useState(1000);
|
|
144
149
|
|
|
145
150
|
const formatPrice = useCallback((price: number) => {
|
|
146
151
|
const formatter = new Intl.NumberFormat('en-US', {
|
|
@@ -155,29 +160,15 @@ export const CompanyPricing: React.FC = () => {
|
|
|
155
160
|
return Math.max(
|
|
156
161
|
100,
|
|
157
162
|
devSeatCount * SEAT_PRICE +
|
|
158
|
-
|
|
159
|
-
|
|
163
|
+
(cloudRenders / 1000) * RENDER_UNIT_PRICE +
|
|
164
|
+
(creations / 1000) * WEBCODECS_UNIT_PRICE,
|
|
160
165
|
);
|
|
161
|
-
}, [
|
|
166
|
+
}, [cloudRenders, devSeatCount, creations]);
|
|
162
167
|
|
|
163
168
|
const totalPriceString = useMemo(() => {
|
|
164
169
|
return formatPrice(totalPrice);
|
|
165
170
|
}, [formatPrice, totalPrice]);
|
|
166
171
|
|
|
167
|
-
const rendersPerMonth = useMemo(() => {
|
|
168
|
-
const formatter = new Intl.NumberFormat('en-US', {
|
|
169
|
-
maximumFractionDigits: 0,
|
|
170
|
-
});
|
|
171
|
-
return formatter.format(cloudUnitCount * 1000);
|
|
172
|
-
}, [cloudUnitCount]);
|
|
173
|
-
|
|
174
|
-
const conversionsPerMonth = useMemo(() => {
|
|
175
|
-
const formatter = new Intl.NumberFormat('en-US', {
|
|
176
|
-
maximumFractionDigits: 0,
|
|
177
|
-
});
|
|
178
|
-
return formatter.format(webcodecsUnits * 1000);
|
|
179
|
-
}, [webcodecsUnits]);
|
|
180
|
-
|
|
181
172
|
return (
|
|
182
173
|
<Container>
|
|
183
174
|
<Audience>For collaborations and companies of 4+ people</Audience>
|
|
@@ -189,80 +180,87 @@ export const CompanyPricing: React.FC = () => {
|
|
|
189
180
|
<InfoTooltip text="Credits for Mux.com. Applies only to new Mux customers." />
|
|
190
181
|
</PricingBulletPoint>
|
|
191
182
|
<div style={{height: 30}} />
|
|
192
|
-
<div className={'flex flex-row items-center'}>
|
|
183
|
+
<div className={'flex flex-col md:flex-row md:items-center'}>
|
|
193
184
|
<div style={textUnitWrapper}>
|
|
194
185
|
<div className={'fontbrand font-bold text-lg'}>Developer Seats</div>
|
|
195
186
|
<div className={'text-muted fontbrand text-sm'}>
|
|
196
187
|
Number of developers working with Remotion
|
|
197
188
|
</div>
|
|
198
189
|
</div>
|
|
199
|
-
<div style={{flex: 3}} />
|
|
200
|
-
<
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
190
|
+
<div style={{flex: 3}} className="hidden md:block" />
|
|
191
|
+
<div className="flex flex-row items-center justify-between mt-3 md:mt-0">
|
|
192
|
+
<Counter
|
|
193
|
+
count={devSeatCount}
|
|
194
|
+
setCount={setDevSeatCount}
|
|
195
|
+
minCount={1}
|
|
196
|
+
/>
|
|
197
|
+
<SmallPriceTag>
|
|
198
|
+
$
|
|
199
|
+
{new Intl.NumberFormat('en-US', {
|
|
200
|
+
maximumFractionDigits: 0,
|
|
201
|
+
}).format(SEAT_PRICE * devSeatCount)}
|
|
202
|
+
</SmallPriceTag>
|
|
203
|
+
</div>
|
|
207
204
|
</div>
|
|
208
205
|
<div style={{height: 14}} />
|
|
209
|
-
<div className={'flex flex-row items-center'}>
|
|
206
|
+
<div className={'flex flex-col md:flex-row md:items-center'}>
|
|
210
207
|
<div style={textUnitWrapper}>
|
|
211
|
-
<div className={'fontbrand font-bold text-lg'}>
|
|
212
|
-
Cloud Rendering Units
|
|
213
|
-
</div>
|
|
208
|
+
<div className={'fontbrand font-bold text-lg'}>Server renders</div>
|
|
214
209
|
<div className={'text-muted fontbrand text-sm'}>
|
|
215
|
-
Allows for {rendersPerMonth}{' '}
|
|
216
210
|
<a
|
|
217
211
|
href="https://www.remotion.dev/docs/compare-ssr"
|
|
218
212
|
className="underline underline-offset-4 text-inherit"
|
|
219
213
|
>
|
|
220
|
-
|
|
221
|
-
</a>
|
|
222
|
-
each
|
|
214
|
+
Renders per month (self-hosted)
|
|
215
|
+
</a>
|
|
223
216
|
</div>
|
|
224
217
|
</div>
|
|
225
|
-
<div style={{flex: 3}} />
|
|
226
|
-
<
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
218
|
+
<div style={{flex: 3}} className="hidden md:block" />
|
|
219
|
+
<div className="flex flex-row items-center justify-between mt-3 md:mt-0">
|
|
220
|
+
<Counter
|
|
221
|
+
count={cloudRenders}
|
|
222
|
+
setCount={setCloudRenders}
|
|
223
|
+
minCount={0}
|
|
224
|
+
step={1000}
|
|
225
|
+
/>
|
|
226
|
+
<SmallPriceTag>
|
|
227
|
+
$
|
|
228
|
+
{new Intl.NumberFormat('en-US', {
|
|
229
|
+
maximumFractionDigits: 0,
|
|
230
|
+
}).format((cloudRenders / 1000) * RENDER_UNIT_PRICE)}
|
|
231
|
+
</SmallPriceTag>
|
|
232
|
+
</div>
|
|
237
233
|
</div>
|
|
238
234
|
<div style={{height: 14}} />
|
|
239
|
-
<div className={'flex flex-row items-center'}>
|
|
235
|
+
<div className={'flex flex-col md:flex-row md:items-center'}>
|
|
240
236
|
<div style={textUnitWrapper}>
|
|
241
237
|
<div className={'fontbrand font-bold text-lg'}>
|
|
242
|
-
WebCodecs
|
|
238
|
+
WebCodecs video creations
|
|
243
239
|
</div>
|
|
244
240
|
<div className={'text-muted fontbrand text-sm'}>
|
|
245
|
-
Allows for{' '}
|
|
246
241
|
<a
|
|
247
242
|
className="underline underline-offset-4 text-inherit"
|
|
248
243
|
href="https://remotion.dev/webcodecs"
|
|
249
244
|
>
|
|
250
|
-
|
|
245
|
+
Client-side video creations per month
|
|
251
246
|
</a>
|
|
252
247
|
</div>
|
|
253
248
|
</div>
|
|
254
|
-
<div style={{flex: 3}} />
|
|
255
|
-
<
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
249
|
+
<div style={{flex: 3}} className="hidden md:block" />
|
|
250
|
+
<div className="flex flex-row items-center justify-between mt-3 md:mt-0">
|
|
251
|
+
<Counter
|
|
252
|
+
count={creations}
|
|
253
|
+
setCount={setCreations}
|
|
254
|
+
minCount={0}
|
|
255
|
+
step={1000}
|
|
256
|
+
/>
|
|
257
|
+
<SmallPriceTag>
|
|
258
|
+
$
|
|
259
|
+
{new Intl.NumberFormat('en-US', {
|
|
260
|
+
maximumFractionDigits: 0,
|
|
261
|
+
}).format((creations / 1000) * WEBCODECS_UNIT_PRICE)}
|
|
262
|
+
</SmallPriceTag>
|
|
263
|
+
</div>
|
|
266
264
|
</div>
|
|
267
265
|
<div style={{height: 20}} />
|
|
268
266
|
<div className={'flex flex-row justify-end'}>
|
|
@@ -276,6 +274,31 @@ export const CompanyPricing: React.FC = () => {
|
|
|
276
274
|
</BottomInfo>
|
|
277
275
|
</div>
|
|
278
276
|
</div>
|
|
277
|
+
<div className={'flex flex-row justify-end mt-4'}>
|
|
278
|
+
<div
|
|
279
|
+
style={{
|
|
280
|
+
...textUnitWrapper,
|
|
281
|
+
alignItems: 'flex-end',
|
|
282
|
+
}}
|
|
283
|
+
>
|
|
284
|
+
<a
|
|
285
|
+
href="https://remotion.pro/dashboard"
|
|
286
|
+
className="font-brand text-brand flex flex-row items-center gap-1 no-underline"
|
|
287
|
+
>
|
|
288
|
+
Buy now{' '}
|
|
289
|
+
<svg
|
|
290
|
+
style={icon}
|
|
291
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
292
|
+
viewBox="0 0 448 512"
|
|
293
|
+
>
|
|
294
|
+
<path
|
|
295
|
+
fill="currentColor"
|
|
296
|
+
d="M438.6 278.6l-160 160C272.4 444.9 264.2 448 256 448s-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L338.8 288H32C14.33 288 .0016 273.7 .0016 256S14.33 224 32 224h306.8l-105.4-105.4c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l160 160C451.1 245.9 451.1 266.1 438.6 278.6z"
|
|
297
|
+
/>
|
|
298
|
+
</svg>
|
|
299
|
+
</a>
|
|
300
|
+
</div>
|
|
301
|
+
</div>
|
|
279
302
|
</Container>
|
|
280
303
|
);
|
|
281
304
|
};
|
|
@@ -7,6 +7,7 @@ import {JSIcon} from '../icons/js';
|
|
|
7
7
|
import {MusicIcon} from '../icons/music';
|
|
8
8
|
import {NextIcon} from '../icons/next';
|
|
9
9
|
import {OverlayIcon} from '../icons/overlay';
|
|
10
|
+
import {Recorder} from '../icons/recorder';
|
|
10
11
|
import {ReactRouterIcon} from '../icons/remix';
|
|
11
12
|
import {SkiaIcon} from '../icons/skia';
|
|
12
13
|
import {Stargazer} from '../icons/stargazer';
|
|
@@ -135,6 +136,10 @@ export const IconForTemplate: React.FC<{
|
|
|
135
136
|
return <OverlayIcon style={{height: scale * 42}} />;
|
|
136
137
|
}
|
|
137
138
|
|
|
139
|
+
if (template.cliId === 'recorder') {
|
|
140
|
+
return <Recorder style={{height: scale * 36}} />;
|
|
141
|
+
}
|
|
142
|
+
|
|
138
143
|
if (
|
|
139
144
|
template.cliId === 'next' ||
|
|
140
145
|
template.cliId === 'next-tailwind' ||
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React, {useEffect, useState} from 'react';
|
|
2
|
-
import {BlueButton} from './layout/Button';
|
|
3
2
|
|
|
4
3
|
export const isWebkit = () => {
|
|
5
4
|
if (typeof window === 'undefined') {
|
|
@@ -14,6 +13,11 @@ export const isWebkit = () => {
|
|
|
14
13
|
return isSafariUserAgent || isChrome;
|
|
15
14
|
};
|
|
16
15
|
|
|
16
|
+
const icon: React.CSSProperties = {
|
|
17
|
+
height: 16,
|
|
18
|
+
marginLeft: 10,
|
|
19
|
+
};
|
|
20
|
+
|
|
17
21
|
export const IfYouKnowReact: React.FC = () => {
|
|
18
22
|
const [vid, setVid] = useState('/img/compose.webm');
|
|
19
23
|
|
|
@@ -24,31 +28,39 @@ export const IfYouKnowReact: React.FC = () => {
|
|
|
24
28
|
}, []);
|
|
25
29
|
|
|
26
30
|
return (
|
|
27
|
-
<div className="flex flex-col lg:flex-row text-left
|
|
31
|
+
<div className="flex flex-col lg:flex-row text-left justify-start lg:justify-end items-start lg:mb-0 gap-6 mt-8">
|
|
28
32
|
<video
|
|
29
33
|
src={vid}
|
|
30
34
|
muted
|
|
31
35
|
autoPlay
|
|
32
36
|
playsInline
|
|
33
37
|
loop
|
|
34
|
-
className="w-[
|
|
38
|
+
className="w-[500px] cursor-default! relative lg:-translate-x-8 -mb-40 lg:mt-0 lg:mb-0"
|
|
35
39
|
/>
|
|
36
|
-
<div
|
|
37
|
-
<div className="lg:text-right">
|
|
40
|
+
<div>
|
|
38
41
|
<h2 className="text-4xl fontbrand pt-20">
|
|
39
|
-
<span className="text-brand">Compose</span>
|
|
40
|
-
<br />
|
|
41
|
-
video with code.
|
|
42
|
+
<span className="text-brand">Compose</span> with code
|
|
42
43
|
</h2>
|
|
43
|
-
<p className="leading-relaxed">
|
|
44
|
+
<p className="leading-relaxed font-brand">
|
|
44
45
|
Use React, a powerful frontend technology, to create sophisticated
|
|
45
46
|
videos with code.
|
|
46
47
|
</p>
|
|
47
|
-
<div className="h-
|
|
48
|
-
<a
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
<div className="h-4" />
|
|
49
|
+
<a
|
|
50
|
+
className="no-underline text-brand font-brand font-bold inline-flex flex-row items-center"
|
|
51
|
+
href="/docs/the-fundamentals"
|
|
52
|
+
>
|
|
53
|
+
Learn Remotion{' '}
|
|
54
|
+
<svg
|
|
55
|
+
style={icon}
|
|
56
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
57
|
+
viewBox="0 0 448 512"
|
|
58
|
+
>
|
|
59
|
+
<path
|
|
60
|
+
fill="currentColor"
|
|
61
|
+
d="M438.6 278.6l-160 160C272.4 444.9 264.2 448 256 448s-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L338.8 288H32C14.33 288 .0016 273.7 .0016 256S14.33 224 32 224h306.8l-105.4-105.4c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l160 160C451.1 245.9 451.1 266.1 438.6 278.6z"
|
|
62
|
+
/>
|
|
63
|
+
</svg>
|
|
52
64
|
</a>
|
|
53
65
|
</div>
|
|
54
66
|
</div>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, {useCallback, useState} from 'react';
|
|
2
2
|
import {BlueButton} from './layout/Button';
|
|
3
3
|
import {Spacer} from './Spacer';
|
|
4
|
+
import {SectionTitle} from './VideoAppsTitle';
|
|
4
5
|
|
|
5
6
|
export const NewsletterButton: React.FC<{}> = () => {
|
|
6
7
|
const [email, setEmail] = useState('');
|
|
@@ -45,17 +46,17 @@ export const NewsletterButton: React.FC<{}> = () => {
|
|
|
45
46
|
<div className="flex flex-col">
|
|
46
47
|
<div className={'w-full'}>
|
|
47
48
|
<div className={'flex flex-col flex-1'}>
|
|
48
|
-
<
|
|
49
|
+
<SectionTitle>Newsletter</SectionTitle>
|
|
49
50
|
<form
|
|
50
51
|
onSubmit={handleSubmit}
|
|
51
52
|
style={{
|
|
52
53
|
width: '100%',
|
|
53
54
|
}}
|
|
54
55
|
>
|
|
55
|
-
<
|
|
56
|
+
<div className={'fontbrand text-center mb-10 -mt-4'}>
|
|
56
57
|
Read about new features and noteworthy updates we have made on
|
|
57
|
-
Remotion once in a while.
|
|
58
|
-
</
|
|
58
|
+
Remotion once in a while.{' '}
|
|
59
|
+
</div>
|
|
59
60
|
|
|
60
61
|
<input
|
|
61
62
|
className="w-full dark:bg-[#121212] rounded-lg border-effect border-black outline-none px-3 py-3 fontbrand text-lg box-border focus:border-brand"
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import React, {useEffect, useRef, useState} from 'react';
|
|
2
|
+
import {isWebkit} from './IfYouKnowReact';
|
|
3
|
+
|
|
4
|
+
const icon: React.CSSProperties = {
|
|
5
|
+
height: 16,
|
|
6
|
+
marginLeft: 10,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const ParameterizeAndEdit: React.FC = () => {
|
|
10
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
11
|
+
const [vid, setVid] = useState('/img/editing-vp9-chrome.webm');
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
if (isWebkit()) {
|
|
15
|
+
setVid('/img/editing-safari.mp4');
|
|
16
|
+
}
|
|
17
|
+
}, []);
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<div
|
|
21
|
+
ref={ref}
|
|
22
|
+
className={
|
|
23
|
+
'flex flex-col lg:flex-row justify-start lg:justify-end items-start gap-6 mt-20 lg:mt-0'
|
|
24
|
+
}
|
|
25
|
+
>
|
|
26
|
+
<div>
|
|
27
|
+
<video
|
|
28
|
+
src={vid}
|
|
29
|
+
autoPlay
|
|
30
|
+
muted
|
|
31
|
+
playsInline
|
|
32
|
+
loop
|
|
33
|
+
style={{
|
|
34
|
+
width: 500,
|
|
35
|
+
maxWidth: '100%',
|
|
36
|
+
borderRadius: 7,
|
|
37
|
+
overflow: 'hidden',
|
|
38
|
+
}}
|
|
39
|
+
/>
|
|
40
|
+
</div>
|
|
41
|
+
<div style={{flex: 1}} className="font-brand pt-4">
|
|
42
|
+
<h2 className={'fontbrand text-4xl'}>
|
|
43
|
+
Edit <span className="text-brand">dynamically</span>
|
|
44
|
+
</h2>
|
|
45
|
+
<p className="leading-relaxed">
|
|
46
|
+
Parameterize your video by passing data.
|
|
47
|
+
<br />
|
|
48
|
+
Or embed it into your app and build an interface around it.
|
|
49
|
+
</p>
|
|
50
|
+
<div className="h-4" />
|
|
51
|
+
<div className="leading-6">
|
|
52
|
+
<a
|
|
53
|
+
className="no-underline text-brand font-brand font-bold inline-flex flex-row items-center"
|
|
54
|
+
href="/docs/studio"
|
|
55
|
+
>
|
|
56
|
+
Remotion Studio{' '}
|
|
57
|
+
<svg
|
|
58
|
+
style={icon}
|
|
59
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
60
|
+
viewBox="0 0 448 512"
|
|
61
|
+
>
|
|
62
|
+
<path
|
|
63
|
+
fill="currentColor"
|
|
64
|
+
d="M438.6 278.6l-160 160C272.4 444.9 264.2 448 256 448s-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L338.8 288H32C14.33 288 .0016 273.7 .0016 256S14.33 224 32 224h306.8l-105.4-105.4c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l160 160C451.1 245.9 451.1 266.1 438.6 278.6z"
|
|
65
|
+
/>
|
|
66
|
+
</svg>
|
|
67
|
+
</a>
|
|
68
|
+
<br />
|
|
69
|
+
<a
|
|
70
|
+
className="no-underline text-brand font-brand font-bold inline-flex flex-row items-center"
|
|
71
|
+
href="/player"
|
|
72
|
+
>
|
|
73
|
+
Remotion Player{' '}
|
|
74
|
+
<svg
|
|
75
|
+
style={icon}
|
|
76
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
77
|
+
viewBox="0 0 448 512"
|
|
78
|
+
>
|
|
79
|
+
<path
|
|
80
|
+
fill="currentColor"
|
|
81
|
+
d="M438.6 278.6l-160 160C272.4 444.9 264.2 448 256 448s-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L338.8 288H32C14.33 288 .0016 273.7 .0016 256S14.33 224 32 224h306.8l-105.4-105.4c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l160 160C451.1 245.9 451.1 266.1 438.6 278.6z"
|
|
82
|
+
/>
|
|
83
|
+
</svg>
|
|
84
|
+
</a>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
};
|