Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
6357b91
Rename `createDescriptor` + `defineEffect` to just `createEffect`
JonnyBurger May 13, 2026
9e9deab
`@remotion/core`: Drop raw effects prop from Solid effect chain deps
pullfrog[bot] May 13, 2026
daede8b
Bump astro from 6.1.6 to 6.1.10 in /packages/astro-example
dependabot[bot] May 14, 2026
7c25338
address #7365
JonnyBurger May 14, 2026
f6b46b9
feat: per-segment easing arrays for interpolate()
JonnyBurger May 14, 2026
7821cff
Update astro to 6.1.10 across all monorepo packages
JonnyBurger May 14, 2026
d024aab
chore: upgrade Mediabunny to 1.45.0
JonnyBurger May 14, 2026
7dcb6f0
Merge pull request #7367 from remotion-dev/dependabot/npm_and_yarn/pa…
JonnyBurger May 14, 2026
5229579
Merge pull request #7364 from remotion-dev/create-effect
JonnyBurger May 14, 2026
4897d9a
feat(effects): add package subpath exports per effect
JonnyBurger May 14, 2026
2cebe3c
feat(light-leaks): add experimental WebGL2 lightLeak canvas effect
JonnyBurger May 14, 2026
e059791
refactor(effects): drop root barrel exports; use subpath imports
JonnyBurger May 14, 2026
3729a0e
Fix Bun 1.3+ build: invalid ESM from sideEffects:false barrel package…
JonnyBurger May 14, 2026
f9ac77e
Add experimental WebGL2 starburst canvas effect
JonnyBurger May 14, 2026
31d0e25
Merge branch 'main' into feat/light-leak-canvas-effect-7372
JonnyBurger May 14, 2026
b785bd1
Merge branch 'main' into fix/effects-subpath-exports-7368
JonnyBurger May 14, 2026
626f12a
Merge branch 'main' into upgrade/mediabunny-1.45.0
JonnyBurger May 14, 2026
db1218a
Merge branch 'main' into feat/interpolate-per-segment-easing-7342
JonnyBurger May 14, 2026
fffb7dc
docs: use distinct easings in per-segment interpolate() example
JonnyBurger May 14, 2026
f7b310a
chore: address PR review — shared easing assert, docs anchor, comments
JonnyBurger May 14, 2026
005acf1
Merge pull request #7374 from remotion-dev/fix/effects-subpath-export…
JonnyBurger May 14, 2026
6d8997d
refactor(light-leaks): use createEffect instead of defineEffect/creat…
JonnyBurger May 14, 2026
f14640c
Merge pull request #7370 from remotion-dev/upgrade/mediabunny-1.45.0
JonnyBurger May 14, 2026
13891c6
Cache starburst palette texture uploads between frames
JonnyBurger May 14, 2026
263602f
Merge pull request #7369 from remotion-dev/feat/interpolate-per-segme…
JonnyBurger May 14, 2026
ace0d79
Merge pull request #7375 from remotion-dev/feat/light-leak-canvas-eff…
JonnyBurger May 14, 2026
26196e1
Merge pull request #7376 from remotion-dev/feat/starburst-effect-7373
JonnyBurger May 14, 2026
1640729
Add @remotion/effects testbed composition
JonnyBurger May 14, 2026
1ca7279
Merge branch 'main' into cursor/7e424736
JonnyBurger May 14, 2026
729dce6
Update EffectsTestbed.tsx
JonnyBurger May 14, 2026
16c4129
update testbed
JonnyBurger May 14, 2026
fd2e06c
easier tests for studio-server
JonnyBurger May 14, 2026
2516437
Merge pull request #7377 from remotion-dev/cursor/7e424736
JonnyBurger May 14, 2026
70767d9
@remotion/timeline-utils: Add waveform tests with @mediabunny/server
cursoragent May 14, 2026
1751e53
Merge pull request #7381 from remotion-dev/cursor/mediabunny-server-w…
JonnyBurger May 14, 2026
dfb4b13
@remotion/timeline-utils: Add film strip codec tests
cursoragent May 14, 2026
2fb90f0
Merge pull request #7383 from remotion-dev/cursor/timeline-filmstrip-…
JonnyBurger May 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 181 additions & 25 deletions bun.lock

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,12 @@
"@types/node": "20.12.14",
"@types/web": "0.0.166",
"@types/bun": "1.3.3",
"mediabunny": "1.42.0",
"@mediabunny/mp3-encoder": "1.42.0",
"@mediabunny/aac-encoder": "1.42.0",
"@mediabunny/flac-encoder": "1.42.0",
"@mediabunny/ac3": "1.42.0",
"mediabunny": "1.45.0",
"@mediabunny/server": "1.45.0",
"@mediabunny/mp3-encoder": "1.45.0",
"@mediabunny/aac-encoder": "1.45.0",
"@mediabunny/flac-encoder": "1.45.0",
"@mediabunny/ac3": "1.45.0",
"next": "16.2.6",
"three": "0.178.0",
"sharp": "0.34.5",
Expand Down
1 change: 0 additions & 1 deletion packages/animated-emoji/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"main": "dist/cjs/index.js",
"types": "dist/cjs/index.d.ts",
"module": "dist/esm/index.mjs",
"sideEffects": false,
"scripts": {
"formatting": "oxfmt src --check",
"format": "oxfmt src",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import type {ExtrapolateType, InterpolateOptions} from 'remotion';
import {interpolate, interpolateColors} from 'remotion';
import {
assertValidInterpolateEasingOption,
interpolate,
interpolateColors,
type EasingFunction,
type ExtrapolateType,
type InterpolateOptions,
} from 'remotion';
import type {
CSSPropertiesKey,
CSSPropertiesValue,
Expand All @@ -8,6 +14,12 @@ import type {
} from '../../type';
import {breakDownValueIntoUnitNumberAndFunctions} from './utils';

type InterpolateStylesResolvedOptions = {
easing: EasingFunction;
extrapolateLeft: ExtrapolateType;
extrapolateRight: ExtrapolateType;
};

const interpolatedPropertyPart = ({
inputValue,
inputRange,
Expand All @@ -23,7 +35,7 @@ const interpolatedPropertyPart = ({
finalStylePropertyPart: UnitNumberAndFunction;
initialStyleProperty: CSSPropertiesValue;
finalStyleProperty: CSSPropertiesValue;
options: Required<InterpolateOptions>;
options: InterpolateStylesResolvedOptions;
}): string | number => {
if (finalStylePropertyPart === undefined) {
throw new TypeError(
Expand Down Expand Up @@ -129,7 +141,7 @@ const interpolateProperty = ({
inputRange: number[];
initialStyleProperty: CSSPropertiesValue;
finalStyleProperty: CSSPropertiesValue;
options: Required<InterpolateOptions>;
options: InterpolateStylesResolvedOptions;
}) => {
if (
typeof initialStyleProperty !== typeof finalStyleProperty &&
Expand Down Expand Up @@ -180,7 +192,7 @@ const interpolateStylesFunction = ({
inputRange: number[];
initialStyle: Style;
finalStyle: Style;
options: Required<InterpolateOptions>;
options: InterpolateStylesResolvedOptions;
}): Style => {
const [startingValue, endingValue] = inputRange;
return Object.keys(initialStyle).reduce((acc, key) => {
Expand Down Expand Up @@ -305,7 +317,15 @@ export const interpolateStyles = (
const initialStyle = outputStylesRange[startIndex];
const finalStyle = outputStylesRange[endIndex];

const easing = options?.easing ?? ((num: number): number => num);
assertValidInterpolateEasingOption(options?.easing, inputRange.length);

const easingOption = options?.easing;
const segmentEasing: EasingFunction =
easingOption === undefined
? (num: number): number => num
: typeof easingOption === 'function'
? easingOption
: easingOption[startIndex];

const extrapolateLeft: ExtrapolateType = options?.extrapolateLeft ?? 'extend';
const extrapolateRight: ExtrapolateType =
Expand All @@ -317,7 +337,7 @@ export const interpolateStyles = (
initialStyle,
finalStyle,
options: {
easing,
easing: segmentEasing,
extrapolateLeft,
extrapolateRight,
},
Expand Down
2 changes: 1 addition & 1 deletion packages/astro-example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"@remotion/three": "workspace:*",
"@remotion/transitions": "workspace:*",
"lottie-web": "5.13.0",
"astro": "6.1.6",
"astro": "6.1.10",
"react": "catalog:",
"react-dom": "catalog:",
"remotion": "workspace:*"
Expand Down
1 change: 0 additions & 1 deletion packages/bundler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"version": "4.0.461",
"description": "Bundle Remotion compositions using Webpack",
"main": "dist/index.js",
"sideEffects": false,
"bugs": {
"url": "https://github.com/remotion-dev/remotion/issues"
},
Expand Down
1 change: 0 additions & 1 deletion packages/captions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"version": "4.0.461",
"description": "Primitives for dealing with captions",
"main": "dist/index.js",
"sideEffects": false,
"bugs": {
"url": "https://github.com/remotion-dev/remotion/issues"
},
Expand Down
1 change: 0 additions & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"version": "4.0.461",
"description": "Control Remotion features using the `npx remotion` command",
"main": "dist/index.js",
"sideEffects": false,
"bin": {
"remotion": "remotion-cli.js",
"remotionb": "remotionb-cli.js",
Expand Down
10 changes: 5 additions & 5 deletions packages/cli/src/extra-packages.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
export const EXTRA_PACKAGES: Record<string, string> = {
mediabunny: '1.42.0',
'@mediabunny/ac3': '1.42.0',
'@mediabunny/mp3-encoder': '1.42.0',
'@mediabunny/aac-encoder': '1.42.0',
'@mediabunny/flac-encoder': '1.42.0',
mediabunny: '1.45.0',
'@mediabunny/ac3': '1.45.0',
'@mediabunny/mp3-encoder': '1.45.0',
'@mediabunny/aac-encoder': '1.45.0',
'@mediabunny/flac-encoder': '1.45.0',
zod: '4.3.6',
};

Expand Down
1 change: 0 additions & 1 deletion packages/cloudrun/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"version": "4.0.461",
"description": "Render Remotion videos on Google Cloud Run",
"main": "dist/index.js",
"sideEffects": false,
"scripts": {
"make": "tsgo -d && cp src/shared/sa-permissions.json dist/shared/sa-permissions.json",
"makeruntime": "bun build.ts",
Expand Down
1 change: 0 additions & 1 deletion packages/compositor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"name": "@remotion/compositor",
"version": "4.0.461",
"description": "Rust binary for Remotion",
"sideEffects": false,
"scripts": {
"build-all": "bun build.ts --all"
},
Expand Down
1 change: 0 additions & 1 deletion packages/convert/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"name": "@remotion/convert",
"version": "4.0.461",
"private": true,
"sideEffects": false,
"type": "module",
"author": "Jonny Burger <jonny@remotion.dev>, Hunain Ahmed <junaidhunain6@gmail.com>",
"scripts": {
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/effects/Solid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ export const Solid: React.FC<SolidProps> = ({
}, [
frame,
color,
experimentalEffects,
outputCanvas,
sourceCanvas,
chainState,
Expand Down
29 changes: 29 additions & 0 deletions packages/core/src/effects/create-effect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type {EffectDefinition, EffectDescriptor} from './effect-types.js';

type EffectFactory<P> = {} extends P
? (params?: P) => EffectDescriptor<unknown>
: (params: P) => EffectDescriptor<unknown>;

// Defines an effect and returns a factory that produces per-frame descriptors.
// The returned function is the public API effect authors expose to users:
//
// export const blur = createEffect<BlurParams, BlurState>({ ... });
// // usage: blur({ radius: 4 })
//
// The descriptor erases `P` and `S` to `unknown` so descriptors of different
// effects can be freely composed inside `EffectsProp` arrays. Without that
// erasure the descriptor would be contravariant in `P` (via `apply`'s
// argument) and concrete descriptors could not flow into `unknown` slots.
export const createEffect = <P, S>(
definition: EffectDefinition<P, S>,
): EffectFactory<P> => {
const widened = definition as unknown as EffectDefinition<unknown, unknown>;
const factory = (params: P = {} as P): EffectDescriptor<unknown> => ({
definition: widened,
params,
stack: new Error().stack!,
effectKey: widened.calculateKey(params),
memoized: false,
});
return factory as EffectFactory<P>;
};
34 changes: 0 additions & 34 deletions packages/core/src/effects/define-effect.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/core/src/effects/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Types needed outside core for `_experimentalEffects` / `@remotion/effects` typing.
// Types needed outside core for `_experimentalEffects` / `@remotion/effects/*` typing.
export type {
EffectDefinitionAndStack,
EffectDescriptor,
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ export {interpolateColors} from './interpolate-colors.js';
export {LogLevel} from './log.js';
export {Loop} from './loop/index.js';
export {
assertValidInterpolateEasingOption,
EasingFunction,
ExtrapolateType,
interpolate,
Expand Down
5 changes: 2 additions & 3 deletions packages/core/src/internals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import {
EditorPropsProvider,
timeValueRef,
} from './EditorProps.js';
import {createDescriptor, defineEffect} from './effects/define-effect.js';
import {createEffect} from './effects/create-effect.js';
import {flattenEffects} from './effects/effect-internals.js';
import {runEffectChain} from './effects/run-effect-chain.js';
import {useEffectChainState} from './effects/use-effect-chain-state.js';
Expand Down Expand Up @@ -327,8 +327,7 @@ export const Internals = {
useEffectChainState,
runEffectChain,
useMemoizedEffects,
defineEffect,
createDescriptor,
createEffect,
computeEffectiveSchemaValuesDotNotation,
OverrideIdsToNodePathsGettersContext,
OverrideIdsToNodePathsSettersContext,
Expand Down
55 changes: 51 additions & 4 deletions packages/core/src/interpolate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,22 @@ export type ExtrapolateType = 'extend' | 'identity' | 'clamp' | 'wrap';
export type EasingFunction = (input: number) => number;

export type InterpolateOptions = Partial<{
easing: EasingFunction;
easing: EasingFunction | readonly EasingFunction[];
extrapolateLeft: ExtrapolateType;
extrapolateRight: ExtrapolateType;
}>;

type InterpolateSegmentResolvedOptions = {
easing: EasingFunction;
extrapolateLeft: ExtrapolateType;
extrapolateRight: ExtrapolateType;
};

function interpolateFunction(
input: number,
inputRange: [number, number],
outputRange: [number, number],
options: Required<InterpolateOptions>,
options: InterpolateSegmentResolvedOptions,
): number {
const {extrapolateLeft, extrapolateRight, easing} = options;

Expand Down Expand Up @@ -114,6 +120,32 @@ function checkInfiniteRange(name: string, arr: readonly number[]) {
}
}

export function assertValidInterpolateEasingOption(
easing: EasingFunction | readonly EasingFunction[] | undefined,
inputRangeLength: number,
) {
if (easing === undefined) {
return;
}

if (typeof easing === 'function') {
return;
}

const expectedLength = inputRangeLength - 1;
if (easing.length !== expectedLength) {
throw new Error(
`When easing is an array, it must have one entry per segment between keyframes (length inputRange.length - 1 = ${expectedLength}), but got length ${easing.length}`,
);
}

for (let i = 0; i < easing.length; i++) {
if (typeof easing[i] !== 'function') {
throw new Error(`easing[${i}] must be a function`);
}
}
}

/*
* @description Allows you to map a range of values to another using a concise syntax.
* @see [Documentation](https://remotion.dev/docs/interpolate)
Expand Down Expand Up @@ -151,7 +183,22 @@ export function interpolate(

checkValidInputRange(inputRange);

const easing = options?.easing ?? ((num: number): number => num);
assertValidInterpolateEasingOption(options?.easing, inputRange.length);

const easingOption = options?.easing;
const defaultEasing = (num: number): number => num;
const resolveEasingForSegment = (segmentIndex: number): EasingFunction => {
if (easingOption === undefined) {
return defaultEasing;
}

if (typeof easingOption === 'function') {
return easingOption;
}

// `segmentIndex` is in [0, inputRange.length - 2]; array length was validated above.
return easingOption[segmentIndex] as EasingFunction;
};

let extrapolateLeft: ExtrapolateType = 'extend';
if (options?.extrapolateLeft !== undefined) {
Expand All @@ -173,7 +220,7 @@ export function interpolate(
[inputRange[range], inputRange[range + 1]],
[outputRange[range], outputRange[range + 1]],
{
easing,
easing: resolveEasingForSegment(range),
extrapolateLeft,
extrapolateRight,
},
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/no-react.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export type {
} from './CompositionManager';
export {DownloadBehavior} from './download-behavior';
export {
assertValidInterpolateEasingOption,
EasingFunction,
ExtrapolateType,
interpolate,
Expand Down
Loading
Loading