@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 +5 -3
- package/dist/cjs/Gif.js +13 -5
- package/dist/cjs/GifForDevelopment.d.ts +4 -1
- package/dist/cjs/GifForDevelopment.js +2 -2
- package/dist/cjs/GifForRendering.d.ts +4 -1
- package/dist/cjs/GifForRendering.js +2 -2
- package/dist/cjs/canvas.d.ts +2 -0
- package/dist/cjs/canvas.js +119 -16
- package/dist/esm/index.mjs +145 -29
- package/package.json +3 -3
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.
|
|
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 =
|
|
52
|
+
exports.Gif = wrapInSchema(GifInner, gifSchema);
|
|
45
53
|
exports.Gif.displayName = 'Gif';
|
|
46
|
-
|
|
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 &
|
|
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 &
|
|
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
|
});
|
package/dist/cjs/canvas.d.ts
CHANGED
|
@@ -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 {};
|
package/dist/cjs/canvas.js
CHANGED
|
@@ -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
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
|
-
|
|
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
|
});
|
package/dist/esm/index.mjs
CHANGED
|
@@ -820,7 +820,7 @@ var getGifDurationInSeconds = async (src2) => {
|
|
|
820
820
|
};
|
|
821
821
|
// src/Gif.tsx
|
|
822
822
|
import {
|
|
823
|
-
Internals as
|
|
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
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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 } =
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
...
|
|
1254
|
-
hidden:
|
|
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 =
|
|
1421
|
+
var Gif = wrapInSchema(GifInner, gifSchema);
|
|
1306
1422
|
Gif.displayName = "Gif";
|
|
1307
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
},
|