@remotion/gif 4.0.463 → 4.0.465

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/cjs/Gif.d.ts CHANGED
@@ -1,11 +1,13 @@
1
1
  import React from 'react';
2
- import { type SequenceControls, type SequenceProps } from 'remotion';
2
+ import { type EffectsProp, type SequenceControls, type SequenceProps } from 'remotion';
3
3
  import type { RemotionGifProps } from './props';
4
- export type GifProps = Omit<SequenceProps, 'children' | 'durationInFrames' | 'layout'> & RemotionGifProps & {
4
+ export type GifProps = Omit<SequenceProps, 'children' | 'durationInFrames' | 'layout' | '_remotionInternalEffects'> & RemotionGifProps & {
5
5
  readonly durationInFrames?: number;
6
+ readonly effects?: EffectsProp;
6
7
  };
7
- export declare const Gif: React.ComponentType<Omit<SequenceProps, "children" | "durationInFrames" | "layout"> & RemotionGifProps & {
8
+ export declare const Gif: React.ComponentType<Omit<SequenceProps, "_remotionInternalEffects" | "children" | "durationInFrames" | "layout"> & RemotionGifProps & {
8
9
  readonly durationInFrames?: number | undefined;
10
+ readonly effects?: EffectsProp | undefined;
9
11
  } & {
10
12
  readonly _experimentalControls?: SequenceControls | undefined;
11
13
  readonly ref?: React.Ref<HTMLCanvasElement> | undefined;
package/dist/cjs/Gif.js CHANGED
@@ -5,6 +5,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const remotion_1 = require("remotion");
6
6
  const GifForDevelopment_1 = require("./GifForDevelopment");
7
7
  const GifForRendering_1 = require("./GifForRendering");
8
+ const { addSequenceStackTraces, useMemoizedEffectDefinitions, useMemoizedEffects, wrapInSchema, } = remotion_1.Internals;
8
9
  /*
9
10
  * @description Displays a GIF that synchronizes with Remotions useCurrentFrame().
10
11
  * @see [Documentation](https://remotion.dev/docs/gif)
@@ -18,13 +19,19 @@ const gifSchema = {
18
19
  default: 1,
19
20
  description: 'Playback Rate',
20
21
  },
21
- ...remotion_1.Internals.sequenceStyleSchema,
22
+ ...remotion_1.Internals.sequenceVisualStyleSchema,
22
23
  hidden: remotion_1.Internals.hiddenField,
23
24
  };
24
- const GifInner = ({ src, width, height, onLoad, onError, fit, playbackRate, loopBehavior, id, delayRenderTimeoutInMilliseconds, durationInFrames, style, _experimentalControls: controls, ref, ...sequenceProps }) => {
25
+ const GifInner = ({ src, width, height, onLoad, onError, fit, playbackRate, loopBehavior, id, delayRenderTimeoutInMilliseconds, durationInFrames, style, _experimentalControls: controls, effects = [], ref, ...sequenceProps }) => {
26
+ var _a;
25
27
  const env = (0, remotion_1.useRemotionEnvironment)();
26
28
  const { durationInFrames: videoDuration } = (0, remotion_1.useVideoConfig)();
27
29
  const resolvedDuration = durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : videoDuration;
30
+ const memoizedEffectDefinitions = useMemoizedEffectDefinitions(effects);
31
+ const memoizedEffects = useMemoizedEffects({
32
+ effects,
33
+ overrideId: (_a = controls === null || controls === void 0 ? void 0 : controls.overrideId) !== null && _a !== void 0 ? _a : null,
34
+ });
28
35
  const gifProps = {
29
36
  src,
30
37
  width,
@@ -37,10 +44,11 @@ const GifInner = ({ src, width, height, onLoad, onError, fit, playbackRate, loop
37
44
  id,
38
45
  delayRenderTimeoutInMilliseconds,
39
46
  style,
47
+ effects: memoizedEffects,
40
48
  };
41
49
  const inner = env.isRendering ? (jsx_runtime_1.jsx(GifForRendering_1.GifForRendering, { ...gifProps, ref: ref })) : (jsx_runtime_1.jsx(GifForDevelopment_1.GifForDevelopment, { ...gifProps, ref: ref }));
42
- return (jsx_runtime_1.jsx(remotion_1.Sequence, { layout: "none", durationInFrames: resolvedDuration, name: "<Gif>", _experimentalControls: controls, ...sequenceProps, children: inner }));
50
+ return (jsx_runtime_1.jsx(remotion_1.Sequence, { layout: "none", durationInFrames: resolvedDuration, name: "<Gif>", _experimentalControls: controls, _remotionInternalEffects: memoizedEffectDefinitions, ...sequenceProps, children: inner }));
43
51
  };
44
- exports.Gif = remotion_1.Internals.wrapInSchema(GifInner, gifSchema);
52
+ exports.Gif = wrapInSchema(GifInner, gifSchema);
45
53
  exports.Gif.displayName = 'Gif';
46
- remotion_1.Internals.addSequenceStackTraces(exports.Gif);
54
+ addSequenceStackTraces(exports.Gif);
@@ -1,2 +1,5 @@
1
+ import type { EffectDefinitionAndStack } from 'remotion';
1
2
  import type { RemotionGifProps } from './props';
2
- export declare const GifForDevelopment: import("react").ForwardRefExoticComponent<RemotionGifProps & import("react").RefAttributes<HTMLCanvasElement>>;
3
+ export declare const GifForDevelopment: import("react").ForwardRefExoticComponent<RemotionGifProps & {
4
+ readonly effects: EffectDefinitionAndStack<unknown>[];
5
+ } & import("react").RefAttributes<HTMLCanvasElement>>;
@@ -10,7 +10,7 @@ const is_cors_error_1 = require("./is-cors-error");
10
10
  const react_tools_1 = require("./react-tools");
11
11
  const resolve_gif_source_1 = require("./resolve-gif-source");
12
12
  const useCurrentGifIndex_1 = require("./useCurrentGifIndex");
13
- exports.GifForDevelopment = (0, react_1.forwardRef)(({ src, width, height, onError, loopBehavior = 'loop', playbackRate = 1, onLoad, fit = 'fill', ...props }, ref) => {
13
+ exports.GifForDevelopment = (0, react_1.forwardRef)(({ src, width, height, onError, loopBehavior = 'loop', playbackRate = 1, onLoad, fit = 'fill', effects, ...props }, ref) => {
14
14
  const resolvedSrc = (0, resolve_gif_source_1.resolveGifSource)(src);
15
15
  const [state, update] = (0, react_1.useState)(() => {
16
16
  var _a;
@@ -75,5 +75,5 @@ exports.GifForDevelopment = (0, react_1.forwardRef)(({ src, width, height, onErr
75
75
  if (index === -1) {
76
76
  return null;
77
77
  }
78
- return (jsx_runtime_1.jsx(canvas_1.Canvas, { fit: fit, index: index, frames: state.frames, width: width, height: height, ...props, ref: ref }));
78
+ return (jsx_runtime_1.jsx(canvas_1.Canvas, { fit: fit, index: index, frames: state.frames, width: width, height: height, effects: effects, ...props, ref: ref }));
79
79
  });
@@ -1,2 +1,5 @@
1
+ import type { EffectDefinitionAndStack } from 'remotion';
1
2
  import type { RemotionGifProps } from './props';
2
- export declare const GifForRendering: import("react").ForwardRefExoticComponent<RemotionGifProps & import("react").RefAttributes<HTMLCanvasElement>>;
3
+ export declare const GifForRendering: import("react").ForwardRefExoticComponent<RemotionGifProps & {
4
+ readonly effects: EffectDefinitionAndStack<unknown>[];
5
+ } & import("react").RefAttributes<HTMLCanvasElement>>;
@@ -10,7 +10,7 @@ const is_cors_error_1 = require("./is-cors-error");
10
10
  const react_tools_1 = require("./react-tools");
11
11
  const resolve_gif_source_1 = require("./resolve-gif-source");
12
12
  const useCurrentGifIndex_1 = require("./useCurrentGifIndex");
13
- exports.GifForRendering = (0, react_1.forwardRef)(({ src, width, height, onLoad, onError, loopBehavior = 'loop', playbackRate = 1, fit = 'fill', delayRenderTimeoutInMilliseconds, ...props }, ref) => {
13
+ exports.GifForRendering = (0, react_1.forwardRef)(({ src, width, height, onLoad, onError, loopBehavior = 'loop', playbackRate = 1, fit = 'fill', delayRenderTimeoutInMilliseconds, effects, ...props }, ref) => {
14
14
  const resolvedSrc = (0, resolve_gif_source_1.resolveGifSource)(src);
15
15
  const { delayRender, continueRender } = (0, remotion_1.useDelayRender)();
16
16
  const [state, update] = (0, react_1.useState)(() => {
@@ -103,5 +103,5 @@ exports.GifForRendering = (0, react_1.forwardRef)(({ src, width, height, onLoad,
103
103
  if (index === -1) {
104
104
  return null;
105
105
  }
106
- return (jsx_runtime_1.jsx(canvas_1.Canvas, { fit: fit, index: index, frames: state.frames, width: width, height: height, ...props, ref: ref }));
106
+ return (jsx_runtime_1.jsx(canvas_1.Canvas, { fit: fit, index: index, frames: state.frames, width: width, height: height, effects: effects, ...props, ref: ref }));
107
107
  });
@@ -1,3 +1,4 @@
1
+ import type { EffectDefinitionAndStack } from 'remotion';
1
2
  import type { GifFillMode } from './props';
2
3
  type Props = {
3
4
  readonly index: number;
@@ -7,6 +8,7 @@ type Props = {
7
8
  readonly fit: GifFillMode;
8
9
  readonly className?: string;
9
10
  readonly style?: React.CSSProperties;
11
+ readonly effects: EffectDefinitionAndStack<unknown>[];
10
12
  };
11
13
  export declare const Canvas: import("react").ForwardRefExoticComponent<Props & import("react").RefAttributes<unknown>>;
12
14
  export {};
@@ -4,7 +4,9 @@ exports.Canvas = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  /* eslint-disable react/require-default-props */
6
6
  const react_1 = require("react");
7
+ const remotion_1 = require("remotion");
7
8
  const use_element_size_1 = require("./use-element-size");
9
+ const { runEffectChain, useEffectChainState } = remotion_1.Internals;
8
10
  const calcArgs = (fit, frameSize, canvasSize) => {
9
11
  switch (fit) {
10
12
  case 'fill': {
@@ -63,35 +65,136 @@ const makeCanvas = () => {
63
65
  canvas.height = 0;
64
66
  return ctx;
65
67
  };
66
- exports.Canvas = (0, react_1.forwardRef)(({ index, frames, width, height, fit, className, style }, ref) => {
68
+ exports.Canvas = (0, react_1.forwardRef)(({ index, frames, width, height, fit, className, style, effects }, ref) => {
67
69
  const canvasRef = (0, react_1.useRef)(null);
68
70
  const [tempCtx] = (0, react_1.useState)(() => {
69
71
  return makeCanvas();
70
72
  });
73
+ const sourceCanvas = (0, react_1.useMemo)(() => {
74
+ if (typeof document === 'undefined') {
75
+ return null;
76
+ }
77
+ return document.createElement('canvas');
78
+ }, []);
79
+ const effectOutputCanvas = (0, react_1.useMemo)(() => {
80
+ if (typeof document === 'undefined') {
81
+ return null;
82
+ }
83
+ return document.createElement('canvas');
84
+ }, []);
85
+ const chainState = useEffectChainState();
86
+ const { delayRender, continueRender, cancelRender } = (0, remotion_1.useDelayRender)();
71
87
  const size = (0, use_element_size_1.useElementSize)(canvasRef);
72
88
  (0, react_1.useImperativeHandle)(ref, () => {
73
89
  return canvasRef.current;
74
90
  }, []);
75
91
  (0, react_1.useEffect)(() => {
76
- var _a;
77
92
  if (!size) {
78
93
  return;
79
94
  }
80
95
  const imageData = frames[index];
81
- const ctx = (_a = canvasRef.current) === null || _a === void 0 ? void 0 : _a.getContext('2d');
82
- if (imageData && tempCtx && ctx) {
83
- if (tempCtx.canvas.width < imageData.width ||
84
- tempCtx.canvas.height < imageData.height) {
85
- tempCtx.canvas.width = imageData.width;
86
- tempCtx.canvas.height = imageData.height;
87
- }
88
- if (size.width > 0 && size.height > 0) {
89
- ctx.clearRect(0, 0, size.width, size.height);
90
- tempCtx.clearRect(0, 0, tempCtx.canvas.width, tempCtx.canvas.height);
91
- }
92
- tempCtx.putImageData(imageData, 0, 0);
93
- ctx.drawImage(tempCtx.canvas, ...calcArgs(fit, imageData, { width: size.width, height: size.height }));
96
+ const outputCanvas = canvasRef.current;
97
+ const outputCtx = outputCanvas === null || outputCanvas === void 0 ? void 0 : outputCanvas.getContext('2d');
98
+ if (!imageData || !tempCtx || !outputCtx || !outputCanvas) {
99
+ return;
100
+ }
101
+ if (tempCtx.canvas.width < imageData.width ||
102
+ tempCtx.canvas.height < imageData.height) {
103
+ tempCtx.canvas.width = imageData.width;
104
+ tempCtx.canvas.height = imageData.height;
105
+ }
106
+ const layoutWidth = width !== null && width !== void 0 ? width : size.width;
107
+ const layoutHeight = height !== null && height !== void 0 ? height : size.height;
108
+ if (layoutWidth <= 0 || layoutHeight <= 0) {
109
+ return;
110
+ }
111
+ if (size.width > 0 && size.height > 0) {
112
+ outputCtx.clearRect(0, 0, size.width, size.height);
113
+ tempCtx.clearRect(0, 0, tempCtx.canvas.width, tempCtx.canvas.height);
94
114
  }
95
- }, [index, frames, fit, tempCtx, size]);
115
+ tempCtx.putImageData(imageData, 0, 0);
116
+ const frameSize = {
117
+ width: imageData.width,
118
+ height: imageData.height,
119
+ };
120
+ const layoutSize = {
121
+ width: layoutWidth,
122
+ height: layoutHeight,
123
+ };
124
+ if (effects.length === 0) {
125
+ outputCtx.drawImage(tempCtx.canvas, ...calcArgs(fit, frameSize, layoutSize));
126
+ return;
127
+ }
128
+ if (!sourceCanvas || !effectOutputCanvas) {
129
+ return;
130
+ }
131
+ // Effects run at the GIF's intrinsic pixel dimensions; fit is applied
132
+ // when compositing onto the layout-sized output canvas.
133
+ if (sourceCanvas.width !== frameSize.width ||
134
+ sourceCanvas.height !== frameSize.height) {
135
+ sourceCanvas.width = frameSize.width;
136
+ sourceCanvas.height = frameSize.height;
137
+ }
138
+ if (effectOutputCanvas.width !== frameSize.width ||
139
+ effectOutputCanvas.height !== frameSize.height) {
140
+ effectOutputCanvas.width = frameSize.width;
141
+ effectOutputCanvas.height = frameSize.height;
142
+ }
143
+ const sourceCtx = sourceCanvas.getContext('2d');
144
+ if (!sourceCtx) {
145
+ return;
146
+ }
147
+ sourceCtx.clearRect(0, 0, frameSize.width, frameSize.height);
148
+ sourceCtx.putImageData(imageData, 0, 0);
149
+ const state = chainState.get(frameSize.width, frameSize.height);
150
+ if (!state) {
151
+ return;
152
+ }
153
+ if (outputCanvas.width !== layoutWidth ||
154
+ outputCanvas.height !== layoutHeight) {
155
+ outputCanvas.width = layoutWidth;
156
+ outputCanvas.height = layoutHeight;
157
+ }
158
+ const effectChainHandle = delayRender('Rendering <Gif/> effect chain');
159
+ let cancelled = false;
160
+ runEffectChain({
161
+ state,
162
+ source: sourceCanvas,
163
+ effects,
164
+ output: effectOutputCanvas,
165
+ width: frameSize.width,
166
+ height: frameSize.height,
167
+ })
168
+ .then((completed) => {
169
+ if (cancelled || !completed) {
170
+ return;
171
+ }
172
+ outputCtx.clearRect(0, 0, layoutWidth, layoutHeight);
173
+ outputCtx.drawImage(effectOutputCanvas, ...calcArgs(fit, frameSize, layoutSize));
174
+ continueRender(effectChainHandle);
175
+ })
176
+ .catch((err) => {
177
+ cancelRender(err);
178
+ });
179
+ return () => {
180
+ cancelled = true;
181
+ continueRender(effectChainHandle);
182
+ };
183
+ }, [
184
+ index,
185
+ frames,
186
+ fit,
187
+ tempCtx,
188
+ size,
189
+ width,
190
+ height,
191
+ effects,
192
+ sourceCanvas,
193
+ effectOutputCanvas,
194
+ chainState,
195
+ delayRender,
196
+ continueRender,
197
+ cancelRender,
198
+ ]);
96
199
  return (jsx_runtime_1.jsx("canvas", { ref: canvasRef, className: className, style: style, width: width !== null && width !== void 0 ? width : size === null || size === void 0 ? void 0 : size.width, height: height !== null && height !== void 0 ? height : size === null || size === void 0 ? void 0 : size.height }));
97
200
  });
@@ -820,7 +820,7 @@ var getGifDurationInSeconds = async (src2) => {
820
820
  };
821
821
  // src/Gif.tsx
822
822
  import {
823
- Internals as Internals2,
823
+ Internals as Internals3,
824
824
  Sequence,
825
825
  useRemotionEnvironment,
826
826
  useVideoConfig as useVideoConfig2
@@ -834,9 +834,11 @@ import {
834
834
  forwardRef,
835
835
  useEffect as useEffect2,
836
836
  useImperativeHandle,
837
+ useMemo as useMemo2,
837
838
  useRef,
838
839
  useState as useState2
839
840
  } from "react";
841
+ import { Internals, useDelayRender } from "remotion";
840
842
 
841
843
  // src/use-element-size.ts
842
844
  import { useCallback, useEffect, useMemo, useState } from "react";
@@ -903,6 +905,7 @@ var useElementSize = (ref) => {
903
905
 
904
906
  // src/canvas.tsx
905
907
  import { jsx } from "react/jsx-runtime";
908
+ var { runEffectChain, useEffectChainState } = Internals;
906
909
  var calcArgs = (fit, frameSize, canvasSize) => {
907
910
  switch (fit) {
908
911
  case "fill": {
@@ -961,11 +964,25 @@ var makeCanvas = () => {
961
964
  canvas.height = 0;
962
965
  return ctx;
963
966
  };
964
- var Canvas = forwardRef(({ index, frames, width, height, fit, className, style }, ref) => {
967
+ var Canvas = forwardRef(({ index, frames, width, height, fit, className, style, effects }, ref) => {
965
968
  const canvasRef = useRef(null);
966
969
  const [tempCtx] = useState2(() => {
967
970
  return makeCanvas();
968
971
  });
972
+ const sourceCanvas = useMemo2(() => {
973
+ if (typeof document === "undefined") {
974
+ return null;
975
+ }
976
+ return document.createElement("canvas");
977
+ }, []);
978
+ const effectOutputCanvas = useMemo2(() => {
979
+ if (typeof document === "undefined") {
980
+ return null;
981
+ }
982
+ return document.createElement("canvas");
983
+ }, []);
984
+ const chainState = useEffectChainState();
985
+ const { delayRender, continueRender, cancelRender } = useDelayRender();
969
986
  const size = useElementSize(canvasRef);
970
987
  useImperativeHandle(ref, () => {
971
988
  return canvasRef.current;
@@ -975,20 +992,101 @@ var Canvas = forwardRef(({ index, frames, width, height, fit, className, style }
975
992
  return;
976
993
  }
977
994
  const imageData = frames[index];
978
- const ctx = canvasRef.current?.getContext("2d");
979
- if (imageData && tempCtx && ctx) {
980
- if (tempCtx.canvas.width < imageData.width || tempCtx.canvas.height < imageData.height) {
981
- tempCtx.canvas.width = imageData.width;
982
- tempCtx.canvas.height = imageData.height;
983
- }
984
- if (size.width > 0 && size.height > 0) {
985
- ctx.clearRect(0, 0, size.width, size.height);
986
- tempCtx.clearRect(0, 0, tempCtx.canvas.width, tempCtx.canvas.height);
987
- }
988
- tempCtx.putImageData(imageData, 0, 0);
989
- ctx.drawImage(tempCtx.canvas, ...calcArgs(fit, imageData, { width: size.width, height: size.height }));
995
+ const outputCanvas = canvasRef.current;
996
+ const outputCtx = outputCanvas?.getContext("2d");
997
+ if (!imageData || !tempCtx || !outputCtx || !outputCanvas) {
998
+ return;
999
+ }
1000
+ if (tempCtx.canvas.width < imageData.width || tempCtx.canvas.height < imageData.height) {
1001
+ tempCtx.canvas.width = imageData.width;
1002
+ tempCtx.canvas.height = imageData.height;
1003
+ }
1004
+ const layoutWidth = width ?? size.width;
1005
+ const layoutHeight = height ?? size.height;
1006
+ if (layoutWidth <= 0 || layoutHeight <= 0) {
1007
+ return;
1008
+ }
1009
+ if (size.width > 0 && size.height > 0) {
1010
+ outputCtx.clearRect(0, 0, size.width, size.height);
1011
+ tempCtx.clearRect(0, 0, tempCtx.canvas.width, tempCtx.canvas.height);
1012
+ }
1013
+ tempCtx.putImageData(imageData, 0, 0);
1014
+ const frameSize = {
1015
+ width: imageData.width,
1016
+ height: imageData.height
1017
+ };
1018
+ const layoutSize = {
1019
+ width: layoutWidth,
1020
+ height: layoutHeight
1021
+ };
1022
+ if (effects.length === 0) {
1023
+ outputCtx.drawImage(tempCtx.canvas, ...calcArgs(fit, frameSize, layoutSize));
1024
+ return;
1025
+ }
1026
+ if (!sourceCanvas || !effectOutputCanvas) {
1027
+ return;
1028
+ }
1029
+ if (sourceCanvas.width !== frameSize.width || sourceCanvas.height !== frameSize.height) {
1030
+ sourceCanvas.width = frameSize.width;
1031
+ sourceCanvas.height = frameSize.height;
1032
+ }
1033
+ if (effectOutputCanvas.width !== frameSize.width || effectOutputCanvas.height !== frameSize.height) {
1034
+ effectOutputCanvas.width = frameSize.width;
1035
+ effectOutputCanvas.height = frameSize.height;
990
1036
  }
991
- }, [index, frames, fit, tempCtx, size]);
1037
+ const sourceCtx = sourceCanvas.getContext("2d");
1038
+ if (!sourceCtx) {
1039
+ return;
1040
+ }
1041
+ sourceCtx.clearRect(0, 0, frameSize.width, frameSize.height);
1042
+ sourceCtx.putImageData(imageData, 0, 0);
1043
+ const state = chainState.get(frameSize.width, frameSize.height);
1044
+ if (!state) {
1045
+ return;
1046
+ }
1047
+ if (outputCanvas.width !== layoutWidth || outputCanvas.height !== layoutHeight) {
1048
+ outputCanvas.width = layoutWidth;
1049
+ outputCanvas.height = layoutHeight;
1050
+ }
1051
+ const effectChainHandle = delayRender("Rendering <Gif/> effect chain");
1052
+ let cancelled = false;
1053
+ runEffectChain({
1054
+ state,
1055
+ source: sourceCanvas,
1056
+ effects,
1057
+ output: effectOutputCanvas,
1058
+ width: frameSize.width,
1059
+ height: frameSize.height
1060
+ }).then((completed) => {
1061
+ if (cancelled || !completed) {
1062
+ return;
1063
+ }
1064
+ outputCtx.clearRect(0, 0, layoutWidth, layoutHeight);
1065
+ outputCtx.drawImage(effectOutputCanvas, ...calcArgs(fit, frameSize, layoutSize));
1066
+ continueRender(effectChainHandle);
1067
+ }).catch((err) => {
1068
+ cancelRender(err);
1069
+ });
1070
+ return () => {
1071
+ cancelled = true;
1072
+ continueRender(effectChainHandle);
1073
+ };
1074
+ }, [
1075
+ index,
1076
+ frames,
1077
+ fit,
1078
+ tempCtx,
1079
+ size,
1080
+ width,
1081
+ height,
1082
+ effects,
1083
+ sourceCanvas,
1084
+ effectOutputCanvas,
1085
+ chainState,
1086
+ delayRender,
1087
+ continueRender,
1088
+ cancelRender
1089
+ ]);
992
1090
  return /* @__PURE__ */ jsx("canvas", {
993
1091
  ref: canvasRef,
994
1092
  className,
@@ -1004,7 +1102,7 @@ var isCorsError = (error) => {
1004
1102
  };
1005
1103
 
1006
1104
  // src/useCurrentGifIndex.tsx
1007
- import { useMemo as useMemo2 } from "react";
1105
+ import { useMemo as useMemo3 } from "react";
1008
1106
  import { useCurrentFrame, useVideoConfig } from "remotion";
1009
1107
  function useCurrentGifIndex({
1010
1108
  delays,
@@ -1013,7 +1111,7 @@ function useCurrentGifIndex({
1013
1111
  }) {
1014
1112
  const currentFrame = useCurrentFrame();
1015
1113
  const videoConfig = useVideoConfig();
1016
- const duration = useMemo2(() => {
1114
+ const duration = useMemo3(() => {
1017
1115
  if (delays.length !== 0) {
1018
1116
  return delays.reduce((sum, delay) => sum + (delay ?? 0), 0);
1019
1117
  }
@@ -1052,6 +1150,7 @@ var GifForDevelopment = forwardRef2(({
1052
1150
  playbackRate = 1,
1053
1151
  onLoad,
1054
1152
  fit = "fill",
1153
+ effects,
1055
1154
  ...props
1056
1155
  }, ref) => {
1057
1156
  const resolvedSrc = resolveGifSource(src2);
@@ -1119,6 +1218,7 @@ var GifForDevelopment = forwardRef2(({
1119
1218
  frames: state.frames,
1120
1219
  width,
1121
1220
  height,
1221
+ effects,
1122
1222
  ...props,
1123
1223
  ref
1124
1224
  });
@@ -1126,7 +1226,7 @@ var GifForDevelopment = forwardRef2(({
1126
1226
 
1127
1227
  // src/GifForRendering.tsx
1128
1228
  import { forwardRef as forwardRef3, useEffect as useEffect4, useRef as useRef3, useState as useState4 } from "react";
1129
- import { Internals, useDelayRender } from "remotion";
1229
+ import { Internals as Internals2, useDelayRender as useDelayRender2 } from "remotion";
1130
1230
  import { jsx as jsx3 } from "react/jsx-runtime";
1131
1231
  var GifForRendering = forwardRef3(({
1132
1232
  src: src2,
@@ -1138,10 +1238,11 @@ var GifForRendering = forwardRef3(({
1138
1238
  playbackRate = 1,
1139
1239
  fit = "fill",
1140
1240
  delayRenderTimeoutInMilliseconds,
1241
+ effects,
1141
1242
  ...props
1142
1243
  }, ref) => {
1143
1244
  const resolvedSrc = resolveGifSource(src2);
1144
- const { delayRender, continueRender } = useDelayRender();
1245
+ const { delayRender, continueRender } = useDelayRender2();
1145
1246
  const [state, update] = useState4(() => {
1146
1247
  const parsedGif = volatileGifCache.get(resolvedSrc);
1147
1248
  if (parsedGif === undefined) {
@@ -1158,7 +1259,7 @@ var GifForRendering = forwardRef3(({
1158
1259
  const [renderHandle] = useState4(() => delayRender(`Rendering <Gif/> with src="${resolvedSrc}"`, {
1159
1260
  timeoutInMilliseconds: delayRenderTimeoutInMilliseconds
1160
1261
  }));
1161
- const logLevel = Internals.useLogLevel();
1262
+ const logLevel = Internals2.useLogLevel();
1162
1263
  useEffect4(() => {
1163
1264
  return () => {
1164
1265
  continueRender(renderHandle);
@@ -1180,10 +1281,10 @@ var GifForRendering = forwardRef3(({
1180
1281
  const newHandle = delayRender("Loading <Gif /> with src=" + resolvedSrc, {
1181
1282
  timeoutInMilliseconds: delayRenderTimeoutInMilliseconds
1182
1283
  });
1183
- Internals.Log.verbose({ logLevel, tag: null }, "Loading GIF with source", resolvedSrc);
1284
+ Internals2.Log.verbose({ logLevel, tag: null }, "Loading GIF with source", resolvedSrc);
1184
1285
  const time = Date.now();
1185
1286
  parseGif({ controller, src: resolvedSrc }).then((parsed) => {
1186
- Internals.Log.verbose({ logLevel, tag: null }, "Parsed GIF in", Date.now() - time, "ms");
1287
+ Internals2.Log.verbose({ logLevel, tag: null }, "Parsed GIF in", Date.now() - time, "ms");
1187
1288
  currentOnLoad.current?.(parsed);
1188
1289
  update(parsed);
1189
1290
  volatileGifCache.set(resolvedSrc, parsed);
@@ -1195,7 +1296,7 @@ var GifForRendering = forwardRef3(({
1195
1296
  continueRender(newHandle);
1196
1297
  return;
1197
1298
  }
1198
- Internals.Log.error({ logLevel, tag: null }, "Failed to load GIF", err);
1299
+ Internals2.Log.error({ logLevel, tag: null }, "Failed to load GIF", err);
1199
1300
  if (currentOnError.current) {
1200
1301
  currentOnError.current(err);
1201
1302
  } else {
@@ -1219,7 +1320,7 @@ var GifForRendering = forwardRef3(({
1219
1320
  delayRenderTimeoutInMilliseconds
1220
1321
  ]);
1221
1322
  if (error) {
1222
- Internals.Log.error({ logLevel, tag: null }, error.stack);
1323
+ Internals2.Log.error({ logLevel, tag: null }, error.stack);
1223
1324
  if (isCorsError(error)) {
1224
1325
  throw new Error(`Failed to render GIF with source ${src2}: "${error.message}". You must enable CORS for this URL.`);
1225
1326
  }
@@ -1234,6 +1335,7 @@ var GifForRendering = forwardRef3(({
1234
1335
  frames: state.frames,
1235
1336
  width,
1236
1337
  height,
1338
+ effects,
1237
1339
  ...props,
1238
1340
  ref
1239
1341
  });
@@ -1241,6 +1343,12 @@ var GifForRendering = forwardRef3(({
1241
1343
 
1242
1344
  // src/Gif.tsx
1243
1345
  import { jsx as jsx4 } from "react/jsx-runtime";
1346
+ var {
1347
+ addSequenceStackTraces,
1348
+ useMemoizedEffectDefinitions,
1349
+ useMemoizedEffects,
1350
+ wrapInSchema
1351
+ } = Internals3;
1244
1352
  var gifSchema = {
1245
1353
  playbackRate: {
1246
1354
  type: "number",
@@ -1250,8 +1358,8 @@ var gifSchema = {
1250
1358
  default: 1,
1251
1359
  description: "Playback Rate"
1252
1360
  },
1253
- ...Internals2.sequenceStyleSchema,
1254
- hidden: Internals2.hiddenField
1361
+ ...Internals3.sequenceVisualStyleSchema,
1362
+ hidden: Internals3.hiddenField
1255
1363
  };
1256
1364
  var GifInner = ({
1257
1365
  src: src2,
@@ -1267,12 +1375,18 @@ var GifInner = ({
1267
1375
  durationInFrames,
1268
1376
  style,
1269
1377
  _experimentalControls: controls,
1378
+ effects = [],
1270
1379
  ref,
1271
1380
  ...sequenceProps
1272
1381
  }) => {
1273
1382
  const env = useRemotionEnvironment();
1274
1383
  const { durationInFrames: videoDuration } = useVideoConfig2();
1275
1384
  const resolvedDuration = durationInFrames ?? videoDuration;
1385
+ const memoizedEffectDefinitions = useMemoizedEffectDefinitions(effects);
1386
+ const memoizedEffects = useMemoizedEffects({
1387
+ effects,
1388
+ overrideId: controls?.overrideId ?? null
1389
+ });
1276
1390
  const gifProps = {
1277
1391
  src: src2,
1278
1392
  width,
@@ -1284,7 +1398,8 @@ var GifInner = ({
1284
1398
  loopBehavior,
1285
1399
  id,
1286
1400
  delayRenderTimeoutInMilliseconds,
1287
- style
1401
+ style,
1402
+ effects: memoizedEffects
1288
1403
  };
1289
1404
  const inner = env.isRendering ? /* @__PURE__ */ jsx4(GifForRendering, {
1290
1405
  ...gifProps,
@@ -1298,13 +1413,14 @@ var GifInner = ({
1298
1413
  durationInFrames: resolvedDuration,
1299
1414
  name: "<Gif>",
1300
1415
  _experimentalControls: controls,
1416
+ _remotionInternalEffects: memoizedEffectDefinitions,
1301
1417
  ...sequenceProps,
1302
1418
  children: inner
1303
1419
  });
1304
1420
  };
1305
- var Gif = Internals2.wrapInSchema(GifInner, gifSchema);
1421
+ var Gif = wrapInSchema(GifInner, gifSchema);
1306
1422
  Gif.displayName = "Gif";
1307
- Internals2.addSequenceStackTraces(Gif);
1423
+ addSequenceStackTraces(Gif);
1308
1424
  // src/preload-gif.ts
1309
1425
  var preloadGif = (src2) => {
1310
1426
  const resolvedSrc = resolveGifSource(src2);
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/gif"
4
4
  },
5
5
  "name": "@remotion/gif",
6
- "version": "4.0.463",
6
+ "version": "4.0.465",
7
7
  "description": "Embed GIFs in a Remotion video",
8
8
  "bugs": {
9
9
  "url": "https://github.com/remotion-dev/remotion/issues"
@@ -29,14 +29,14 @@
29
29
  }
30
30
  },
31
31
  "dependencies": {
32
- "remotion": "4.0.463"
32
+ "remotion": "4.0.465"
33
33
  },
34
34
  "devDependencies": {
35
35
  "esbuild": "0.28.0",
36
36
  "react": "19.2.3",
37
37
  "react-dom": "19.2.3",
38
38
  "webpack": "5.105.0",
39
- "@remotion/eslint-config-internal": "4.0.463",
39
+ "@remotion/eslint-config-internal": "4.0.465",
40
40
  "eslint": "9.19.0",
41
41
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
42
42
  },