egaki 0.6.0 → 0.7.1
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/CHANGELOG.md +145 -9
- package/dist/cli/cache-utils.d.ts +33 -0
- package/dist/cli/cache-utils.d.ts.map +1 -0
- package/dist/cli/cache-utils.js +157 -0
- package/dist/cli/cached-generate.d.ts +105 -0
- package/dist/cli/cached-generate.d.ts.map +1 -0
- package/dist/cli/cached-generate.js +208 -0
- package/dist/cli/cached-generate.test.d.ts +11 -0
- package/dist/cli/cached-generate.test.d.ts.map +1 -0
- package/dist/cli/cached-generate.test.js +431 -0
- package/dist/cli/cartesia-provider.d.ts +16 -0
- package/dist/cli/cartesia-provider.d.ts.map +1 -0
- package/dist/cli/cartesia-provider.js +184 -0
- package/dist/cli/chatgpt-auth.d.ts.map +1 -0
- package/dist/cli/cli.d.ts +4 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/{cli.js → cli/cli.js} +626 -600
- package/dist/cli/clone-generate.d.ts +26 -0
- package/dist/cli/clone-generate.d.ts.map +1 -0
- package/dist/cli/clone-generate.js +148 -0
- package/dist/cli/credentials.d.ts.map +1 -0
- package/dist/{credentials.js → cli/credentials.js} +20 -0
- package/dist/cli/elevenlabs-speech-provider.d.ts +26 -0
- package/dist/cli/elevenlabs-speech-provider.d.ts.map +1 -0
- package/dist/cli/elevenlabs-speech-provider.js +199 -0
- package/dist/cli/generate.d.ts +140 -0
- package/dist/cli/generate.d.ts.map +1 -0
- package/dist/cli/generate.js +604 -0
- package/dist/cli/generate.test.d.ts +2 -0
- package/dist/cli/generate.test.d.ts.map +1 -0
- package/dist/cli/generate.test.js +131 -0
- package/dist/cli/login.d.ts.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +7 -0
- package/dist/{model-catalog.d.ts → cli/model-catalog.d.ts} +6 -0
- package/dist/cli/model-catalog.d.ts.map +1 -0
- package/dist/{model-catalog.js → cli/model-catalog.js} +714 -4
- package/dist/{models.d.ts → cli/models.d.ts} +12 -5
- package/dist/cli/models.d.ts.map +1 -0
- package/dist/{models.js → cli/models.js} +58 -57
- package/dist/cli/open-browser.d.ts.map +1 -0
- package/dist/cli/openai-speech-provider.d.ts +3 -0
- package/dist/cli/openai-speech-provider.d.ts.map +1 -0
- package/dist/cli/openai-speech-provider.js +28 -0
- package/dist/cli/separation-generate.d.ts +34 -0
- package/dist/cli/separation-generate.d.ts.map +1 -0
- package/dist/cli/separation-generate.js +117 -0
- package/dist/cli/speech-catalog.d.ts +35 -0
- package/dist/cli/speech-catalog.d.ts.map +1 -0
- package/dist/cli/speech-catalog.js +195 -0
- package/dist/cli/speech-generate.d.ts +86 -0
- package/dist/cli/speech-generate.d.ts.map +1 -0
- package/dist/cli/speech-generate.js +156 -0
- package/dist/cli/speech-models.d.ts +8 -0
- package/dist/cli/speech-models.d.ts.map +1 -0
- package/dist/cli/speech-models.js +109 -0
- package/dist/cli/speech-provider.test.d.ts +2 -0
- package/dist/cli/speech-provider.test.d.ts.map +1 -0
- package/dist/cli/speech-provider.test.js +197 -0
- package/dist/cli/subscription.d.ts.map +1 -0
- package/dist/cli/transcription-catalog.d.ts +35 -0
- package/dist/cli/transcription-catalog.d.ts.map +1 -0
- package/dist/cli/transcription-catalog.js +192 -0
- package/dist/cli/transcription-generate.d.ts +62 -0
- package/dist/cli/transcription-generate.d.ts.map +1 -0
- package/dist/cli/transcription-generate.js +144 -0
- package/dist/cli/transcription-models.d.ts +9 -0
- package/dist/cli/transcription-models.d.ts.map +1 -0
- package/dist/cli/transcription-models.js +100 -0
- package/dist/cli/transcription-providers.d.ts +22 -0
- package/dist/cli/transcription-providers.d.ts.map +1 -0
- package/dist/cli/transcription-providers.js +290 -0
- package/dist/cli/video-model-catalog.d.ts.map +1 -0
- package/dist/cli/xai-auth.d.ts.map +1 -0
- package/dist/{xai-auth.js → cli/xai-auth.js} +1 -1
- package/dist/vite/angled-screen.d.ts +57 -0
- package/dist/vite/angled-screen.d.ts.map +1 -0
- package/dist/vite/angled-screen.js +115 -0
- package/dist/vite/app.d.ts +51 -0
- package/dist/vite/app.d.ts.map +1 -0
- package/dist/vite/app.js +150 -0
- package/dist/vite/bands-shader.d.ts +47 -0
- package/dist/vite/bands-shader.d.ts.map +1 -0
- package/dist/vite/bands-shader.js +267 -0
- package/dist/vite/code-block.d.ts +107 -0
- package/dist/vite/code-block.d.ts.map +1 -0
- package/dist/vite/code-block.js +641 -0
- package/dist/vite/components.d.ts +36 -0
- package/dist/vite/components.d.ts.map +1 -0
- package/dist/vite/components.js +113 -0
- package/dist/vite/dispersion-rings-shader.d.ts +44 -0
- package/dist/vite/dispersion-rings-shader.d.ts.map +1 -0
- package/dist/vite/dispersion-rings-shader.js +282 -0
- package/dist/vite/easing-curves.d.ts +129 -0
- package/dist/vite/easing-curves.d.ts.map +1 -0
- package/dist/vite/easing-curves.js +584 -0
- package/dist/vite/easing-curves.test.d.ts +2 -0
- package/dist/vite/easing-curves.test.d.ts.map +1 -0
- package/dist/vite/easing-curves.test.js +200 -0
- package/dist/vite/generated-media-client.d.ts +35 -0
- package/dist/vite/generated-media-client.d.ts.map +1 -0
- package/dist/vite/generated-media-client.js +76 -0
- package/dist/vite/keyframes.d.ts +129 -0
- package/dist/vite/keyframes.d.ts.map +1 -0
- package/dist/vite/keyframes.js +194 -0
- package/dist/vite/layout-editor.d.ts +45 -0
- package/dist/vite/layout-editor.d.ts.map +1 -0
- package/dist/vite/layout-editor.js +587 -0
- package/dist/vite/layout-transition.d.ts +136 -0
- package/dist/vite/layout-transition.d.ts.map +1 -0
- package/dist/vite/layout-transition.js +581 -0
- package/dist/vite/liquid-gradient-shader.d.ts +62 -0
- package/dist/vite/liquid-gradient-shader.d.ts.map +1 -0
- package/dist/vite/liquid-gradient-shader.js +413 -0
- package/dist/vite/mdx-client.d.ts +15 -0
- package/dist/vite/mdx-client.d.ts.map +1 -0
- package/dist/vite/mdx-client.js +265 -0
- package/dist/vite/mdx-parse.d.ts +102 -0
- package/dist/vite/mdx-parse.d.ts.map +1 -0
- package/dist/vite/mdx-parse.js +251 -0
- package/dist/vite/mdx-provided-components.d.ts +18 -0
- package/dist/vite/mdx-provided-components.d.ts.map +1 -0
- package/dist/vite/mdx-provided-components.js +14 -0
- package/dist/vite/mdx-video.d.ts +327 -0
- package/dist/vite/mdx-video.d.ts.map +1 -0
- package/dist/vite/mdx-video.js +596 -0
- package/dist/vite/mdx-video.test.d.ts +9 -0
- package/dist/vite/mdx-video.test.d.ts.map +1 -0
- package/dist/vite/mdx-video.test.js +1945 -0
- package/dist/vite/media-components.d.ts +45 -0
- package/dist/vite/media-components.d.ts.map +1 -0
- package/dist/vite/media-components.js +355 -0
- package/dist/vite/media-duration-store.d.ts +66 -0
- package/dist/vite/media-duration-store.d.ts.map +1 -0
- package/dist/vite/media-duration-store.js +204 -0
- package/dist/vite/player-page.d.ts +35 -0
- package/dist/vite/player-page.d.ts.map +1 -0
- package/dist/vite/player-page.js +720 -0
- package/dist/vite/render-client.d.ts +18 -0
- package/dist/vite/render-client.d.ts.map +1 -0
- package/dist/vite/render-client.js +67 -0
- package/dist/vite/sdk.d.ts +221 -0
- package/dist/vite/sdk.d.ts.map +1 -0
- package/dist/vite/sdk.js +355 -0
- package/dist/vite/server-components.d.ts +55 -0
- package/dist/vite/server-components.d.ts.map +1 -0
- package/dist/vite/server-components.js +156 -0
- package/dist/vite/server-mdx.d.ts +74 -0
- package/dist/vite/server-mdx.d.ts.map +1 -0
- package/dist/vite/server-mdx.js +259 -0
- package/dist/vite/shader-renderer.d.ts +48 -0
- package/dist/vite/shader-renderer.d.ts.map +1 -0
- package/dist/vite/shader-renderer.js +411 -0
- package/dist/vite/store-hooks.d.ts +12 -0
- package/dist/vite/store-hooks.d.ts.map +1 -0
- package/dist/vite/store-hooks.js +93 -0
- package/dist/vite/store.d.ts +75 -0
- package/dist/vite/store.d.ts.map +1 -0
- package/dist/vite/store.js +52 -0
- package/dist/vite/store.test.d.ts +6 -0
- package/dist/vite/store.test.d.ts.map +1 -0
- package/dist/vite/store.test.js +172 -0
- package/dist/vite/tweakpane-hook.d.ts +94 -0
- package/dist/vite/tweakpane-hook.d.ts.map +1 -0
- package/dist/vite/tweakpane-hook.js +450 -0
- package/dist/vite/vite-plugin.d.ts +28 -0
- package/dist/vite/vite-plugin.d.ts.map +1 -0
- package/dist/vite/vite-plugin.js +539 -0
- package/dist/vite/wave-gradient-shader.d.ts +41 -0
- package/dist/vite/wave-gradient-shader.d.ts.map +1 -0
- package/dist/vite/wave-gradient-shader.js +207 -0
- package/package.json +101 -24
- package/skills/egaki/SKILL.md +162 -1
- package/src/cli/cache-utils.ts +169 -0
- package/src/cli/cached-generate.test.ts +531 -0
- package/src/cli/cached-generate.ts +348 -0
- package/src/cli/cartesia-provider.ts +249 -0
- package/src/{cli.ts → cli/cli.ts} +836 -884
- package/src/cli/clone-generate.ts +202 -0
- package/src/{credentials.ts → cli/credentials.ts} +20 -0
- package/src/cli/elevenlabs-speech-provider.ts +243 -0
- package/src/cli/generate.test.ts +166 -0
- package/src/cli/generate.ts +912 -0
- package/src/cli/main.ts +8 -0
- package/src/{model-catalog.ts → cli/model-catalog.ts} +787 -58
- package/src/{models.ts → cli/models.ts} +65 -86
- package/src/cli/openai-speech-provider.ts +34 -0
- package/src/cli/separation-generate.ts +187 -0
- package/src/cli/speech-catalog.ts +253 -0
- package/src/cli/speech-generate.ts +275 -0
- package/src/cli/speech-models.ts +146 -0
- package/src/cli/speech-provider.test.ts +226 -0
- package/src/cli/transcription-catalog.ts +250 -0
- package/src/cli/transcription-generate.ts +214 -0
- package/src/cli/transcription-models.ts +136 -0
- package/src/cli/transcription-providers.ts +427 -0
- package/src/{xai-auth.ts → cli/xai-auth.ts} +1 -1
- package/src/vite/angled-screen.tsx +214 -0
- package/src/vite/app.tsx +197 -0
- package/src/vite/bands-shader.tsx +319 -0
- package/src/vite/code-block.tsx +939 -0
- package/src/vite/components.tsx +278 -0
- package/src/vite/dispersion-rings-shader.tsx +331 -0
- package/src/vite/easing-curves.test.ts +232 -0
- package/src/vite/easing-curves.ts +743 -0
- package/src/vite/generated-media-client.tsx +121 -0
- package/src/vite/keyframes.tsx +347 -0
- package/src/vite/layout-editor.tsx +709 -0
- package/src/vite/layout-transition.tsx +706 -0
- package/src/vite/liquid-gradient-shader.tsx +474 -0
- package/src/vite/mdx-client.tsx +420 -0
- package/src/vite/mdx-parse.ts +343 -0
- package/src/vite/mdx-provided-components.ts +19 -0
- package/src/vite/mdx-video.test.tsx +2219 -0
- package/src/vite/mdx-video.tsx +976 -0
- package/src/vite/media-components.tsx +473 -0
- package/src/vite/media-duration-store.ts +225 -0
- package/src/vite/motion-timing.ts +194 -0
- package/src/vite/player-page.tsx +1107 -0
- package/src/vite/render-client.ts +84 -0
- package/src/vite/sdk.ts +598 -0
- package/src/vite/server-components.tsx +241 -0
- package/src/vite/server-mdx.ts +285 -0
- package/src/vite/shader-renderer.tsx +535 -0
- package/src/vite/store-hooks.ts +117 -0
- package/src/vite/store.test.ts +202 -0
- package/src/vite/store.ts +115 -0
- package/src/vite/styles.css +21 -0
- package/src/vite/tweakpane-hook.tsx +593 -0
- package/src/vite/virtual-modules.d.ts +30 -0
- package/src/vite/vite-plugin.ts +585 -0
- package/src/vite/wave-gradient-shader.tsx +253 -0
- package/README.md +0 -370
- package/dist/antigravity-auth.d.ts +0 -15
- package/dist/antigravity-auth.d.ts.map +0 -1
- package/dist/antigravity-auth.js +0 -544
- package/dist/antigravity-image.d.ts +0 -11
- package/dist/antigravity-image.d.ts.map +0 -1
- package/dist/antigravity-image.js +0 -285
- package/dist/chatgpt-auth.d.ts.map +0 -1
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/credentials.d.ts.map +0 -1
- package/dist/gateway-model-candidates.generated.d.ts +0 -11
- package/dist/gateway-model-candidates.generated.d.ts.map +0 -1
- package/dist/gateway-model-candidates.generated.js +0 -64
- package/dist/login.d.ts.map +0 -1
- package/dist/model-catalog.d.ts.map +0 -1
- package/dist/models.d.ts.map +0 -1
- package/dist/open-browser.d.ts.map +0 -1
- package/dist/subscription.d.ts.map +0 -1
- package/dist/video-model-catalog.d.ts.map +0 -1
- package/dist/xai-auth.d.ts.map +0 -1
- /package/dist/{chatgpt-auth.d.ts → cli/chatgpt-auth.d.ts} +0 -0
- /package/dist/{chatgpt-auth.js → cli/chatgpt-auth.js} +0 -0
- /package/dist/{credentials.d.ts → cli/credentials.d.ts} +0 -0
- /package/dist/{login.d.ts → cli/login.d.ts} +0 -0
- /package/dist/{login.js → cli/login.js} +0 -0
- /package/dist/{open-browser.d.ts → cli/open-browser.d.ts} +0 -0
- /package/dist/{open-browser.js → cli/open-browser.js} +0 -0
- /package/dist/{subscription.d.ts → cli/subscription.d.ts} +0 -0
- /package/dist/{subscription.js → cli/subscription.js} +0 -0
- /package/dist/{video-model-catalog.d.ts → cli/video-model-catalog.d.ts} +0 -0
- /package/dist/{video-model-catalog.js → cli/video-model-catalog.js} +0 -0
- /package/dist/{xai-auth.d.ts → cli/xai-auth.d.ts} +0 -0
- /package/src/{chatgpt-auth.ts → cli/chatgpt-auth.ts} +0 -0
- /package/src/{login.ts → cli/login.ts} +0 -0
- /package/src/{open-browser.ts → cli/open-browser.ts} +0 -0
- /package/src/{subscription.ts → cli/subscription.ts} +0 -0
- /package/src/{video-model-catalog.ts → cli/video-model-catalog.ts} +0 -0
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Client-side video components for MDX rendering.
|
|
5
|
+
*
|
|
6
|
+
* Contains animation wrappers (enter/exit), element overrides for safe-mdx,
|
|
7
|
+
* and the components map builder. All marked 'use client' because animation
|
|
8
|
+
* components use Remotion hooks (useCurrentFrame, useVideoConfig).
|
|
9
|
+
*
|
|
10
|
+
* The server imports this file and gets client references for the components
|
|
11
|
+
* map. safe-mdx creates React elements with these references on the server;
|
|
12
|
+
* hooks execute on the client inside Remotion's Player render loop.
|
|
13
|
+
*/
|
|
14
|
+
import { createContext, useContext, useId, useInsertionEffect, useLayoutEffect } from 'react';
|
|
15
|
+
import { splitIntoSections, calculateTotalDuration, resolveAutoDurations, } from "./mdx-parse.js";
|
|
16
|
+
import { BlurReveal, MaskedSlideReveal, StaggeredFadeUp, ShimmerSweep, } from "./components.js";
|
|
17
|
+
import { AngledScreen } from "./angled-screen.js";
|
|
18
|
+
import { CodeBlock, CODE_THEMES } from "./code-block.js";
|
|
19
|
+
import { BandsShader } from "./bands-shader.js";
|
|
20
|
+
import { WaveGradientShader } from "./wave-gradient-shader.js";
|
|
21
|
+
import { LiquidGradientShader } from "./liquid-gradient-shader.js";
|
|
22
|
+
import { DispersionRingsShader } from "./dispersion-rings-shader.js";
|
|
23
|
+
export { splitIntoSections, calculateTotalDuration, resolveAutoDurations };
|
|
24
|
+
import { useTweakpane, TWEAKPANE_DISABLED } from "./tweakpane-hook.js";
|
|
25
|
+
export { useTweakpane, TWEAKPANE_DISABLED };
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// MotionTimingSync — bridges Framer Motion (motion/react) with Remotion.
|
|
28
|
+
//
|
|
29
|
+
// Reads the global seekTo function set by the virtual:egaki-motion-timing
|
|
30
|
+
// module (emitted by the Vite plugin when the user has `motion` installed).
|
|
31
|
+
// Calls seekTo with the current frame time from useLayoutEffect so motion.div
|
|
32
|
+
// animations stay in sync with Remotion's frame-based rendering. No-op when
|
|
33
|
+
// motion isn't installed.
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
export function MotionTimingSync({ children }) {
|
|
36
|
+
const scopeId = useId();
|
|
37
|
+
const frame = useCurrentFrame();
|
|
38
|
+
const { fps } = useVideoConfig();
|
|
39
|
+
const timeMs = (frame / fps) * 1000;
|
|
40
|
+
// Runs before any child layout effects create JSAnimation instances, so
|
|
41
|
+
// the play() patch can immediately sample new animations at this frame.
|
|
42
|
+
useInsertionEffect(() => {
|
|
43
|
+
globalThis.__egakiMotionPrepareTime?.(timeMs);
|
|
44
|
+
}, [timeMs]);
|
|
45
|
+
// useLayoutEffect, not useEffect: motion/react creates JSAnimation
|
|
46
|
+
// instances during layout/effect lifecycle, not during render. Using
|
|
47
|
+
// useLayoutEffect ensures seekTo runs AFTER motion has mounted its
|
|
48
|
+
// animations but BEFORE the browser paints, so Remotion's frame
|
|
49
|
+
// capture sees the correct animation state.
|
|
50
|
+
useLayoutEffect(() => {
|
|
51
|
+
globalThis.__egakiMotionSeekTo?.(timeMs, scopeId);
|
|
52
|
+
}, [timeMs, scopeId]);
|
|
53
|
+
return (_jsx("div", { "data-egaki-motion-scope-id": scopeId, style: { display: 'contents' }, children: children }));
|
|
54
|
+
}
|
|
55
|
+
export const ServerSlotsContext = createContext({});
|
|
56
|
+
import { AbsoluteFill, Internals, interpolate, spring, useCurrentFrame, useVideoConfig, } from 'remotion';
|
|
57
|
+
import { BEZIER_POINTS, cubicBezier, naturalThrowSamples, decelerateOvershootSamples, decelerateElasticSamples, accelerateImpulseSamples, accelerateElasticSamples, elasticSnapSamples, bounceSamples, bounceAnticipateSamples, bounceThrowSamples, impulseSlowSamples, impulseOvershootSamples, overshootSamples, overshootElasticSamples, overshootBouncySamples, lerpSamples, } from "./easing-curves.js";
|
|
58
|
+
// Re-export the continuous preset functions (Jitter easings at ANY intensity,
|
|
59
|
+
// e.g. impulseOvershoot(96), interpolated in config space) and the engine
|
|
60
|
+
// primitives for building custom curves.
|
|
61
|
+
export { BEZIER_POINTS, cubicBezier, polybezier, pathPreset, springPreset, bouncePreset, samplePreset, naturalThrow, decelerateOvershoot, decelerateElastic, accelerateImpulse, accelerateElastic, elasticSnap, bounce, bounceAnticipate, bounceThrow, impulseSlow, impulseOvershoot, overshoot, overshootElastic, overshootBouncy, } from "./easing-curves.js";
|
|
62
|
+
// Raw sampled curves (51 points per intensity level 0/25/50/75/100).
|
|
63
|
+
export { naturalThrowSamples, decelerateOvershootSamples, decelerateElasticSamples, accelerateImpulseSamples, accelerateElasticSamples, elasticSnapSamples, bounceSamples, bounceAnticipateSamples, bounceThrowSamples, impulseSlowSamples, impulseOvershootSamples, overshootSamples, overshootElasticSamples, overshootBouncySamples, lerpSamples, };
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// useAbsoluteCurrentFrame() — absolute composition frame hook
|
|
66
|
+
//
|
|
67
|
+
// Remotion's useCurrentFrame() returns the frame relative to the current
|
|
68
|
+
// Series.Sequence (resets to 0 at each section). This hook returns the
|
|
69
|
+
// absolute frame across the entire composition, useful for global timing,
|
|
70
|
+
// syncing elements across sections, or computing total elapsed time.
|
|
71
|
+
// Uses Remotion's internal useTimelinePosition which is what useCurrentFrame
|
|
72
|
+
// reads before subtracting the sequence offset.
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
/**
|
|
75
|
+
* Returns the absolute frame number across the entire composition.
|
|
76
|
+
*
|
|
77
|
+
* Unlike `useCurrentFrame()` which resets to 0 at each section boundary
|
|
78
|
+
* (Series.Sequence), this returns the global frame from 0 to totalDuration.
|
|
79
|
+
*
|
|
80
|
+
* ```tsx
|
|
81
|
+
* const absoluteFrame = useAbsoluteCurrentFrame()
|
|
82
|
+
* const elapsedSeconds = absoluteFrame / fps
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export function useAbsoluteCurrentFrame() {
|
|
86
|
+
return Internals.Timeline.useTimelinePosition();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Returns `true` when the component is being rendered inside a premounted
|
|
90
|
+
* `<Series.Sequence premountFor={…}>` — i.e. the sequence is mounted early
|
|
91
|
+
* for preloading but invisible (opacity 0, pointer-events none, frozen at
|
|
92
|
+
* its start frame).
|
|
93
|
+
*
|
|
94
|
+
* Use this to skip expensive side effects (tweakpane registration, heavy
|
|
95
|
+
* canvas work, etc.) that shouldn't run during premount.
|
|
96
|
+
*
|
|
97
|
+
* Uses Remotion's internal `SequenceContext.premounting` flag — the same
|
|
98
|
+
* mechanism Remotion's own `<Video>`, `<Audio>`, and `<Img>` use to skip
|
|
99
|
+
* buffering during premount.
|
|
100
|
+
*/
|
|
101
|
+
export function useIsPremounting() {
|
|
102
|
+
const ctx = useContext(Internals.SequenceContext);
|
|
103
|
+
return ctx?.premounting ?? false;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Convert a human-readable (duration, bounce) pair into Remotion spring
|
|
107
|
+
* physics config. Matches Motion's `visualDuration` spring formula exactly.
|
|
108
|
+
*
|
|
109
|
+
* The `duration` param is a *perceptual* duration (how long the animation
|
|
110
|
+
* *feels*), not the exact settling time. Motion multiplies it by 1.2
|
|
111
|
+
* internally to derive the natural frequency, so the spring actually
|
|
112
|
+
* oscillates slightly longer than `duration` but *appears* to complete
|
|
113
|
+
* within it. We use the same 1.2 factor for identical behavior.
|
|
114
|
+
*
|
|
115
|
+
* @param duration - Perceptual animation duration in seconds (e.g. 0.5).
|
|
116
|
+
* Internally multiplied by 1.2 to match Motion's visualDuration formula.
|
|
117
|
+
* @param bounce - Bounciness from 0 (no overshoot) to 1 (max bounce). Default 0.
|
|
118
|
+
*
|
|
119
|
+
* ```ts
|
|
120
|
+
* // No bounce, 400ms
|
|
121
|
+
* spring({ frame, fps, config: springFromDuration(0.4) })
|
|
122
|
+
*
|
|
123
|
+
* // Subtle Apple-like overshoot, 600ms
|
|
124
|
+
* spring({ frame, fps, config: springFromDuration(0.6, 0.25) })
|
|
125
|
+
*
|
|
126
|
+
* // Playful bounce, 500ms
|
|
127
|
+
* spring({ frame, fps, config: springFromDuration(0.5, 0.5) })
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
export function springFromDuration(duration, bounce = 0) {
|
|
131
|
+
// Matches Motion's visualDuration path (motion-dom spring.ts lines 191-205).
|
|
132
|
+
// The 1.2 factor converts perceptual duration to the spring's natural period.
|
|
133
|
+
const omega = (2 * Math.PI) / (duration * 1.2);
|
|
134
|
+
const stiffness = omega * omega;
|
|
135
|
+
// Motion clamps dampingRatio (not bounce) to [0.05, 1]
|
|
136
|
+
const dampingRatio = Math.max(0.05, Math.min(1, 1 - bounce));
|
|
137
|
+
return {
|
|
138
|
+
stiffness,
|
|
139
|
+
damping: 2 * dampingRatio * Math.sqrt(stiffness),
|
|
140
|
+
mass: 1,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
// findSpringConfig — Motion's duration-based spring solver (Newton-Raphson).
|
|
145
|
+
//
|
|
146
|
+
// Unlike springFromDuration (which uses a perceptual visual-duration), this
|
|
147
|
+
// finds spring params where the envelope decays to near-zero at exactly the
|
|
148
|
+
// given duration. Ported from Motion's findSpring() (motion-dom spring.ts).
|
|
149
|
+
// ---------------------------------------------------------------------------
|
|
150
|
+
function calcAngularFreq(undampedFreq, dampingRatio) {
|
|
151
|
+
return undampedFreq * Math.sqrt(1 - dampingRatio * dampingRatio);
|
|
152
|
+
}
|
|
153
|
+
function approximateRoot(envelope, derivative, initialGuess) {
|
|
154
|
+
let result = initialGuess;
|
|
155
|
+
for (let i = 1; i < 12; i++) {
|
|
156
|
+
result = result - envelope(result) / derivative(result);
|
|
157
|
+
}
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Find spring physics config where the spring settles at exactly `duration`.
|
|
162
|
+
* Ported from Motion's `findSpring()` — uses Newton-Raphson root-finding to
|
|
163
|
+
* solve for the undamped natural frequency that makes the spring envelope
|
|
164
|
+
* reach near-zero at the given duration.
|
|
165
|
+
*
|
|
166
|
+
* Use this when you need the spring to settle at a precise time (e.g. syncing
|
|
167
|
+
* to a beat or section boundary). For general-purpose springs where the feel
|
|
168
|
+
* matters more than exact timing, prefer `springFromDuration()`.
|
|
169
|
+
*
|
|
170
|
+
* Note: Motion's generator also forcibly snaps `value = target` when
|
|
171
|
+
* `t >= duration`. Remotion's spring() does not; it naturally settles.
|
|
172
|
+
* The envelope will be near-zero at `duration` but not forcibly clamped.
|
|
173
|
+
*
|
|
174
|
+
* @param duration - Exact settling time in seconds.
|
|
175
|
+
* @param bounce - Bounciness from 0 (no overshoot) to 1 (max bounce). Default 0.
|
|
176
|
+
*
|
|
177
|
+
* ```ts
|
|
178
|
+
* // Spring that settles in exactly 800ms with moderate bounce
|
|
179
|
+
* spring({ frame, fps, config: findSpringConfig(0.8, 0.3) })
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
export function findSpringConfig(duration, bounce = 0) {
|
|
183
|
+
const mass = 1;
|
|
184
|
+
const velocity = 0;
|
|
185
|
+
const safeMin = 0.001;
|
|
186
|
+
let dampingRatio = 1 - bounce;
|
|
187
|
+
dampingRatio = Math.max(0.05, Math.min(1, dampingRatio));
|
|
188
|
+
duration = Math.max(0.01, Math.min(10, duration));
|
|
189
|
+
let envelope;
|
|
190
|
+
let derivative;
|
|
191
|
+
if (dampingRatio < 1) {
|
|
192
|
+
// Underdamped
|
|
193
|
+
envelope = (undampedFreq) => {
|
|
194
|
+
const exponentialDecay = undampedFreq * dampingRatio;
|
|
195
|
+
const delta = exponentialDecay * duration;
|
|
196
|
+
const a = exponentialDecay - velocity;
|
|
197
|
+
const b = calcAngularFreq(undampedFreq, dampingRatio);
|
|
198
|
+
const c = Math.exp(-delta);
|
|
199
|
+
return safeMin - (a / b) * c;
|
|
200
|
+
};
|
|
201
|
+
derivative = (undampedFreq) => {
|
|
202
|
+
const exponentialDecay = undampedFreq * dampingRatio;
|
|
203
|
+
const delta = exponentialDecay * duration;
|
|
204
|
+
const d = delta * velocity + velocity;
|
|
205
|
+
const e = Math.pow(dampingRatio, 2) * Math.pow(undampedFreq, 2) * duration;
|
|
206
|
+
const f = Math.exp(-delta);
|
|
207
|
+
const g = calcAngularFreq(Math.pow(undampedFreq, 2), dampingRatio);
|
|
208
|
+
const factor = -envelope(undampedFreq) + safeMin > 0 ? -1 : 1;
|
|
209
|
+
return (factor * ((d - e) * f)) / g;
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
// Critically damped
|
|
214
|
+
envelope = (undampedFreq) => {
|
|
215
|
+
const a = Math.exp(-undampedFreq * duration);
|
|
216
|
+
const b = (undampedFreq - velocity) * duration + 1;
|
|
217
|
+
return -safeMin + a * b;
|
|
218
|
+
};
|
|
219
|
+
derivative = (undampedFreq) => {
|
|
220
|
+
const a = Math.exp(-undampedFreq * duration);
|
|
221
|
+
const b = (velocity - undampedFreq) * (duration * duration);
|
|
222
|
+
return a * b;
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
const undampedFreq = approximateRoot(envelope, derivative, 5 / duration);
|
|
226
|
+
if (isNaN(undampedFreq)) {
|
|
227
|
+
return { stiffness: 100, damping: 10, mass: 1 };
|
|
228
|
+
}
|
|
229
|
+
const stiffness = Math.pow(undampedFreq, 2) * mass;
|
|
230
|
+
return {
|
|
231
|
+
stiffness,
|
|
232
|
+
damping: dampingRatio * 2 * Math.sqrt(mass * stiffness),
|
|
233
|
+
mass,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Shorthand: run a spring animation driven by springFromDuration().
|
|
238
|
+
* Returns 0-to-1 progress (or 0-to-`to` if specified).
|
|
239
|
+
*
|
|
240
|
+
* ```tsx
|
|
241
|
+
* const scale = dspring(frame, fps, 0.5, 0.3) // 500ms, slight bounce
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
export function dspring(frame, fps, duration, bounce = 0, options) {
|
|
245
|
+
return spring({
|
|
246
|
+
frame,
|
|
247
|
+
fps,
|
|
248
|
+
config: springFromDuration(duration, bounce),
|
|
249
|
+
delay: options?.delay,
|
|
250
|
+
to: options?.to,
|
|
251
|
+
from: options?.from,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
// ---------------------------------------------------------------------------
|
|
255
|
+
// Easing presets — named bezier curves for common motion styles.
|
|
256
|
+
// Use with interpolate(frame, range, range, { easing: EASE.apple }).
|
|
257
|
+
//
|
|
258
|
+
// These are the After Effects / Apple motion graphics "cheat codes":
|
|
259
|
+
// curves that motion designers converge on for premium-feeling animation.
|
|
260
|
+
// ---------------------------------------------------------------------------
|
|
261
|
+
export const EASE = {
|
|
262
|
+
/** AE 75% influence — tight S-curve, the "Apple ease" */
|
|
263
|
+
apple: cubicBezier(0.76, 0, 0.24, 1),
|
|
264
|
+
/** Fast enter, gentle settle — elements arriving with momentum */
|
|
265
|
+
enterFast: cubicBezier(0.22, 1, 0.36, 1),
|
|
266
|
+
/** Slow start, fast exit — elements leaving the frame */
|
|
267
|
+
exitSlow: cubicBezier(0.55, 0, 1, 0.45),
|
|
268
|
+
/** Social media punch — very sharp burst */
|
|
269
|
+
snappy: cubicBezier(0.87, 0, 0.13, 1),
|
|
270
|
+
/** Luxurious, slow cinematic feel */
|
|
271
|
+
cinematic: cubicBezier(0.83, 0, 0.17, 1),
|
|
272
|
+
// --- Bezier presets (intensity 50 defaults) ---
|
|
273
|
+
/** Strong ease-out, snaps into place. The workhorse motion curve. */
|
|
274
|
+
smooth: cubicBezier(0.5, 0, 0, 1),
|
|
275
|
+
/** Symmetric S-curve, natural feeling in-out */
|
|
276
|
+
natural: cubicBezier(0.8, 0, 0.2, 1),
|
|
277
|
+
/** Pure deceleration, no ease-in. Objects arriving at full speed. */
|
|
278
|
+
decelerate: cubicBezier(0, 0, 0, 1),
|
|
279
|
+
/** Pure acceleration, no ease-out. Objects leaving from rest. */
|
|
280
|
+
accelerate: cubicBezier(1, 0, 1, 1),
|
|
281
|
+
// --- Sampled presets (intensity 50, spring/bounce/overshoot) ---
|
|
282
|
+
// Values can exceed 0-1 range. Use with interpolate().
|
|
283
|
+
/** Elastic snap into place with ringing oscillation */
|
|
284
|
+
elasticSnap: sampledEasing(elasticSnapSamples[50]),
|
|
285
|
+
/** Standard bounce, like a ball dropping */
|
|
286
|
+
bounce: sampledEasing(bounceSamples[50]),
|
|
287
|
+
/** Bounce with anticipation (pulls back first) */
|
|
288
|
+
bounceAnticipate: sampledEasing(bounceAnticipateSamples[50]),
|
|
289
|
+
/** Throw with bounce on landing */
|
|
290
|
+
bounceThrow: sampledEasing(bounceThrowSamples[50]),
|
|
291
|
+
/** Overshoot then settle back */
|
|
292
|
+
overshoot: sampledEasing(overshootSamples[50]),
|
|
293
|
+
/** Overshoot with elastic ringing */
|
|
294
|
+
overshootElastic: sampledEasing(overshootElasticSamples[50]),
|
|
295
|
+
/** Overshoot with bouncy settle */
|
|
296
|
+
overshootBouncy: sampledEasing(overshootBouncySamples[50]),
|
|
297
|
+
/** Deceleration with overshoot */
|
|
298
|
+
decelerateOvershoot: sampledEasing(decelerateOvershootSamples[50]),
|
|
299
|
+
/** Deceleration with elastic overshoot */
|
|
300
|
+
decelerateElastic: sampledEasing(decelerateElasticSamples[50]),
|
|
301
|
+
/** Natural throw with momentum */
|
|
302
|
+
naturalThrow: sampledEasing(naturalThrowSamples[50]),
|
|
303
|
+
/** Accelerating impulse burst */
|
|
304
|
+
accelerateImpulse: sampledEasing(accelerateImpulseSamples[50]),
|
|
305
|
+
/** Acceleration with elastic windup */
|
|
306
|
+
accelerateElastic: sampledEasing(accelerateElasticSamples[50]),
|
|
307
|
+
/** Slow impulse, gradual build then release */
|
|
308
|
+
impulseSlow: sampledEasing(impulseSlowSamples[50]),
|
|
309
|
+
/** Impulse with overshoot settle */
|
|
310
|
+
impulseOvershoot: sampledEasing(impulseOvershootSamples[50]),
|
|
311
|
+
};
|
|
312
|
+
/** Wrap a sampled curve into a Remotion-compatible easing function. */
|
|
313
|
+
function sampledEasing(samples) {
|
|
314
|
+
return (t) => lerpSamples(samples, t);
|
|
315
|
+
}
|
|
316
|
+
function snapIntensity(i) {
|
|
317
|
+
return (Math.round(i / 25) * 25);
|
|
318
|
+
}
|
|
319
|
+
/** smooth at custom intensity. Pattern: cubic-bezier(lerp(0.3, 0.9, i/100), 0, 0, 1) */
|
|
320
|
+
export function smoothEasing(intensity) {
|
|
321
|
+
const x1 = 0.3 + 0.6 * (intensity / 100);
|
|
322
|
+
return cubicBezier(x1, 0, 0, 1);
|
|
323
|
+
}
|
|
324
|
+
/** natural at custom intensity. Pattern: cubic-bezier(lerp(0.5, 1, i/100), 0, lerp(0.5, 0, i/100), 1) */
|
|
325
|
+
export function naturalEasing(intensity) {
|
|
326
|
+
const x1 = 0.5 + 0.5 * (intensity / 100);
|
|
327
|
+
const x2 = 0.5 - 0.5 * (intensity / 100);
|
|
328
|
+
return cubicBezier(x1, 0, x2, 1);
|
|
329
|
+
}
|
|
330
|
+
/** decelerate at custom intensity */
|
|
331
|
+
export function decelerateEasing(intensity) {
|
|
332
|
+
// 0→(0, 0, 0.3, 1), 50→(0, 0, 0, 1), 75→(0, 0.45, 0, 1), 100→(0, 0.9, 0, 1)
|
|
333
|
+
if (intensity <= 50) {
|
|
334
|
+
const x2 = 0.3 * (1 - intensity / 50);
|
|
335
|
+
return cubicBezier(0, 0, x2, 1);
|
|
336
|
+
}
|
|
337
|
+
const y1 = 0.9 * ((intensity - 50) / 50);
|
|
338
|
+
return cubicBezier(0, y1, 0, 1);
|
|
339
|
+
}
|
|
340
|
+
/** accelerate at custom intensity */
|
|
341
|
+
export function accelerateEasing(intensity) {
|
|
342
|
+
// 0→(0.7, 0, 1, 1), 50→(1, 0, 1, 1), 75→(1, 0, 1, 0.55), 100→(1, 0, 1, 0.1)
|
|
343
|
+
if (intensity <= 50) {
|
|
344
|
+
const x1 = 0.7 + 0.3 * (intensity / 50);
|
|
345
|
+
return cubicBezier(x1, 0, 1, 1);
|
|
346
|
+
}
|
|
347
|
+
const y2 = 1 - 0.9 * ((intensity - 50) / 50);
|
|
348
|
+
return cubicBezier(1, 0, 1, y2);
|
|
349
|
+
}
|
|
350
|
+
/** elasticSnap at custom intensity (sampled) */
|
|
351
|
+
export function elasticSnapEasing(intensity) {
|
|
352
|
+
return sampledEasing(elasticSnapSamples[snapIntensity(intensity)]);
|
|
353
|
+
}
|
|
354
|
+
/** bounce at custom intensity (sampled) */
|
|
355
|
+
export function bounceEasing(intensity) {
|
|
356
|
+
return sampledEasing(bounceSamples[snapIntensity(intensity)]);
|
|
357
|
+
}
|
|
358
|
+
/** bounceAnticipate at custom intensity (sampled) */
|
|
359
|
+
export function bounceAnticipateEasing(intensity) {
|
|
360
|
+
return sampledEasing(bounceAnticipateSamples[snapIntensity(intensity)]);
|
|
361
|
+
}
|
|
362
|
+
/** bounceThrow at custom intensity (sampled) */
|
|
363
|
+
export function bounceThrowEasing(intensity) {
|
|
364
|
+
return sampledEasing(bounceThrowSamples[snapIntensity(intensity)]);
|
|
365
|
+
}
|
|
366
|
+
/** overshoot at custom intensity (sampled) */
|
|
367
|
+
export function overshootEasing(intensity) {
|
|
368
|
+
return sampledEasing(overshootSamples[snapIntensity(intensity)]);
|
|
369
|
+
}
|
|
370
|
+
/** overshootElastic at custom intensity (sampled) */
|
|
371
|
+
export function overshootElasticEasing(intensity) {
|
|
372
|
+
return sampledEasing(overshootElasticSamples[snapIntensity(intensity)]);
|
|
373
|
+
}
|
|
374
|
+
/** overshootBouncy at custom intensity (sampled) */
|
|
375
|
+
export function overshootBouncyEasing(intensity) {
|
|
376
|
+
return sampledEasing(overshootBouncySamples[snapIntensity(intensity)]);
|
|
377
|
+
}
|
|
378
|
+
/** decelerateOvershoot at custom intensity (sampled) */
|
|
379
|
+
export function decelerateOvershootEasing(intensity) {
|
|
380
|
+
return sampledEasing(decelerateOvershootSamples[snapIntensity(intensity)]);
|
|
381
|
+
}
|
|
382
|
+
/** decelerateElastic at custom intensity (sampled) */
|
|
383
|
+
export function decelerateElasticEasing(intensity) {
|
|
384
|
+
return sampledEasing(decelerateElasticSamples[snapIntensity(intensity)]);
|
|
385
|
+
}
|
|
386
|
+
/** naturalThrow at custom intensity (sampled) */
|
|
387
|
+
export function naturalThrowEasing(intensity) {
|
|
388
|
+
return sampledEasing(naturalThrowSamples[snapIntensity(intensity)]);
|
|
389
|
+
}
|
|
390
|
+
/** accelerateImpulse at custom intensity (sampled) */
|
|
391
|
+
export function accelerateImpulseEasing(intensity) {
|
|
392
|
+
return sampledEasing(accelerateImpulseSamples[snapIntensity(intensity)]);
|
|
393
|
+
}
|
|
394
|
+
/** accelerateElastic at custom intensity (sampled) */
|
|
395
|
+
export function accelerateElasticEasing(intensity) {
|
|
396
|
+
return sampledEasing(accelerateElasticSamples[snapIntensity(intensity)]);
|
|
397
|
+
}
|
|
398
|
+
/** impulseSlow at custom intensity (sampled) */
|
|
399
|
+
export function impulseSlowEasing(intensity) {
|
|
400
|
+
return sampledEasing(impulseSlowSamples[snapIntensity(intensity)]);
|
|
401
|
+
}
|
|
402
|
+
/** impulseOvershoot at custom intensity (sampled) */
|
|
403
|
+
export function impulseOvershootEasing(intensity) {
|
|
404
|
+
return sampledEasing(impulseOvershootSamples[snapIntensity(intensity)]);
|
|
405
|
+
}
|
|
406
|
+
// ---------------------------------------------------------------------------
|
|
407
|
+
// Fill — full-frame layer with stretch + vertical center
|
|
408
|
+
//
|
|
409
|
+
// Like Remotion's AbsoluteFill but with better defaults for video content:
|
|
410
|
+
// children stretch horizontally to fill the frame, center vertically.
|
|
411
|
+
// ---------------------------------------------------------------------------
|
|
412
|
+
export function Fill({ children, style, ...rest }) {
|
|
413
|
+
return (_jsx(AbsoluteFill, { style: {
|
|
414
|
+
alignItems: 'stretch',
|
|
415
|
+
justifyContent: 'center',
|
|
416
|
+
...style,
|
|
417
|
+
}, ...rest, children: children }));
|
|
418
|
+
}
|
|
419
|
+
// ---------------------------------------------------------------------------
|
|
420
|
+
// Background — real component that self-positions as an absolute layer
|
|
421
|
+
//
|
|
422
|
+
// Works both in MDX and when imported from TSX components. Renders its
|
|
423
|
+
// children in a full-frame AbsoluteFill behind sibling content. In Remotion
|
|
424
|
+
// all layout is absolute, so this naturally layers behind content that
|
|
425
|
+
// comes after it in DOM order.
|
|
426
|
+
// ---------------------------------------------------------------------------
|
|
427
|
+
export function Background({ children }) {
|
|
428
|
+
return _jsx(AbsoluteFill, { style: { zIndex: -1 }, children: children });
|
|
429
|
+
}
|
|
430
|
+
const FONT_SANS = '-apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", sans-serif';
|
|
431
|
+
const FONT_MONO = '"SF Mono", ui-monospace, SFMono-Regular, "Cascadia Code", monospace';
|
|
432
|
+
// Ease-out for enters: arrives with momentum, decelerates into place.
|
|
433
|
+
const ENTER_EASING = cubicBezier(0.5, 0, 0, 1);
|
|
434
|
+
// Ease-in for exits: starts slow, accelerates away.
|
|
435
|
+
const EXIT_EASING = cubicBezier(1, 0, 1, 1);
|
|
436
|
+
/** Resolve the effective start frame and default easing from AnimateProps. */
|
|
437
|
+
function resolveAnimateStart(startInFrames, duration, cutInMotion, durationInFrames) {
|
|
438
|
+
if (startInFrames < 0) {
|
|
439
|
+
// Exit: negative start counts from section end
|
|
440
|
+
const resolvedStart = durationInFrames + startInFrames;
|
|
441
|
+
return {
|
|
442
|
+
effectiveStart: resolvedStart + cutInMotion * duration,
|
|
443
|
+
isExit: true,
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
// Enter: positive start counts from section start
|
|
447
|
+
return {
|
|
448
|
+
effectiveStart: startInFrames - cutInMotion * duration,
|
|
449
|
+
isExit: false,
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
// ---------------------------------------------------------------------------
|
|
453
|
+
// Easing function → bezier control points extraction.
|
|
454
|
+
//
|
|
455
|
+
// cubicBezier() attaches a [BEZIER_POINTS] symbol property to the returned
|
|
456
|
+
// function with the original [x1, y1, x2, y2] tuple. This lets the tweakpane
|
|
457
|
+
// bezier blade show and edit the exact curve for any easing created with
|
|
458
|
+
// cubicBezier(), including EASE presets and user-defined curves.
|
|
459
|
+
// Non-bezier presets (sampled from spring/bounce physics) don't have this
|
|
460
|
+
// property and fall back to a default curve.
|
|
461
|
+
// ---------------------------------------------------------------------------
|
|
462
|
+
/** Default bezier control points for enter (ease-out) and exit (ease-in). */
|
|
463
|
+
const DEFAULT_ENTER_BEZIER = [0.5, 0, 0, 1]; // smooth
|
|
464
|
+
const DEFAULT_EXIT_BEZIER = [1, 0, 1, 1]; // accelerate
|
|
465
|
+
/** Extract bezier control points from an easing function, or null if not a bezier. */
|
|
466
|
+
function easingToBezier(fn) {
|
|
467
|
+
if (!fn)
|
|
468
|
+
return null;
|
|
469
|
+
const points = fn[BEZIER_POINTS];
|
|
470
|
+
if (Array.isArray(points) && points.length === 4)
|
|
471
|
+
return points;
|
|
472
|
+
return null;
|
|
473
|
+
}
|
|
474
|
+
/** Shared tweakpane + interpolation logic for all animation primitives. */
|
|
475
|
+
function useAnimateValue(componentName, props) {
|
|
476
|
+
const frame = useCurrentFrame();
|
|
477
|
+
const { durationInFrames, fps } = useVideoConfig();
|
|
478
|
+
const tpLabel = props.label ? `${componentName}: ${props.label}` : componentName;
|
|
479
|
+
// Determine default bezier control points from the easing prop
|
|
480
|
+
const defaultIsExit = (props.startInFrames ?? 0) < 0;
|
|
481
|
+
const propBezier = easingToBezier(props.easing);
|
|
482
|
+
const defaultBezier = propBezier ?? (defaultIsExit ? DEFAULT_EXIT_BEZIER : DEFAULT_ENTER_BEZIER);
|
|
483
|
+
const tp = useTweakpane(tpLabel, {
|
|
484
|
+
from: { value: props.from, min: -2000, max: 2000, step: 1 },
|
|
485
|
+
to: { value: props.to, min: -2000, max: 2000, step: 1 },
|
|
486
|
+
duration: { value: props.duration, min: 1, max: 10 * fps, step: 1 },
|
|
487
|
+
startInFrames: { value: props.startInFrames ?? 0, min: -10 * fps, max: 10 * fps, step: 1 },
|
|
488
|
+
cutInMotion: { value: props.cutInMotion ?? 0, min: 0, max: 1, step: 0.01 },
|
|
489
|
+
easing: { type: 'cubicBezier', value: defaultBezier },
|
|
490
|
+
inline: props.inline ?? false,
|
|
491
|
+
});
|
|
492
|
+
const tpBezier = tp.easing;
|
|
493
|
+
// If the user changed the bezier curve in tweakpane, use it.
|
|
494
|
+
// Otherwise use the original prop easing (which may be a non-bezier function).
|
|
495
|
+
const bezierChanged = tpBezier[0] !== defaultBezier[0]
|
|
496
|
+
|| tpBezier[1] !== defaultBezier[1]
|
|
497
|
+
|| tpBezier[2] !== defaultBezier[2]
|
|
498
|
+
|| tpBezier[3] !== defaultBezier[3];
|
|
499
|
+
const finalEasing = bezierChanged
|
|
500
|
+
? cubicBezier(tpBezier[0], tpBezier[1], tpBezier[2], tpBezier[3])
|
|
501
|
+
: (props.easing ?? (defaultIsExit ? EXIT_EASING : ENTER_EASING));
|
|
502
|
+
const { effectiveStart } = resolveAnimateStart(tp.startInFrames, tp.duration, tp.cutInMotion, durationInFrames);
|
|
503
|
+
const value = interpolate(frame, [effectiveStart, effectiveStart + tp.duration], [tp.from, tp.to], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: finalEasing });
|
|
504
|
+
return {
|
|
505
|
+
value,
|
|
506
|
+
resolvedInline: tp.inline,
|
|
507
|
+
resolvedStyle: props.style,
|
|
508
|
+
label: props.label,
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
export function Opacity(props) {
|
|
512
|
+
const { value, resolvedInline, resolvedStyle, label } = useAnimateValue('Opacity', props);
|
|
513
|
+
const animStyle = { opacity: value, ...resolvedStyle };
|
|
514
|
+
if (resolvedInline)
|
|
515
|
+
return _jsx("div", { style: animStyle, "data-animation": label, children: props.children });
|
|
516
|
+
return _jsx(Fill, { style: animStyle, "data-animation": label, children: props.children });
|
|
517
|
+
}
|
|
518
|
+
export function Scale(props) {
|
|
519
|
+
const { value, resolvedInline, resolvedStyle, label } = useAnimateValue('Scale', props);
|
|
520
|
+
const animStyle = { transform: `scale(${value})`, willChange: 'transform', ...resolvedStyle };
|
|
521
|
+
if (resolvedInline)
|
|
522
|
+
return _jsx("div", { style: animStyle, "data-animation": label, children: props.children });
|
|
523
|
+
return _jsx(Fill, { style: animStyle, "data-animation": label, children: props.children });
|
|
524
|
+
}
|
|
525
|
+
export function TranslateX(props) {
|
|
526
|
+
const { value, resolvedInline, resolvedStyle, label } = useAnimateValue('TranslateX', props);
|
|
527
|
+
const animStyle = { transform: `translateX(${value}px)`, willChange: 'transform', ...resolvedStyle };
|
|
528
|
+
if (resolvedInline)
|
|
529
|
+
return _jsx("div", { style: animStyle, "data-animation": label, children: props.children });
|
|
530
|
+
return _jsx(Fill, { style: animStyle, "data-animation": label, children: props.children });
|
|
531
|
+
}
|
|
532
|
+
export function TranslateY(props) {
|
|
533
|
+
const { value, resolvedInline, resolvedStyle, label } = useAnimateValue('TranslateY', props);
|
|
534
|
+
const animStyle = { transform: `translateY(${value}px)`, willChange: 'transform', ...resolvedStyle };
|
|
535
|
+
if (resolvedInline)
|
|
536
|
+
return _jsx("div", { style: animStyle, "data-animation": label, children: props.children });
|
|
537
|
+
return _jsx(Fill, { style: animStyle, "data-animation": label, children: props.children });
|
|
538
|
+
}
|
|
539
|
+
export function Blur(props) {
|
|
540
|
+
const { value, resolvedInline, resolvedStyle, label } = useAnimateValue('Blur', props);
|
|
541
|
+
const animStyle = { filter: `blur(${value}px)`, ...resolvedStyle };
|
|
542
|
+
if (resolvedInline)
|
|
543
|
+
return _jsx("div", { style: animStyle, "data-animation": label, children: props.children });
|
|
544
|
+
return _jsx(Fill, { style: animStyle, "data-animation": label, children: props.children });
|
|
545
|
+
}
|
|
546
|
+
// ---------------------------------------------------------------------------
|
|
547
|
+
// ---------------------------------------------------------------------------
|
|
548
|
+
// Keyframes & Lottie utilities — extracted to ./keyframes.tsx
|
|
549
|
+
// Re-exported here so all existing consumers keep working.
|
|
550
|
+
// ---------------------------------------------------------------------------
|
|
551
|
+
export { keyframes, fromLottieProperty, extractLottieDimensionEasing, } from "./keyframes.js";
|
|
552
|
+
// ---------------------------------------------------------------------------
|
|
553
|
+
// LayoutTransition — extracted to ./layout-transition.tsx
|
|
554
|
+
// Re-exported here so all existing consumers keep working.
|
|
555
|
+
// ---------------------------------------------------------------------------
|
|
556
|
+
export { LayoutContainerContext, LayoutTransition, LayoutTransitionProvider, LayoutGhost, LayoutAnimationLayer, } from "./layout-transition.js";
|
|
557
|
+
// Local import for use in MDX_BUILTIN_COMPONENTS
|
|
558
|
+
import { LayoutTransition } from "./layout-transition.js";
|
|
559
|
+
// ---------------------------------------------------------------------------
|
|
560
|
+
// Media components & ExportContext — extracted to ./media-components.tsx
|
|
561
|
+
// Re-exported here so all existing consumers keep working.
|
|
562
|
+
// ---------------------------------------------------------------------------
|
|
563
|
+
import { ExportContext, useIsExporting, Img, Audio, Video } from "./media-components.js";
|
|
564
|
+
export { ExportContext, useIsExporting, Img, Audio, Video } from "./media-components.js";
|
|
565
|
+
// Visual components and animations are re-exported so they're available
|
|
566
|
+
// as named imports from this client module for MDX usage.
|
|
567
|
+
export { BlurReveal, MaskedSlideReveal, StaggeredFadeUp, ShimmerSweep, AngledScreen, CodeBlock, CODE_THEMES, BandsShader, WaveGradientShader, LiquidGradientShader, DispersionRingsShader, };
|
|
568
|
+
function GeneratedImage(_props) { return null; }
|
|
569
|
+
function GeneratedVideo(_props) { return null; }
|
|
570
|
+
function GeneratedSpeech(_props) { return null; }
|
|
571
|
+
export const MDX_BUILTIN_COMPONENTS = {
|
|
572
|
+
Fill,
|
|
573
|
+
Background,
|
|
574
|
+
LayoutTransition,
|
|
575
|
+
AngledScreen,
|
|
576
|
+
BandsShader,
|
|
577
|
+
WaveGradientShader,
|
|
578
|
+
LiquidGradientShader,
|
|
579
|
+
DispersionRingsShader,
|
|
580
|
+
BlurReveal,
|
|
581
|
+
MaskedSlideReveal,
|
|
582
|
+
StaggeredFadeUp,
|
|
583
|
+
CodeBlock,
|
|
584
|
+
ShimmerSweep,
|
|
585
|
+
Img,
|
|
586
|
+
Audio,
|
|
587
|
+
Video,
|
|
588
|
+
Opacity,
|
|
589
|
+
Scale,
|
|
590
|
+
TranslateX,
|
|
591
|
+
TranslateY,
|
|
592
|
+
Blur,
|
|
593
|
+
GeneratedImage,
|
|
594
|
+
GeneratedVideo,
|
|
595
|
+
GeneratedSpeech,
|
|
596
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for mdx-video: section splitting, frontmatter parsing,
|
|
3
|
+
* background extraction, and JSX output via createMdxComposition.
|
|
4
|
+
*
|
|
5
|
+
* Uses inline snapshots so the rendered Remotion JSX structure
|
|
6
|
+
* is visible directly in the test file for easy debugging.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=mdx-video.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mdx-video.test.d.ts","sourceRoot":"","sources":["../../src/vite/mdx-video.test.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|