@remotion/promo-pages 5.0.0-canary → 5.0.0-canary.3
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/dist/Homepage.js +1 -1
- package/dist/homepage/Pricing.js +1 -1
- package/package.json +15 -12
- package/.turbo/turbo-make.log +0 -8
- package/bundle.ts +0 -38
- package/eslint.config.mjs +0 -7
- package/index.html +0 -13
- package/public/fire.mp3 +0 -0
- package/public/img/cluster.png +0 -0
- package/public/img/code-sample-new.png +0 -0
- package/public/img/freelancers/alex.jpeg +0 -0
- package/public/img/freelancers/antoine.jpeg +0 -0
- package/public/img/freelancers/ayush.png +0 -0
- package/public/img/freelancers/benjamin.jpeg +0 -0
- package/public/img/freelancers/default.png +0 -0
- package/public/img/freelancers/florent.jpeg +0 -0
- package/public/img/freelancers/karel.jpeg +0 -0
- package/public/img/freelancers/lorenzo.jpeg +0 -0
- package/public/img/freelancers/mickael.jpeg +0 -0
- package/public/img/freelancers/mohit.jpeg +0 -0
- package/public/img/freelancers/pramod.jpg +0 -0
- package/public/img/freelancers/pranav.jpg +0 -0
- package/public/img/freelancers/rahul.png +0 -0
- package/public/img/freelancers/ray.jpeg +0 -0
- package/public/img/freelancers/stephen.png +0 -0
- package/public/img/freelancers/umungo.png +0 -0
- package/public/img/freelancers/yehor.jpeg +0 -0
- package/public/img/gt-planar-black.woff2 +0 -0
- package/public/img/gt-planar-bold.woff2 +0 -0
- package/public/img/gt-planar-medium.woff2 +0 -0
- package/public/img/gt-planar-regular.woff2 +0 -0
- package/public/img/logo-small.png +0 -0
- package/public/img/mp4.png +0 -0
- package/public/img/player-demo.mp4 +0 -0
- package/public/img/player-example-dark.png +0 -0
- package/public/img/player-example.png +0 -0
- package/public/img/writeinreact.png +0 -0
- package/public/partyhorn.mp3 +0 -0
- package/public/sad.mp3 +0 -0
- package/src/cn.ts +0 -6
- package/src/components/Homepage.tsx +0 -88
- package/src/components/homepage/BackgroundAnimation.tsx +0 -108
- package/src/components/homepage/ChooseTemplate.tsx +0 -57
- package/src/components/homepage/CodeExample.tsx +0 -89
- package/src/components/homepage/CommunityStats.tsx +0 -54
- package/src/components/homepage/CommunityStatsItems.tsx +0 -304
- package/src/components/homepage/Counter.tsx +0 -110
- package/src/components/homepage/Demo/Card.tsx +0 -273
- package/src/components/homepage/Demo/Cards.tsx +0 -129
- package/src/components/homepage/Demo/Comp.tsx +0 -157
- package/src/components/homepage/Demo/CurrentCountry.tsx +0 -97
- package/src/components/homepage/Demo/DemoError.tsx +0 -18
- package/src/components/homepage/Demo/DemoErrorIcon.tsx +0 -32
- package/src/components/homepage/Demo/DemoRender.tsx +0 -166
- package/src/components/homepage/Demo/DigitWheel.tsx +0 -179
- package/src/components/homepage/Demo/DisplayedEmoji.tsx +0 -81
- package/src/components/homepage/Demo/DoneCheckmark.tsx +0 -39
- package/src/components/homepage/Demo/DownloadNudge.tsx +0 -62
- package/src/components/homepage/Demo/DragAndDropNudge.tsx +0 -57
- package/src/components/homepage/Demo/EmojiCard.tsx +0 -198
- package/src/components/homepage/Demo/Minus.tsx +0 -21
- package/src/components/homepage/Demo/PlayPauseButton.tsx +0 -66
- package/src/components/homepage/Demo/PlayerControls.tsx +0 -48
- package/src/components/homepage/Demo/PlayerSeekBar.tsx +0 -325
- package/src/components/homepage/Demo/PlayerVolume.tsx +0 -83
- package/src/components/homepage/Demo/Progress.tsx +0 -38
- package/src/components/homepage/Demo/Spinner.tsx +0 -60
- package/src/components/homepage/Demo/Switcher.tsx +0 -54
- package/src/components/homepage/Demo/Temperature.tsx +0 -44
- package/src/components/homepage/Demo/TemperatureNumber.tsx +0 -68
- package/src/components/homepage/Demo/ThemeNudge.tsx +0 -72
- package/src/components/homepage/Demo/TimeDisplay.tsx +0 -43
- package/src/components/homepage/Demo/TrendingRepos.tsx +0 -106
- package/src/components/homepage/Demo/icons.tsx +0 -114
- package/src/components/homepage/Demo/index.tsx +0 -158
- package/src/components/homepage/Demo/math.ts +0 -43
- package/src/components/homepage/Demo/types.ts +0 -6
- package/src/components/homepage/Editor.tsx +0 -67
- package/src/components/homepage/EvaluateRemotion.tsx +0 -92
- package/src/components/homepage/FreePricing.tsx +0 -295
- package/src/components/homepage/GetStartedStrip.tsx +0 -77
- package/src/components/homepage/GitHubButton.tsx +0 -23
- package/src/components/homepage/IconForTemplate.tsx +0 -154
- package/src/components/homepage/IfYouKnowReact.tsx +0 -29
- package/src/components/homepage/InfoTooltip.tsx +0 -25
- package/src/components/homepage/MoreTemplatesButton.tsx +0 -29
- package/src/components/homepage/MuxVideo.tsx +0 -68
- package/src/components/homepage/NewsletterButton.tsx +0 -88
- package/src/components/homepage/Pricing.tsx +0 -49
- package/src/components/homepage/PricingBulletPoint.tsx +0 -50
- package/src/components/homepage/RealMp4Videos.tsx +0 -50
- package/src/components/homepage/Spacer.tsx +0 -5
- package/src/components/homepage/TemplateIcon.tsx +0 -36
- package/src/components/homepage/TextInput.tsx +0 -62
- package/src/components/homepage/TrustedByBanner.tsx +0 -194
- package/src/components/homepage/VideoApps.tsx +0 -231
- package/src/components/homepage/VideoAppsShowcase.tsx +0 -276
- package/src/components/homepage/VideoAppsTitle.tsx +0 -24
- package/src/components/homepage/VideoPlayerWithControls.tsx +0 -188
- package/src/components/homepage/WriteInReact.tsx +0 -34
- package/src/components/homepage/YouAreHere.tsx +0 -30
- package/src/components/homepage/custom.css +0 -57
- package/src/components/homepage/layout/Button.tsx +0 -93
- package/src/components/homepage/layout/colors.ts +0 -17
- package/src/components/homepage/layout/use-color-mode.tsx +0 -44
- package/src/components/homepage/layout/use-el-size.ts +0 -51
- package/src/components/homepage/layout/use-mobile-layout.ts +0 -8
- package/src/components/homepage/video-player.css +0 -24
- package/src/components/icons/blank.tsx +0 -13
- package/src/components/icons/clone.tsx +0 -10
- package/src/components/icons/code-hike.tsx +0 -15
- package/src/components/icons/cubes.tsx +0 -13
- package/src/components/icons/js.tsx +0 -17
- package/src/components/icons/next.tsx +0 -64
- package/src/components/icons/overlay.tsx +0 -24
- package/src/components/icons/remix.tsx +0 -24
- package/src/components/icons/skia.tsx +0 -13
- package/src/components/icons/stargazer.tsx +0 -13
- package/src/components/icons/still.tsx +0 -13
- package/src/components/icons/tailwind.tsx +0 -22
- package/src/components/icons/tiktok.tsx +0 -13
- package/src/components/icons/ts.tsx +0 -18
- package/src/components/icons/tts.tsx +0 -13
- package/src/components/icons/undo.tsx +0 -11
- package/src/components/icons/waveform.tsx +0 -13
- package/src/fonts.css +0 -30
- package/src/index.css +0 -74
- package/src/main.tsx +0 -12
- package/tsconfig.json +0 -15
- package/vite.config.ts +0 -9
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import {Wheel} from './DigitWheel';
|
|
3
|
-
|
|
4
|
-
export const TemperatureNumber: React.FC<{
|
|
5
|
-
readonly theme: 'dark' | 'light';
|
|
6
|
-
readonly temperatureInCelsius: number;
|
|
7
|
-
}> = ({theme, temperatureInCelsius}) => {
|
|
8
|
-
const temperatureInFahrenheit = (temperatureInCelsius * 9) / 5 + 32;
|
|
9
|
-
|
|
10
|
-
const celsiusDegree = Math.abs(temperatureInCelsius);
|
|
11
|
-
const fahrenheitDegree = Math.abs(temperatureInFahrenheit);
|
|
12
|
-
|
|
13
|
-
const paddedCelsiusDegree = String(celsiusDegree)
|
|
14
|
-
.padStart(fahrenheitDegree.toFixed(0).length, '0')
|
|
15
|
-
.split('');
|
|
16
|
-
const paddedFahrenheitDegree = fahrenheitDegree
|
|
17
|
-
.toFixed(0)
|
|
18
|
-
.padStart(paddedCelsiusDegree.length, '0')
|
|
19
|
-
.split('');
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<div
|
|
23
|
-
style={{
|
|
24
|
-
lineHeight: 1.1,
|
|
25
|
-
fontFamily: 'GTPlanar',
|
|
26
|
-
textAlign: 'center',
|
|
27
|
-
fontWeight: 'bold',
|
|
28
|
-
fontSize: 60,
|
|
29
|
-
color: theme === 'dark' ? 'white' : 'black',
|
|
30
|
-
fontVariantNumeric: 'tabular-nums',
|
|
31
|
-
display: 'flex',
|
|
32
|
-
flexDirection: 'row',
|
|
33
|
-
alignItems: 'center',
|
|
34
|
-
}}
|
|
35
|
-
>
|
|
36
|
-
{paddedCelsiusDegree.map((digit, i) => (
|
|
37
|
-
<Wheel
|
|
38
|
-
// eslint-disable-next-line react/no-array-index-key
|
|
39
|
-
key={i}
|
|
40
|
-
delay={i * 4}
|
|
41
|
-
renderDigit={(_i) => 9 - _i}
|
|
42
|
-
digits={[
|
|
43
|
-
Number(paddedFahrenheitDegree[i]),
|
|
44
|
-
Number(digit),
|
|
45
|
-
Number(paddedFahrenheitDegree[i]),
|
|
46
|
-
]}
|
|
47
|
-
isNegative={[
|
|
48
|
-
temperatureInFahrenheit < 0,
|
|
49
|
-
temperatureInCelsius < 0,
|
|
50
|
-
temperatureInFahrenheit < 0,
|
|
51
|
-
]}
|
|
52
|
-
isLeadingDigit={i === 0}
|
|
53
|
-
/>
|
|
54
|
-
))}
|
|
55
|
-
<div style={{width: 8}} />
|
|
56
|
-
°
|
|
57
|
-
<Wheel
|
|
58
|
-
delay={paddedCelsiusDegree.length * 4 - 2}
|
|
59
|
-
digits={[0, 1, 0]}
|
|
60
|
-
renderDigit={(_i) =>
|
|
61
|
-
_i % 2 === 0 ? 'C' : <span style={{marginLeft: -5}}>F</span>
|
|
62
|
-
}
|
|
63
|
-
isLeadingDigit={false}
|
|
64
|
-
isNegative={[false, false, false]}
|
|
65
|
-
/>
|
|
66
|
-
</div>
|
|
67
|
-
);
|
|
68
|
-
};
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import {FONTS} from '../layout/colors';
|
|
3
|
-
import {useColorMode} from '../layout/use-color-mode';
|
|
4
|
-
|
|
5
|
-
const origWidth = 21;
|
|
6
|
-
const scale = 0.4;
|
|
7
|
-
|
|
8
|
-
export const Icon: React.FC = () => {
|
|
9
|
-
return (
|
|
10
|
-
<svg
|
|
11
|
-
style={{
|
|
12
|
-
width: origWidth * scale,
|
|
13
|
-
}}
|
|
14
|
-
viewBox="0 0 21 161"
|
|
15
|
-
fill="none"
|
|
16
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
17
|
-
>
|
|
18
|
-
<path
|
|
19
|
-
d="M5 5C23 59.5 14.5 120.5 5.00005 156"
|
|
20
|
-
stroke="currentColor"
|
|
21
|
-
strokeWidth="8"
|
|
22
|
-
strokeLinecap="round"
|
|
23
|
-
/>
|
|
24
|
-
</svg>
|
|
25
|
-
);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export const ThemeNudge: React.FC = () => {
|
|
29
|
-
const {colorMode, setColorMode} = useColorMode();
|
|
30
|
-
|
|
31
|
-
const toggleTheme: React.MouseEventHandler = React.useCallback(
|
|
32
|
-
(e) => {
|
|
33
|
-
e.preventDefault();
|
|
34
|
-
setColorMode(colorMode === 'dark' ? 'light' : 'dark');
|
|
35
|
-
},
|
|
36
|
-
[colorMode, setColorMode],
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
return (
|
|
40
|
-
<div
|
|
41
|
-
style={{
|
|
42
|
-
flexDirection: 'row',
|
|
43
|
-
display: 'flex',
|
|
44
|
-
justifyContent: 'flex-start',
|
|
45
|
-
paddingBottom: 5,
|
|
46
|
-
textAlign: 'right',
|
|
47
|
-
position: 'absolute',
|
|
48
|
-
right: 0,
|
|
49
|
-
}}
|
|
50
|
-
>
|
|
51
|
-
<div>
|
|
52
|
-
<div
|
|
53
|
-
style={{
|
|
54
|
-
fontFamily: FONTS.GTPLANAR,
|
|
55
|
-
fontSize: 15,
|
|
56
|
-
width: 280,
|
|
57
|
-
paddingBottom: 8,
|
|
58
|
-
marginLeft: -15,
|
|
59
|
-
textWrap: 'balance',
|
|
60
|
-
marginTop: 5,
|
|
61
|
-
}}
|
|
62
|
-
>
|
|
63
|
-
<a href="#" onClick={toggleTheme} className="bluelink">
|
|
64
|
-
Switch to {colorMode === 'dark' ? 'light' : 'dark'} mode
|
|
65
|
-
</a>{' '}
|
|
66
|
-
and see the video adjust!{' '}
|
|
67
|
-
</div>
|
|
68
|
-
<Icon />
|
|
69
|
-
</div>
|
|
70
|
-
</div>
|
|
71
|
-
);
|
|
72
|
-
};
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type {PlayerRef} from '@remotion/player';
|
|
2
|
-
import React, {useEffect} from 'react';
|
|
3
|
-
|
|
4
|
-
const formatTime = (timeInSeconds: number) => {
|
|
5
|
-
const minutes = Math.floor(timeInSeconds / 60);
|
|
6
|
-
const seconds = Math.floor(timeInSeconds - minutes * 60);
|
|
7
|
-
return `${String(minutes)}:${String(seconds).padStart(2, '0')}`;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export const TimeDisplay: React.FC<{
|
|
11
|
-
readonly fps: number;
|
|
12
|
-
readonly playerRef: React.RefObject<PlayerRef | null>;
|
|
13
|
-
}> = ({fps, playerRef}) => {
|
|
14
|
-
const [time, setTime] = React.useState(0);
|
|
15
|
-
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
const {current} = playerRef;
|
|
18
|
-
if (!current) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const onTimeUpdate = () => {
|
|
23
|
-
setTime(current.getCurrentFrame());
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
current.addEventListener('frameupdate', onTimeUpdate);
|
|
27
|
-
|
|
28
|
-
return () => {
|
|
29
|
-
current.removeEventListener('frameupdate', onTimeUpdate);
|
|
30
|
-
};
|
|
31
|
-
}, [playerRef]);
|
|
32
|
-
|
|
33
|
-
return (
|
|
34
|
-
<div
|
|
35
|
-
style={{
|
|
36
|
-
fontSize: 16,
|
|
37
|
-
fontVariantNumeric: 'tabular-nums',
|
|
38
|
-
}}
|
|
39
|
-
>
|
|
40
|
-
<span>{formatTime(time / fps)}</span>
|
|
41
|
-
</div>
|
|
42
|
-
);
|
|
43
|
-
};
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import React, {useMemo} from 'react';
|
|
2
|
-
import {AbsoluteFill, spring, useCurrentFrame, useVideoConfig} from 'remotion';
|
|
3
|
-
import type {RemoteData} from './Comp';
|
|
4
|
-
|
|
5
|
-
const TrendingRepoItem: React.FC<{
|
|
6
|
-
readonly repo: string;
|
|
7
|
-
readonly theme: 'dark' | 'light';
|
|
8
|
-
readonly number: number;
|
|
9
|
-
}> = ({repo, theme, number}) => {
|
|
10
|
-
const frame = useCurrentFrame();
|
|
11
|
-
const {fps} = useVideoConfig();
|
|
12
|
-
|
|
13
|
-
const progress = spring({
|
|
14
|
-
fps,
|
|
15
|
-
frame,
|
|
16
|
-
config: {
|
|
17
|
-
damping: 200,
|
|
18
|
-
},
|
|
19
|
-
delay: number * 10 + 20,
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
const item: React.CSSProperties = useMemo(() => {
|
|
23
|
-
return {
|
|
24
|
-
lineHeight: 1.1,
|
|
25
|
-
fontFamily: 'GTPlanar',
|
|
26
|
-
fontWeight: '500',
|
|
27
|
-
color: theme === 'dark' ? 'white' : 'black',
|
|
28
|
-
fontFeatureSettings: "'ss03' 1",
|
|
29
|
-
opacity: progress,
|
|
30
|
-
};
|
|
31
|
-
}, [progress, theme]);
|
|
32
|
-
|
|
33
|
-
return (
|
|
34
|
-
<div style={item}>
|
|
35
|
-
{number}. {repo}
|
|
36
|
-
</div>
|
|
37
|
-
);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export const TrendingRepos: React.FC<{
|
|
41
|
-
readonly theme: 'dark' | 'light';
|
|
42
|
-
readonly trending: RemoteData | null;
|
|
43
|
-
}> = ({theme, trending}) => {
|
|
44
|
-
const fill = theme === 'light' ? '#666' : '#999';
|
|
45
|
-
const frame = useCurrentFrame();
|
|
46
|
-
const {fps} = useVideoConfig();
|
|
47
|
-
|
|
48
|
-
const progress1 = spring({
|
|
49
|
-
fps,
|
|
50
|
-
frame,
|
|
51
|
-
config: {
|
|
52
|
-
damping: 200,
|
|
53
|
-
},
|
|
54
|
-
delay: 0,
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
if (trending === null) {
|
|
58
|
-
return null;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return (
|
|
62
|
-
<AbsoluteFill>
|
|
63
|
-
<AbsoluteFill
|
|
64
|
-
style={{
|
|
65
|
-
justifyContent: 'center',
|
|
66
|
-
paddingLeft: 20,
|
|
67
|
-
paddingRight: 20,
|
|
68
|
-
}}
|
|
69
|
-
>
|
|
70
|
-
<div>
|
|
71
|
-
<div
|
|
72
|
-
style={{
|
|
73
|
-
color: fill,
|
|
74
|
-
fontFamily: 'GTPlanar',
|
|
75
|
-
fontWeight: '500',
|
|
76
|
-
fontSize: 12,
|
|
77
|
-
opacity: progress1,
|
|
78
|
-
}}
|
|
79
|
-
>
|
|
80
|
-
{new Intl.DateTimeFormat('en-US', {
|
|
81
|
-
weekday: 'long',
|
|
82
|
-
month: 'long',
|
|
83
|
-
day: 'numeric',
|
|
84
|
-
}).format(new Date(trending.date))}
|
|
85
|
-
</div>
|
|
86
|
-
<div
|
|
87
|
-
style={{
|
|
88
|
-
color: '#0b84f3',
|
|
89
|
-
fontFamily: 'GTPlanar',
|
|
90
|
-
fontWeight: '500',
|
|
91
|
-
fontSize: 16,
|
|
92
|
-
marginBottom: 15,
|
|
93
|
-
opacity: progress1,
|
|
94
|
-
lineHeight: 1,
|
|
95
|
-
}}
|
|
96
|
-
>
|
|
97
|
-
Trending repositories
|
|
98
|
-
</div>
|
|
99
|
-
<TrendingRepoItem number={1} repo={trending.repos[0]} theme={theme} />
|
|
100
|
-
<TrendingRepoItem number={2} repo={trending.repos[1]} theme={theme} />
|
|
101
|
-
<TrendingRepoItem number={3} repo={trending.repos[2]} theme={theme} />
|
|
102
|
-
</div>
|
|
103
|
-
</AbsoluteFill>
|
|
104
|
-
</AbsoluteFill>
|
|
105
|
-
);
|
|
106
|
-
};
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import type {SVGProps} from 'react';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import {RED} from '../layout/colors';
|
|
4
|
-
|
|
5
|
-
export const IconLeft: React.FC<SVGProps<SVGSVGElement>> = (props) => (
|
|
6
|
-
<svg viewBox="0 0 320 512" {...props}>
|
|
7
|
-
<path
|
|
8
|
-
fill="currentColor"
|
|
9
|
-
d="M34.52 239.03L228.87 44.69c9.37-9.37 24.57-9.37 33.94 0l22.67 22.67c9.36 9.36 9.37 24.52.04 33.9L131.49 256l154.02 154.75c9.34 9.38 9.32 24.54-.04 33.9l-22.67 22.67c-9.37 9.37-24.57 9.37-33.94 0L34.52 272.97c-9.37-9.37-9.37-24.57 0-33.94z"
|
|
10
|
-
/>
|
|
11
|
-
</svg>
|
|
12
|
-
);
|
|
13
|
-
export const IconRight: React.FC<SVGProps<SVGSVGElement>> = (props) => (
|
|
14
|
-
<svg viewBox="0 0 320 512" {...props}>
|
|
15
|
-
<path
|
|
16
|
-
fill="currentColor"
|
|
17
|
-
d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"
|
|
18
|
-
/>
|
|
19
|
-
</svg>
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
export const CancelIcon: React.FC<SVGProps<SVGSVGElement>> = (props) => {
|
|
23
|
-
return (
|
|
24
|
-
<svg
|
|
25
|
-
aria-hidden="true"
|
|
26
|
-
focusable="false"
|
|
27
|
-
data-prefix="fas"
|
|
28
|
-
data-icon="times"
|
|
29
|
-
className="svg-inline--fa fa-times fa-w-11"
|
|
30
|
-
role="img"
|
|
31
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
32
|
-
viewBox="0 0 352 512"
|
|
33
|
-
{...props}
|
|
34
|
-
>
|
|
35
|
-
<path
|
|
36
|
-
fill="currentColor"
|
|
37
|
-
d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"
|
|
38
|
-
/>
|
|
39
|
-
</svg>
|
|
40
|
-
);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export const PausedIcon: React.FC<SVGProps<SVGSVGElement>> = (props) => {
|
|
44
|
-
return (
|
|
45
|
-
<svg
|
|
46
|
-
aria-hidden="true"
|
|
47
|
-
focusable="false"
|
|
48
|
-
data-prefix="fas"
|
|
49
|
-
data-icon="play"
|
|
50
|
-
className="svg-inline--fa fa-play fa-w-14"
|
|
51
|
-
role="img"
|
|
52
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
53
|
-
viewBox="0 0 448 512"
|
|
54
|
-
{...props}
|
|
55
|
-
>
|
|
56
|
-
<path
|
|
57
|
-
fill="currentColor"
|
|
58
|
-
d="M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z"
|
|
59
|
-
/>
|
|
60
|
-
</svg>
|
|
61
|
-
);
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
export const PlayingIcon: React.FC<SVGProps<SVGSVGElement>> = (props) => {
|
|
65
|
-
return (
|
|
66
|
-
<svg
|
|
67
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
68
|
-
viewBox="0 0 320 512"
|
|
69
|
-
fill="currentColor"
|
|
70
|
-
{...props}
|
|
71
|
-
>
|
|
72
|
-
<path d="M48 64C21.5 64 0 85.5 0 112L0 400c0 26.5 21.5 48 48 48l32 0c26.5 0 48-21.5 48-48l0-288c0-26.5-21.5-48-48-48L48 64zm192 0c-26.5 0-48 21.5-48 48l0 288c0 26.5 21.5 48 48 48l32 0c26.5 0 48-21.5 48-48l0-288c0-26.5-21.5-48-48-48l-32 0z" />
|
|
73
|
-
</svg>
|
|
74
|
-
);
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export const FullscreenIcon: React.FC<SVGProps<SVGSVGElement>> = (props) => {
|
|
78
|
-
return (
|
|
79
|
-
<svg
|
|
80
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
81
|
-
viewBox="0 0 448 512"
|
|
82
|
-
fill="currentColor"
|
|
83
|
-
{...props}
|
|
84
|
-
>
|
|
85
|
-
<path d="M32 32C14.3 32 0 46.3 0 64l0 96c0 17.7 14.3 32 32 32s32-14.3 32-32l0-64 64 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L32 32zM64 352c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 96c0 17.7 14.3 32 32 32l96 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-64 0 0-64zM320 32c-17.7 0-32 14.3-32 32s14.3 32 32 32l64 0 0 64c0 17.7 14.3 32 32 32s32-14.3 32-32l0-96c0-17.7-14.3-32-32-32l-96 0zM448 352c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 64-64 0c-17.7 0-32 14.3-32 32s14.3 32 32 32l96 0c17.7 0 32-14.3 32-32l0-96z" />
|
|
86
|
-
</svg>
|
|
87
|
-
);
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
export const NotMutedIcon: React.FC<SVGProps<SVGSVGElement>> = (props) => {
|
|
91
|
-
return (
|
|
92
|
-
<svg
|
|
93
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
94
|
-
{...props}
|
|
95
|
-
viewBox="0 0 640 512"
|
|
96
|
-
fill="currentColor"
|
|
97
|
-
>
|
|
98
|
-
<path d="M32 160l0 192 128 0L304 480l48 0 0-448-48 0L160 160 32 160zM441.6 332.8C464.9 315.3 480 287.4 480 256s-15.1-59.3-38.4-76.8l-28.8 38.4c11.7 8.8 19.2 22.7 19.2 38.4s-7.5 29.6-19.2 38.4l28.8 38.4zm57.6 76.8c46.6-35 76.8-90.8 76.8-153.6s-30.2-118.6-76.8-153.6l-28.8 38.4c35 26.3 57.6 68.1 57.6 115.2s-22.6 88.9-57.6 115.2l28.8 38.4z" />
|
|
99
|
-
</svg>
|
|
100
|
-
);
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
export const IsMutedIcon: React.FC<SVGProps<SVGSVGElement>> = (props) => {
|
|
104
|
-
return (
|
|
105
|
-
<svg
|
|
106
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
107
|
-
{...props}
|
|
108
|
-
viewBox="0 0 640 512"
|
|
109
|
-
fill={RED}
|
|
110
|
-
>
|
|
111
|
-
<path d="M48.4 14.8L29.4 .1 0 38l19 14.7L591.5 497.2l19 14.7L639.9 474l-19-14.7-95.1-73.8C557 351.3 576 305.9 576 256c0-62.8-30.2-118.6-76.8-153.6l-28.8 38.4c35 26.3 57.6 68.1 57.6 115.2c0 38.8-15.3 74-40.3 99.9l-38.2-29.7C468.3 308.7 480 283.7 480 256c0-31.4-15.1-59.3-38.4-76.8l-28.8 38.4c11.7 8.8 19.2 22.7 19.2 38.4s-7.5 29.6-19.2 38.4l5.9 7.9L352 250.5 352 32l-48 0L195.2 128.7 48.4 14.8zM352 373.3L81.2 160 32 160l0 192 128 0L304 480l48 0 0-106.7z" />
|
|
112
|
-
</svg>
|
|
113
|
-
);
|
|
114
|
-
};
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import type {PlayerRef} from '@remotion/player';
|
|
2
|
-
import {Player} from '@remotion/player';
|
|
3
|
-
import React, {
|
|
4
|
-
useCallback,
|
|
5
|
-
useEffect,
|
|
6
|
-
useMemo,
|
|
7
|
-
useRef,
|
|
8
|
-
useState,
|
|
9
|
-
type CSSProperties,
|
|
10
|
-
} from 'react';
|
|
11
|
-
|
|
12
|
-
import {PALETTE} from '../layout/colors';
|
|
13
|
-
import {useColorMode} from '../layout/use-color-mode';
|
|
14
|
-
import {SectionTitle} from '../VideoAppsTitle';
|
|
15
|
-
import {
|
|
16
|
-
getDataAndProps,
|
|
17
|
-
HomepageVideoComp,
|
|
18
|
-
type DemoPlayerProps,
|
|
19
|
-
type LocationAndTrending,
|
|
20
|
-
type RemoteData,
|
|
21
|
-
} from './Comp';
|
|
22
|
-
import {DemoError} from './DemoError';
|
|
23
|
-
import {RenderButton} from './DemoRender';
|
|
24
|
-
import {DownloadNudge} from './DownloadNudge';
|
|
25
|
-
import {DragAndDropNudge} from './DragAndDropNudge';
|
|
26
|
-
import {PlayerControls} from './PlayerControls';
|
|
27
|
-
import {ThemeNudge} from './ThemeNudge';
|
|
28
|
-
import type {Location} from './types';
|
|
29
|
-
|
|
30
|
-
const style: React.CSSProperties = {
|
|
31
|
-
width: '100%',
|
|
32
|
-
aspectRatio: '640 / 360',
|
|
33
|
-
borderBottom: `2px solid ${PALETTE.BOX_STROKE}`,
|
|
34
|
-
touchAction: 'none', // prevent page from scrolling when dragging children on mobile
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const playerWrapper: CSSProperties = {
|
|
38
|
-
border: `2px solid ${PALETTE.BOX_STROKE}`,
|
|
39
|
-
borderBottom: `4px solid ${PALETTE.BOX_STROKE}`,
|
|
40
|
-
borderRadius: 8,
|
|
41
|
-
width: '100%',
|
|
42
|
-
overflow: 'hidden',
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export const Demo: React.FC = () => {
|
|
46
|
-
const {colorMode} = useColorMode();
|
|
47
|
-
const [data, setData] = useState<LocationAndTrending | null>(null);
|
|
48
|
-
const ref = useRef<PlayerRef>(null);
|
|
49
|
-
|
|
50
|
-
const [isFullscreen, setIsFullscreen] = useState(false);
|
|
51
|
-
const [cardOrder, setCardOrder] = useState([0, 1, 2, 3]);
|
|
52
|
-
const [emojiIndex, setEmojiIndex] = useState<number>(0);
|
|
53
|
-
const [error, setError] = useState(false);
|
|
54
|
-
|
|
55
|
-
useEffect(() => {
|
|
56
|
-
getDataAndProps()
|
|
57
|
-
.then((d) => {
|
|
58
|
-
setData(d);
|
|
59
|
-
})
|
|
60
|
-
.catch((err) => {
|
|
61
|
-
// eslint-disable-next-line no-console
|
|
62
|
-
console.log(err);
|
|
63
|
-
setError(true);
|
|
64
|
-
});
|
|
65
|
-
}, []);
|
|
66
|
-
|
|
67
|
-
useEffect(() => {
|
|
68
|
-
const {current: playerRef} = ref;
|
|
69
|
-
if (!playerRef || !data) {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const onFullscreenChange = () => {
|
|
74
|
-
setIsFullscreen(playerRef.isFullscreen());
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
playerRef.addEventListener('fullscreenchange', onFullscreenChange);
|
|
78
|
-
|
|
79
|
-
return () => {
|
|
80
|
-
playerRef.removeEventListener('fullscreenchange', onFullscreenChange);
|
|
81
|
-
};
|
|
82
|
-
}, [data]);
|
|
83
|
-
|
|
84
|
-
const updateCardOrder = useCallback((newCardOrder: number[]) => {
|
|
85
|
-
setCardOrder(newCardOrder);
|
|
86
|
-
}, []);
|
|
87
|
-
|
|
88
|
-
const props: DemoPlayerProps = useMemo(() => {
|
|
89
|
-
return {
|
|
90
|
-
theme: colorMode,
|
|
91
|
-
onToggle: () => {
|
|
92
|
-
ref.current?.toggle();
|
|
93
|
-
},
|
|
94
|
-
cardOrder,
|
|
95
|
-
updateCardOrder,
|
|
96
|
-
location: data?.location ?? null,
|
|
97
|
-
trending: data?.trending ?? null,
|
|
98
|
-
onClickLeft: () => {
|
|
99
|
-
setEmojiIndex((e) => e - 1);
|
|
100
|
-
},
|
|
101
|
-
onClickRight: () => {
|
|
102
|
-
setEmojiIndex((e) => e + 1);
|
|
103
|
-
},
|
|
104
|
-
emojiIndex,
|
|
105
|
-
};
|
|
106
|
-
}, [cardOrder, emojiIndex, colorMode, data, updateCardOrder]);
|
|
107
|
-
|
|
108
|
-
const onError = useCallback(() => {
|
|
109
|
-
setError(true);
|
|
110
|
-
}, []);
|
|
111
|
-
|
|
112
|
-
return (
|
|
113
|
-
<div>
|
|
114
|
-
<br />
|
|
115
|
-
<br />
|
|
116
|
-
<SectionTitle>Demo</SectionTitle>
|
|
117
|
-
<div style={{height: 140, position: 'relative'}}>
|
|
118
|
-
<DragAndDropNudge />
|
|
119
|
-
<ThemeNudge />
|
|
120
|
-
</div>
|
|
121
|
-
<div style={playerWrapper}>
|
|
122
|
-
<Player
|
|
123
|
-
ref={ref}
|
|
124
|
-
component={HomepageVideoComp}
|
|
125
|
-
compositionWidth={640}
|
|
126
|
-
compositionHeight={360}
|
|
127
|
-
durationInFrames={120}
|
|
128
|
-
fps={30}
|
|
129
|
-
autoPlay
|
|
130
|
-
controls={isFullscreen}
|
|
131
|
-
clickToPlay={false}
|
|
132
|
-
style={style}
|
|
133
|
-
initiallyMuted
|
|
134
|
-
inputProps={props}
|
|
135
|
-
loop
|
|
136
|
-
/>
|
|
137
|
-
<PlayerControls playerRef={ref} durationInFrames={120} fps={30}>
|
|
138
|
-
<RenderButton
|
|
139
|
-
onError={onError}
|
|
140
|
-
renderData={
|
|
141
|
-
data
|
|
142
|
-
? {
|
|
143
|
-
cardOrder,
|
|
144
|
-
emojiIndex,
|
|
145
|
-
location: data.location as Location,
|
|
146
|
-
theme: colorMode,
|
|
147
|
-
trending: data.trending as RemoteData,
|
|
148
|
-
}
|
|
149
|
-
: null
|
|
150
|
-
}
|
|
151
|
-
/>
|
|
152
|
-
</PlayerControls>
|
|
153
|
-
</div>
|
|
154
|
-
{error ? <DemoError /> : null}
|
|
155
|
-
<DownloadNudge />
|
|
156
|
-
</div>
|
|
157
|
-
);
|
|
158
|
-
};
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
export type Position = {
|
|
2
|
-
x: number;
|
|
3
|
-
y: number;
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
export const paddingAndMargin = 20;
|
|
7
|
-
const height = 360;
|
|
8
|
-
const width = 640;
|
|
9
|
-
export const cardHeight = (height - paddingAndMargin * 3) / 2;
|
|
10
|
-
export const cardWidth = (width - paddingAndMargin * 3) / 2;
|
|
11
|
-
|
|
12
|
-
export const getPositionForIndex = (index: number): Position => {
|
|
13
|
-
const x =
|
|
14
|
-
index % 2 === 0 ? paddingAndMargin : cardWidth + paddingAndMargin * 2;
|
|
15
|
-
const y = index < 2 ? paddingAndMargin : cardHeight + paddingAndMargin * 2;
|
|
16
|
-
|
|
17
|
-
return {x, y};
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export const getInitialPositions = () => {
|
|
21
|
-
return new Array(4).fill(true).map((_, i) => getPositionForIndex(i));
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export const getIndexFromPosition = (clientX: number, clientY: number) => {
|
|
25
|
-
const left = clientX < cardWidth / 2 + paddingAndMargin;
|
|
26
|
-
const top = clientY < cardHeight / 2 + paddingAndMargin;
|
|
27
|
-
|
|
28
|
-
if (left && top) {
|
|
29
|
-
return 0;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (!left && top) {
|
|
33
|
-
return 1;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (left && !top) {
|
|
37
|
-
return 2;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (!left && !top) {
|
|
41
|
-
return 3;
|
|
42
|
-
}
|
|
43
|
-
};
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import React, {useCallback, useEffect, useRef, useState} from 'react';
|
|
2
|
-
|
|
3
|
-
export const LightningFastEditor: React.FC = () => {
|
|
4
|
-
const ref = useRef<HTMLDivElement>(null);
|
|
5
|
-
const videoRef = useRef<HTMLVideoElement>(null);
|
|
6
|
-
const [isIntersecting, setIsIntersecting] = useState(false);
|
|
7
|
-
|
|
8
|
-
const callback: IntersectionObserverCallback = useCallback((data) => {
|
|
9
|
-
const {isIntersecting: intersecting} = data[0];
|
|
10
|
-
setIsIntersecting(intersecting);
|
|
11
|
-
if (intersecting) {
|
|
12
|
-
videoRef.current?.play();
|
|
13
|
-
} else {
|
|
14
|
-
videoRef.current?.pause();
|
|
15
|
-
}
|
|
16
|
-
}, []);
|
|
17
|
-
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
const {current} = ref;
|
|
20
|
-
if (!current) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const observer = new IntersectionObserver(callback, {
|
|
25
|
-
root: null,
|
|
26
|
-
threshold: 0.2,
|
|
27
|
-
});
|
|
28
|
-
observer.observe(current);
|
|
29
|
-
|
|
30
|
-
return () => observer.unobserve(current);
|
|
31
|
-
}, [callback]);
|
|
32
|
-
return (
|
|
33
|
-
<div
|
|
34
|
-
ref={ref}
|
|
35
|
-
className={
|
|
36
|
-
'flex flex-col-reverse lg:flex-row justify-start lg:justify-end lg:text-right items-start lg:items-center'
|
|
37
|
-
}
|
|
38
|
-
>
|
|
39
|
-
<div>
|
|
40
|
-
<video
|
|
41
|
-
src="/img/player-demo.mp4"
|
|
42
|
-
autoPlay
|
|
43
|
-
muted
|
|
44
|
-
playsInline
|
|
45
|
-
loop
|
|
46
|
-
style={{
|
|
47
|
-
animationPlayState: isIntersecting ? 'running' : 'paused',
|
|
48
|
-
width: 500,
|
|
49
|
-
maxWidth: '100%',
|
|
50
|
-
borderRadius: 7,
|
|
51
|
-
overflow: 'hidden',
|
|
52
|
-
}}
|
|
53
|
-
/>
|
|
54
|
-
</div>
|
|
55
|
-
<div style={{flex: 1}}>
|
|
56
|
-
<h2 className={'fontbrand text-4xl'}>
|
|
57
|
-
Fast and <br /> <span className="text-brand">delightful</span> editing
|
|
58
|
-
</h2>
|
|
59
|
-
<p className="leading-relaxed">
|
|
60
|
-
Preview your video in the browser. <br />
|
|
61
|
-
Fast refresh while the video is playing. <br />
|
|
62
|
-
Scrub through the timeline to get every frame perfect.
|
|
63
|
-
</p>
|
|
64
|
-
</div>
|
|
65
|
-
</div>
|
|
66
|
-
);
|
|
67
|
-
};
|