@remotion/promo-pages 4.0.363 → 4.0.365

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.
Files changed (107) hide show
  1. package/dist/Homepage.js +26 -27
  2. package/dist/Users/jonathanburger/remotion/packages/promo-pages/dist/Homepage.js +26 -27
  3. package/package.json +10 -10
  4. package/.turbo/turbo-lint.log +0 -15
  5. package/.turbo/turbo-make.log +0 -5
  6. package/bundle.ts +0 -54
  7. package/eslint.config.mjs +0 -7
  8. package/server.ts +0 -26
  9. package/src/cn.ts +0 -6
  10. package/src/components/Homepage.tsx +0 -87
  11. package/src/components/TeamPicture.tsx +0 -11
  12. package/src/components/homepage/BackgroundAnimation.tsx +0 -108
  13. package/src/components/homepage/ChooseTemplate.tsx +0 -57
  14. package/src/components/homepage/CommunityStats.tsx +0 -54
  15. package/src/components/homepage/CommunityStatsItems.tsx +0 -304
  16. package/src/components/homepage/Counter.tsx +0 -120
  17. package/src/components/homepage/Demo/Card.tsx +0 -273
  18. package/src/components/homepage/Demo/Cards.tsx +0 -129
  19. package/src/components/homepage/Demo/Comp.tsx +0 -157
  20. package/src/components/homepage/Demo/CurrentCountry.tsx +0 -97
  21. package/src/components/homepage/Demo/DemoError.tsx +0 -18
  22. package/src/components/homepage/Demo/DemoErrorIcon.tsx +0 -32
  23. package/src/components/homepage/Demo/DemoRender.tsx +0 -166
  24. package/src/components/homepage/Demo/DigitWheel.tsx +0 -179
  25. package/src/components/homepage/Demo/DisplayedEmoji.tsx +0 -93
  26. package/src/components/homepage/Demo/DoneCheckmark.tsx +0 -39
  27. package/src/components/homepage/Demo/DownloadNudge.tsx +0 -62
  28. package/src/components/homepage/Demo/DragAndDropNudge.tsx +0 -57
  29. package/src/components/homepage/Demo/EmojiCard.tsx +0 -200
  30. package/src/components/homepage/Demo/Minus.tsx +0 -21
  31. package/src/components/homepage/Demo/PlayPauseButton.tsx +0 -66
  32. package/src/components/homepage/Demo/PlayerControls.tsx +0 -48
  33. package/src/components/homepage/Demo/PlayerSeekBar.tsx +0 -325
  34. package/src/components/homepage/Demo/PlayerVolume.tsx +0 -83
  35. package/src/components/homepage/Demo/Progress.tsx +0 -38
  36. package/src/components/homepage/Demo/Spinner.tsx +0 -60
  37. package/src/components/homepage/Demo/Switcher.tsx +0 -54
  38. package/src/components/homepage/Demo/Temperature.tsx +0 -44
  39. package/src/components/homepage/Demo/TemperatureNumber.tsx +0 -68
  40. package/src/components/homepage/Demo/ThemeNudge.tsx +0 -72
  41. package/src/components/homepage/Demo/TimeDisplay.tsx +0 -43
  42. package/src/components/homepage/Demo/TrendingRepos.tsx +0 -106
  43. package/src/components/homepage/Demo/icons.tsx +0 -114
  44. package/src/components/homepage/Demo/index.tsx +0 -158
  45. package/src/components/homepage/Demo/math.ts +0 -43
  46. package/src/components/homepage/Demo/types.ts +0 -6
  47. package/src/components/homepage/EditorStarterSection.tsx +0 -76
  48. package/src/components/homepage/EvaluateRemotion.tsx +0 -92
  49. package/src/components/homepage/FreePricing.tsx +0 -283
  50. package/src/components/homepage/GetStartedStrip.tsx +0 -77
  51. package/src/components/homepage/GitHubButton.tsx +0 -23
  52. package/src/components/homepage/IconForTemplate.tsx +0 -170
  53. package/src/components/homepage/IfYouKnowReact.tsx +0 -68
  54. package/src/components/homepage/InfoTooltip.tsx +0 -25
  55. package/src/components/homepage/MoreTemplatesButton.tsx +0 -29
  56. package/src/components/homepage/MoreVideoPowerSection.tsx +0 -95
  57. package/src/components/homepage/MuxVideo.tsx +0 -68
  58. package/src/components/homepage/NewsletterButton.tsx +0 -89
  59. package/src/components/homepage/ParameterizeAndEdit.tsx +0 -106
  60. package/src/components/homepage/Pricing.tsx +0 -49
  61. package/src/components/homepage/PricingBulletPoint.tsx +0 -50
  62. package/src/components/homepage/RealMp4Videos.tsx +0 -108
  63. package/src/components/homepage/Spacer.tsx +0 -5
  64. package/src/components/homepage/TemplateIcon.tsx +0 -36
  65. package/src/components/homepage/TextInput.tsx +0 -62
  66. package/src/components/homepage/TrustedByBanner.tsx +0 -145
  67. package/src/components/homepage/VideoApps.tsx +0 -231
  68. package/src/components/homepage/VideoAppsShowcase.tsx +0 -270
  69. package/src/components/homepage/VideoAppsTitle.tsx +0 -11
  70. package/src/components/homepage/VideoPlayerWithControls.tsx +0 -189
  71. package/src/components/homepage/WriteInReact.tsx +0 -34
  72. package/src/components/homepage/YouAreHere.tsx +0 -30
  73. package/src/components/homepage/layout/Button.tsx +0 -93
  74. package/src/components/homepage/layout/colors.ts +0 -17
  75. package/src/components/homepage/layout/use-color-mode.tsx +0 -44
  76. package/src/components/homepage/layout/use-el-size.ts +0 -51
  77. package/src/components/homepage/layout/use-mobile-layout.ts +0 -8
  78. package/src/components/homepage/video-player.css +0 -24
  79. package/src/components/icons/blank.tsx +0 -13
  80. package/src/components/icons/clone.tsx +0 -10
  81. package/src/components/icons/code-hike.tsx +0 -15
  82. package/src/components/icons/cubes.tsx +0 -13
  83. package/src/components/icons/js.tsx +0 -17
  84. package/src/components/icons/music.tsx +0 -9
  85. package/src/components/icons/next.tsx +0 -64
  86. package/src/components/icons/overlay.tsx +0 -24
  87. package/src/components/icons/recorder.tsx +0 -23
  88. package/src/components/icons/remix.tsx +0 -27
  89. package/src/components/icons/skia.tsx +0 -13
  90. package/src/components/icons/stargazer.tsx +0 -13
  91. package/src/components/icons/still.tsx +0 -13
  92. package/src/components/icons/tailwind.tsx +0 -22
  93. package/src/components/icons/tiktok.tsx +0 -13
  94. package/src/components/icons/ts.tsx +0 -18
  95. package/src/components/icons/tts.tsx +0 -13
  96. package/src/components/icons/undo.tsx +0 -11
  97. package/src/components/icons/waveform.tsx +0 -13
  98. package/src/components/team/TeamCards.tsx +0 -167
  99. package/src/components/team/TitleTeamCards.tsx +0 -22
  100. package/src/components/team.css +0 -22
  101. package/src/components/team.tsx +0 -51
  102. package/src/fonts.css +0 -30
  103. package/src/index.css +0 -140
  104. package/src/main.tsx +0 -12
  105. package/src/team.tsx +0 -12
  106. package/tsconfig.json +0 -11
  107. package/vite.config.ts +0 -9
@@ -1,200 +0,0 @@
1
- import type {EmojiName} from '@remotion/animated-emoji';
2
- import React, {
3
- forwardRef,
4
- useCallback,
5
- useEffect,
6
- useImperativeHandle,
7
- useRef,
8
- } from 'react';
9
- import {AbsoluteFill, useRemotionEnvironment} from 'remotion';
10
- import {DisplayedEmoji} from './DisplayedEmoji';
11
-
12
- export type EmojiCardRef = {
13
- onLeft: () => void;
14
- onRight: () => void;
15
- };
16
-
17
- type Transforms = [number, number, number];
18
-
19
- type Anim = {
20
- ref1: HTMLDivElement;
21
- ref2: HTMLDivElement;
22
- ref3: HTMLDivElement;
23
- transforms: Transforms;
24
- };
25
-
26
- const applyTransforms = ({ref1, ref2, ref3, transforms}: Anim) => {
27
- ref1.style.transform = `translateX(${transforms[0]}%)`;
28
- ref2.style.transform = `translateX(${transforms[1]}%)`;
29
- ref3.style.transform = `translateX(${transforms[2]}%)`;
30
- };
31
-
32
- const waitForRaq = async () => {
33
- await new Promise((resolve) => {
34
- requestAnimationFrame(resolve);
35
- });
36
- };
37
-
38
- const moveLeft = async ({ref1, ref2, ref3, transforms}: Anim) => {
39
- for (let i = 0; i < 20; i++) {
40
- for (const idx in transforms) {
41
- transforms[idx] -= 5;
42
- if (transforms[idx] <= -200) {
43
- transforms[idx] += 300;
44
- }
45
- }
46
-
47
- applyTransforms({ref1, ref2, ref3, transforms});
48
- await waitForRaq();
49
- }
50
- };
51
-
52
- const moveRight = async ({ref1, ref2, ref3, transforms}: Anim) => {
53
- for (let i = 0; i < 20; i++) {
54
- for (const idx in transforms) {
55
- transforms[idx] += 5;
56
- if (transforms[idx] >= 100) {
57
- transforms[idx] -= 300;
58
- }
59
- }
60
-
61
- applyTransforms({ref1, ref2, ref3, transforms});
62
- await waitForRaq();
63
- }
64
- };
65
-
66
- const emojiStyle: React.CSSProperties = {
67
- width: '100%',
68
- position: 'absolute',
69
- top: 'calc(50% - 50px)',
70
- };
71
-
72
- export type EmojiCardProps = {
73
- readonly emojiIndex: EmojiName;
74
- };
75
-
76
- const EmojiCardRefFn: React.ForwardRefRenderFunction<
77
- EmojiCardRef,
78
- EmojiCardProps
79
- > = ({emojiIndex}, ref) => {
80
- const ref1 = useRef<HTMLDivElement>(null);
81
- const ref2 = useRef<HTMLDivElement>(null);
82
- const ref3 = useRef<HTMLDivElement>(null);
83
- const transforms = useRef<Transforms>([-100, 0, 100]);
84
-
85
- const onLeft = useCallback(() => {
86
- if (!ref1.current || !ref2.current || !ref3.current) {
87
- return;
88
- }
89
-
90
- moveLeft({
91
- ref1: ref1.current,
92
- ref2: ref2.current,
93
- ref3: ref3.current,
94
- transforms: transforms.current,
95
- });
96
- }, []);
97
-
98
- const onRight = useCallback(() => {
99
- if (!ref1.current || !ref2.current || !ref3.current) {
100
- return;
101
- }
102
-
103
- moveRight({
104
- ref1: ref1.current,
105
- ref2: ref2.current,
106
- ref3: ref3.current,
107
- transforms: transforms.current,
108
- });
109
- }, []);
110
-
111
- useEffect(() => {
112
- if (!ref1.current || !ref2.current || !ref3.current) {
113
- return;
114
- }
115
-
116
- applyTransforms({
117
- ref1: ref1.current,
118
- ref2: ref2.current,
119
- ref3: ref3.current,
120
- transforms: transforms.current,
121
- });
122
- }, []);
123
-
124
- useImperativeHandle(ref, () => {
125
- return {
126
- onLeft,
127
- onRight,
128
- };
129
- }, [onLeft, onRight]);
130
-
131
- useEffect(() => {
132
- if (!ref1.current || !ref2.current || !ref3.current) {
133
- return;
134
- }
135
-
136
- applyTransforms({
137
- ref1: ref1.current,
138
- ref2: ref2.current,
139
- ref3: ref3.current,
140
- transforms: transforms.current,
141
- });
142
- }, []);
143
-
144
- const env = useRemotionEnvironment();
145
-
146
- return (
147
- <AbsoluteFill
148
- style={{
149
- justifyContent: 'center',
150
- alignItems: 'center',
151
- overflow: 'hidden',
152
- }}
153
- >
154
- <div
155
- style={{
156
- color: '#0b84f3',
157
- fontFamily: 'GTPlanar',
158
- fontWeight: '500',
159
- fontSize: 13,
160
- textAlign: 'center',
161
- position: 'absolute',
162
- marginTop: -90,
163
- }}
164
- >
165
- Choose an emoji
166
- </div>
167
- <div
168
- style={{
169
- position: 'absolute',
170
- width: '100%',
171
- display: 'flex',
172
- whiteSpace: 'nowrap',
173
- height: '100%',
174
- }}
175
- >
176
- {env.isRendering ? (
177
- <div style={emojiStyle}>
178
- <DisplayedEmoji emoji={emojiIndex} />
179
- </div>
180
- ) : (
181
- <>
182
- <div ref={ref1} style={emojiStyle}>
183
- <DisplayedEmoji emoji={'melting'} />
184
- </div>
185
- <div ref={ref2} style={emojiStyle}>
186
- <DisplayedEmoji emoji={'partying-face'} />
187
- </div>
188
- <div ref={ref3} style={emojiStyle}>
189
- <DisplayedEmoji emoji={'fire'} />
190
- </div>
191
- </>
192
- )}
193
- </div>
194
- </AbsoluteFill>
195
- );
196
- };
197
-
198
- export const EmojiCard = forwardRef<EmojiCardRef, EmojiCardProps>(
199
- EmojiCardRefFn,
200
- );
@@ -1,21 +0,0 @@
1
- import React from 'react';
2
-
3
- export const Minus: React.FC<{
4
- readonly leftOffset: number;
5
- readonly minusSignOpacity: number;
6
- }> = ({leftOffset, minusSignOpacity}) => {
7
- return (
8
- <div
9
- style={{
10
- position: 'relative',
11
- marginLeft: -40 - leftOffset,
12
- marginTop: 5,
13
- width: 40,
14
- opacity: minusSignOpacity,
15
- textAlign: 'right',
16
- }}
17
- >
18
- -
19
- </div>
20
- );
21
- };
@@ -1,66 +0,0 @@
1
- import type {PlayerRef} from '@remotion/player';
2
- import React, {useCallback, useEffect} from 'react';
3
- import {PALETTE} from '../layout/colors';
4
- import {PausedIcon, PlayingIcon} from './icons';
5
-
6
- const playerButtonStyle: React.CSSProperties = {
7
- appearance: 'none',
8
- border: 'none',
9
- borderRadius: 0,
10
- background: 'none',
11
- display: 'flex',
12
- justifyContent: 'center',
13
- alignItems: 'center',
14
- paddingRight: 20,
15
- paddingLeft: 20,
16
- cursor: 'pointer',
17
- height: 50,
18
- color: PALETTE.TEXT_COLOR,
19
- };
20
-
21
- export const PlayPauseButton: React.FC<{
22
- readonly playerRef: React.RefObject<PlayerRef | null>;
23
- }> = ({playerRef}) => {
24
- const [playing, setPlaying] = React.useState(true);
25
-
26
- useEffect(() => {
27
- const {current} = playerRef;
28
- if (!current) {
29
- return;
30
- }
31
-
32
- const onPlay = () => {
33
- setPlaying(true);
34
- };
35
-
36
- const onPause = () => {
37
- setPlaying(false);
38
- };
39
-
40
- current.addEventListener('play', onPlay);
41
- current.addEventListener('pause', onPause);
42
-
43
- return () => {
44
- current.removeEventListener('play', onPlay);
45
- current.removeEventListener('pause', onPause);
46
- };
47
- }, [playerRef]);
48
-
49
- const onToggle = useCallback(() => {
50
- playerRef.current?.toggle();
51
- }, [playerRef]);
52
-
53
- const playPauseIconStyle: React.CSSProperties = {
54
- width: 15,
55
- };
56
-
57
- return (
58
- <button type="button" style={playerButtonStyle} onClick={onToggle}>
59
- {playing ? (
60
- <PlayingIcon style={playPauseIconStyle} />
61
- ) : (
62
- <PausedIcon style={playPauseIconStyle} />
63
- )}
64
- </button>
65
- );
66
- };
@@ -1,48 +0,0 @@
1
- import type {PlayerRef} from '@remotion/player';
2
- import React from 'react';
3
- import {PALETTE} from '../layout/colors';
4
- import {PlayerSeekBar} from './PlayerSeekBar';
5
- import {PlayerVolume} from './PlayerVolume';
6
- import {PlayPauseButton} from './PlayPauseButton';
7
- import {TimeDisplay} from './TimeDisplay';
8
-
9
- const Separator: React.FC = () => {
10
- return (
11
- <div
12
- style={{
13
- borderRight: `2px solid ${PALETTE.BOX_STROKE}`,
14
- height: 50,
15
- }}
16
- />
17
- );
18
- };
19
-
20
- export const PlayerControls: React.FC<{
21
- readonly playerRef: React.RefObject<PlayerRef | null>;
22
- readonly durationInFrames: number;
23
- readonly fps: number;
24
- readonly children: React.ReactNode;
25
- }> = ({playerRef, durationInFrames, fps, children}) => {
26
- return (
27
- <div className={'flex flex-row items-center bg-pane'}>
28
- <PlayPauseButton playerRef={playerRef} />
29
- <Separator />
30
- <PlayerVolume playerRef={playerRef} />
31
- <Separator />
32
- <div style={{width: 15}} />
33
- <TimeDisplay playerRef={playerRef} fps={fps} />
34
- <div style={{width: 15}} />
35
- <PlayerSeekBar
36
- durationInFrames={durationInFrames}
37
- playerRef={playerRef}
38
- inFrame={null}
39
- outFrame={null}
40
- onSeekEnd={() => undefined}
41
- onSeekStart={() => undefined}
42
- />
43
- <div style={{width: 20}} />
44
- <Separator />
45
- {children}
46
- </div>
47
- );
48
- };
@@ -1,325 +0,0 @@
1
- import type {PlayerRef} from '@remotion/player';
2
- import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
3
- import {interpolate} from 'remotion';
4
- import {useElementSize} from '../layout/use-el-size';
5
-
6
- const getFrameFromX = (
7
- clientX: number,
8
- durationInFrames: number,
9
- width: number,
10
- ) => {
11
- const pos = clientX;
12
- const frame = Math.round(
13
- interpolate(pos, [0, width], [0, durationInFrames - 1], {
14
- extrapolateLeft: 'clamp',
15
- extrapolateRight: 'clamp',
16
- }),
17
- );
18
- return frame;
19
- };
20
-
21
- const BAR_HEIGHT = 5;
22
- const KNOB_SIZE = 12;
23
- const VERTICAL_PADDING = 4;
24
-
25
- const containerStyle: React.CSSProperties = {
26
- userSelect: 'none',
27
- WebkitUserSelect: 'none',
28
- paddingTop: VERTICAL_PADDING,
29
- paddingBottom: VERTICAL_PADDING,
30
- boxSizing: 'border-box',
31
- cursor: 'pointer',
32
- position: 'relative',
33
- touchAction: 'none',
34
- flex: 1,
35
- };
36
-
37
- const barBackground: React.CSSProperties = {
38
- height: BAR_HEIGHT,
39
- backgroundColor: 'rgba(0, 0, 0, 0.25)',
40
- width: '100%',
41
- borderRadius: BAR_HEIGHT / 2,
42
- };
43
-
44
- const findBodyInWhichDivIsLocated = (div: HTMLElement) => {
45
- let current = div;
46
-
47
- while (current.parentElement) {
48
- current = current.parentElement;
49
- }
50
-
51
- return current;
52
- };
53
-
54
- export const useHoverState = (
55
- ref: React.RefObject<HTMLDivElement | null>,
56
- hideControlsWhenPointerDoesntMove: boolean | number,
57
- ) => {
58
- const [hovered, setHovered] = useState(false);
59
-
60
- useEffect(() => {
61
- const {current} = ref;
62
- if (!current) {
63
- return;
64
- }
65
-
66
- let hoverTimeout: Timer;
67
- const addHoverTimeout = () => {
68
- if (hideControlsWhenPointerDoesntMove) {
69
- clearTimeout(hoverTimeout);
70
- hoverTimeout = setTimeout(
71
- () => {
72
- setHovered(false);
73
- },
74
- hideControlsWhenPointerDoesntMove === true
75
- ? 3000
76
- : hideControlsWhenPointerDoesntMove,
77
- );
78
- }
79
- };
80
-
81
- const onHover = () => {
82
- setHovered(true);
83
- addHoverTimeout();
84
- };
85
-
86
- const onLeave = () => {
87
- setHovered(false);
88
- clearTimeout(hoverTimeout);
89
- };
90
-
91
- const onMove = () => {
92
- setHovered(true);
93
- addHoverTimeout();
94
- };
95
-
96
- current.addEventListener('mouseenter', onHover);
97
- current.addEventListener('mouseleave', onLeave);
98
- current.addEventListener('mousemove', onMove);
99
-
100
- return () => {
101
- current.removeEventListener('mouseenter', onHover);
102
- current.removeEventListener('mouseleave', onLeave);
103
- current.removeEventListener('mousemove', onMove);
104
- clearTimeout(hoverTimeout);
105
- };
106
- }, [hideControlsWhenPointerDoesntMove, ref]);
107
- return hovered;
108
- };
109
-
110
- export const PlayerSeekBar: React.FC<{
111
- readonly durationInFrames: number;
112
- readonly onSeekStart: () => void;
113
- readonly onSeekEnd: () => void;
114
- readonly inFrame: number | null;
115
- readonly outFrame: number | null;
116
- readonly playerRef: React.RefObject<PlayerRef | null>;
117
- }> = ({
118
- durationInFrames,
119
- onSeekEnd,
120
- onSeekStart,
121
- inFrame,
122
- outFrame,
123
- playerRef,
124
- }) => {
125
- const containerRef = useRef<HTMLDivElement>(null);
126
- const barHovered = useHoverState(containerRef, false);
127
- const size = useElementSize(containerRef.current);
128
- const [playing, setPlaying] = useState(false);
129
-
130
- const [frame, setFrame] = useState(0);
131
-
132
- useEffect(() => {
133
- const {current} = playerRef;
134
- if (!current) {
135
- return;
136
- }
137
-
138
- const onFrameUpdate = () => {
139
- setFrame(playerRef.current!.getCurrentFrame());
140
- };
141
-
142
- current.addEventListener('frameupdate', onFrameUpdate);
143
-
144
- return () => {
145
- current.removeEventListener('frameupdate', onFrameUpdate);
146
- };
147
- }, [playerRef]);
148
-
149
- useEffect(() => {
150
- const {current} = playerRef;
151
- if (!current) {
152
- return;
153
- }
154
-
155
- const onPlay = () => {
156
- setPlaying(true);
157
- };
158
-
159
- const onPause = () => {
160
- setPlaying(false);
161
- };
162
-
163
- current.addEventListener('play', onPlay);
164
- current.addEventListener('pause', onPause);
165
-
166
- return () => {
167
- current.removeEventListener('play', onPlay);
168
- current.removeEventListener('pause', onPause);
169
- };
170
- }, [playerRef]);
171
-
172
- const [dragging, setDragging] = useState<
173
- | {
174
- dragging: false;
175
- }
176
- | {
177
- dragging: true;
178
- wasPlaying: boolean;
179
- }
180
- >({
181
- dragging: false,
182
- });
183
-
184
- const width = size?.width ?? 0;
185
-
186
- const onPointerDown = useCallback(
187
- (e: React.PointerEvent<HTMLDivElement>) => {
188
- if (e.button !== 0) {
189
- return;
190
- }
191
-
192
- const posLeft = containerRef.current?.getBoundingClientRect()
193
- .left as number;
194
-
195
- const _frame = getFrameFromX(
196
- e.clientX - posLeft,
197
- durationInFrames,
198
- width,
199
- );
200
- playerRef.current!.pause();
201
- playerRef.current!.seekTo(_frame);
202
- setDragging({
203
- dragging: true,
204
- wasPlaying: playing,
205
- });
206
- onSeekStart();
207
- },
208
- [durationInFrames, width, playerRef, playing, onSeekStart],
209
- );
210
-
211
- const onPointerMove = useCallback(
212
- (e: PointerEvent) => {
213
- if (!size) {
214
- throw new Error('Player has no size');
215
- }
216
-
217
- if (!dragging.dragging) {
218
- return;
219
- }
220
-
221
- const posLeft = containerRef.current?.getBoundingClientRect()
222
- .left as number;
223
-
224
- const _frame = getFrameFromX(
225
- e.clientX - posLeft,
226
- durationInFrames,
227
- size.width,
228
- );
229
- playerRef.current!.seekTo(_frame);
230
- },
231
- [dragging.dragging, durationInFrames, playerRef, size],
232
- );
233
-
234
- const onPointerUp = useCallback(() => {
235
- setDragging({
236
- dragging: false,
237
- });
238
- if (!dragging.dragging) {
239
- return;
240
- }
241
-
242
- if (dragging.wasPlaying) {
243
- playerRef.current!.play();
244
- } else {
245
- playerRef.current!.pause();
246
- }
247
-
248
- onSeekEnd();
249
- }, [dragging, onSeekEnd, playerRef]);
250
-
251
- useEffect(() => {
252
- if (!dragging.dragging) {
253
- return;
254
- }
255
-
256
- const body = findBodyInWhichDivIsLocated(
257
- containerRef.current as HTMLElement,
258
- );
259
-
260
- body.addEventListener('pointermove', onPointerMove);
261
- body.addEventListener('pointerup', onPointerUp);
262
- return () => {
263
- body.removeEventListener('pointermove', onPointerMove);
264
- body.removeEventListener('pointerup', onPointerUp);
265
- };
266
- }, [dragging.dragging, onPointerMove, onPointerUp]);
267
-
268
- const knobStyle: React.CSSProperties = useMemo(() => {
269
- return {
270
- height: KNOB_SIZE,
271
- width: KNOB_SIZE,
272
- borderRadius: KNOB_SIZE / 2,
273
- position: 'absolute',
274
- top: VERTICAL_PADDING - KNOB_SIZE / 2 + 5 / 2,
275
- backgroundColor: 'var(--ifm-font-color-base)',
276
- left: Math.max(
277
- 0,
278
- (frame / Math.max(1, durationInFrames - 1)) * width - KNOB_SIZE / 2,
279
- ),
280
- outline: '2px solid var(--ifm-background-color)',
281
- opacity: Number(barHovered),
282
- transition: 'opacity 0.s ease',
283
- };
284
- }, [barHovered, durationInFrames, frame, width]);
285
-
286
- const fillStyle: React.CSSProperties = useMemo(() => {
287
- return {
288
- height: BAR_HEIGHT,
289
- backgroundColor: 'var(--ifm-font-color-base)',
290
- width: ((frame - (inFrame ?? 0)) / (durationInFrames - 1)) * 100 + '%',
291
- marginLeft: ((inFrame ?? 0) / (durationInFrames - 1)) * 100 + '%',
292
- borderRadius: BAR_HEIGHT / 2,
293
- };
294
- }, [durationInFrames, frame, inFrame]);
295
-
296
- const active: React.CSSProperties = useMemo(() => {
297
- return {
298
- height: BAR_HEIGHT,
299
- backgroundColor: 'var(--ifm-font-color-base)',
300
- opacity: 0.2,
301
- width:
302
- (((outFrame ?? durationInFrames - 1) - (inFrame ?? 0)) /
303
- (durationInFrames - 1)) *
304
- 100 +
305
- '%',
306
- marginLeft: ((inFrame ?? 0) / (durationInFrames - 1)) * 100 + '%',
307
- borderRadius: BAR_HEIGHT / 2,
308
- position: 'absolute',
309
- };
310
- }, [durationInFrames, inFrame, outFrame]);
311
-
312
- return (
313
- <div
314
- ref={containerRef}
315
- onPointerDown={onPointerDown}
316
- style={containerStyle}
317
- >
318
- <div style={barBackground}>
319
- <div style={active} />
320
- <div style={fillStyle} />
321
- </div>
322
- <div style={knobStyle} />
323
- </div>
324
- );
325
- };