@remotion/gif 4.0.0-lambda.3 → 4.0.0-newpathfunctions.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/LICENSE.md +8 -8
  2. package/dist/Gif.d.ts +1 -2
  3. package/dist/Gif.js +2 -1
  4. package/dist/GifForDevelopment.d.ts +1 -1
  5. package/dist/GifForDevelopment.js +59 -20
  6. package/dist/GifForRendering.d.ts +1 -1
  7. package/dist/GifForRendering.js +66 -21
  8. package/dist/canvas.d.ts +13 -0
  9. package/dist/canvas.js +96 -0
  10. package/dist/get-gif-duration-in-seconds.d.ts +1 -0
  11. package/dist/get-gif-duration-in-seconds.js +30 -0
  12. package/dist/gif-cache.d.ts +4 -0
  13. package/dist/gif-cache.js +6 -0
  14. package/dist/gifuct/deinterlace.d.ts +4 -0
  15. package/dist/gifuct/deinterlace.js +26 -0
  16. package/dist/gifuct/index.d.ts +4 -0
  17. package/dist/gifuct/index.js +60 -0
  18. package/dist/gifuct/lzw.d.ts +5 -0
  19. package/dist/gifuct/lzw.js +119 -0
  20. package/dist/gifuct/types.d.ts +96 -0
  21. package/dist/gifuct/types.js +2 -0
  22. package/dist/index.d.ts +4 -2
  23. package/dist/index.js +7 -16
  24. package/dist/is-cors-error.d.ts +1 -0
  25. package/dist/is-cors-error.js +13 -0
  26. package/dist/parse-generate.d.ts +18 -0
  27. package/dist/parse-generate.js +96 -0
  28. package/dist/parser/decompress-frames.d.ts +2 -0
  29. package/dist/parser/decompress-frames.js +19 -0
  30. package/dist/preload-gif.d.ts +4 -0
  31. package/dist/preload-gif.js +37 -0
  32. package/dist/props.d.ts +4 -2
  33. package/dist/props.js +0 -0
  34. package/dist/react-tools.d.ts +9 -0
  35. package/dist/react-tools.js +39 -0
  36. package/dist/resolve-gif-source.d.ts +1 -0
  37. package/dist/resolve-gif-source.js +7 -0
  38. package/dist/use-element-size.d.ts +6 -0
  39. package/dist/use-element-size.js +73 -0
  40. package/dist/useCurrentGifIndex.d.ts +2 -2
  41. package/dist/useCurrentGifIndex.js +21 -14
  42. package/dist/worker/index.d.ts +1 -0
  43. package/dist/worker/index.js +12 -0
  44. package/dist/worker/source.d.ts +1 -0
  45. package/dist/worker/source.js +7 -0
  46. package/dist/worker/worker.d.ts +1 -0
  47. package/dist/worker/worker.js +39 -0
  48. package/package.json +11 -12
  49. package/dist/Gif.d.ts.map +0 -1
  50. package/dist/Gif.js.map +0 -1
  51. package/dist/GifForDevelopment.d.ts.map +0 -1
  52. package/dist/GifForDevelopment.js.map +0 -1
  53. package/dist/GifForRendering.d.ts.map +0 -1
  54. package/dist/GifForRendering.js.map +0 -1
  55. package/dist/index.d.ts.map +0 -1
  56. package/dist/index.js.map +0 -1
  57. package/dist/props.d.ts.map +0 -1
  58. package/dist/props.js.map +0 -1
  59. package/dist/useCurrentGifIndex.d.ts.map +0 -1
  60. package/dist/useCurrentGifIndex.js.map +0 -1
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ /* eslint-disable no-multi-assign */
3
+ /* eslint-disable no-redeclare */
4
+ /* eslint-disable no-bitwise */
5
+ /* eslint-disable no-var */
6
+ /**
7
+ * javascript port of java LZW decompression
8
+ * Original java author url: https://gist.github.com/devunwired/4479231
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.lzw = void 0;
12
+ const lzw = (minCodeSize, data, pixelCount) => {
13
+ const MAX_STACK_SIZE = 4096;
14
+ const nullCode = -1;
15
+ const npix = pixelCount;
16
+ let available;
17
+ let code_mask;
18
+ let code_size;
19
+ let in_code;
20
+ let old_code;
21
+ var bits;
22
+ let code;
23
+ let i;
24
+ var datum;
25
+ var first;
26
+ var top;
27
+ var bi;
28
+ var pi;
29
+ const dstPixels = new Array(pixelCount);
30
+ const prefix = new Array(MAX_STACK_SIZE);
31
+ const suffix = new Array(MAX_STACK_SIZE);
32
+ const pixelStack = new Array(MAX_STACK_SIZE + 1);
33
+ // Initialize GIF data stream decoder.
34
+ const data_size = minCodeSize;
35
+ const clear = 1 << data_size;
36
+ const end_of_information = clear + 1;
37
+ available = clear + 2;
38
+ old_code = nullCode;
39
+ code_size = data_size + 1;
40
+ code_mask = (1 << code_size) - 1;
41
+ for (code = 0; code < clear; code++) {
42
+ prefix[code] = 0;
43
+ suffix[code] = code;
44
+ }
45
+ // Decode GIF pixel stream.
46
+ var datum;
47
+ var bits;
48
+ var first;
49
+ var top;
50
+ var pi;
51
+ var bi;
52
+ datum = bits = first = top = pi = bi = 0;
53
+ for (i = 0; i < npix;) {
54
+ if (top === 0) {
55
+ if (bits < code_size) {
56
+ // get the next byte
57
+ datum += data[bi] << bits;
58
+ bits += 8;
59
+ bi++;
60
+ continue;
61
+ }
62
+ // Get the next code.
63
+ code = datum & code_mask;
64
+ datum >>= code_size;
65
+ bits -= code_size;
66
+ // Interpret the code
67
+ if (code > available || code === end_of_information) {
68
+ break;
69
+ }
70
+ if (code === clear) {
71
+ // Reset decoder.
72
+ code_size = data_size + 1;
73
+ code_mask = (1 << code_size) - 1;
74
+ available = clear + 2;
75
+ old_code = nullCode;
76
+ continue;
77
+ }
78
+ if (old_code === nullCode) {
79
+ pixelStack[top++] = suffix[code];
80
+ old_code = code;
81
+ first = code;
82
+ continue;
83
+ }
84
+ in_code = code;
85
+ if (code === available) {
86
+ pixelStack[top++] = first;
87
+ code = old_code;
88
+ }
89
+ while (code > clear) {
90
+ pixelStack[top++] = suffix[code];
91
+ code = prefix[code];
92
+ }
93
+ first = suffix[code] & 0xff;
94
+ pixelStack[top++] = first;
95
+ // add a new string to the table, but only if space is available
96
+ // if not, just continue with current table until a clear code is found
97
+ // (deferred clear code implementation as per GIF spec)
98
+ if (available < MAX_STACK_SIZE) {
99
+ prefix[available] = old_code;
100
+ suffix[available] = first;
101
+ available++;
102
+ if ((available & code_mask) === 0 && available < MAX_STACK_SIZE) {
103
+ code_size++;
104
+ code_mask += available;
105
+ }
106
+ }
107
+ old_code = in_code;
108
+ }
109
+ // Pop a pixel off the pixel stack.
110
+ top--;
111
+ dstPixels[pi++] = pixelStack[top];
112
+ i++;
113
+ }
114
+ for (i = pi; i < npix; i++) {
115
+ dstPixels[i] = 0; // clear missing pixels
116
+ }
117
+ return dstPixels;
118
+ };
119
+ exports.lzw = lzw;
@@ -0,0 +1,96 @@
1
+ declare type Dimensions = {
2
+ top: number;
3
+ left: number;
4
+ width: number;
5
+ height: number;
6
+ };
7
+ declare type Application = {
8
+ application: {
9
+ blockSize: number;
10
+ blocks: number[];
11
+ codes: number[];
12
+ id: string;
13
+ };
14
+ };
15
+ declare type Lct = {
16
+ exists: boolean;
17
+ future: number;
18
+ interlaced: boolean;
19
+ size: number;
20
+ sort: boolean;
21
+ };
22
+ export declare type Frame = {
23
+ gce: {
24
+ byteSize: number;
25
+ codes: number[];
26
+ delay: number;
27
+ terminator: number;
28
+ transparentColorIndex: number;
29
+ extras: {
30
+ userInput: boolean;
31
+ transparentColorGiven: boolean;
32
+ future: number;
33
+ disposal: number;
34
+ };
35
+ };
36
+ image: {
37
+ code: number;
38
+ data: {
39
+ minCodeSize: number;
40
+ blocks: number[];
41
+ };
42
+ descriptor: {
43
+ top: number;
44
+ left: number;
45
+ width: number;
46
+ height: number;
47
+ lct: Lct;
48
+ };
49
+ lct: [number, number, number][] | undefined;
50
+ };
51
+ };
52
+ export declare type ParsedFrame = {
53
+ dims: {
54
+ width: number;
55
+ height: number;
56
+ top: number;
57
+ left: number;
58
+ };
59
+ colorTable: [number, number, number][];
60
+ delay: number;
61
+ disposalType: number;
62
+ patch: Uint8ClampedArray;
63
+ pixels: number[];
64
+ transparentIndex: number;
65
+ };
66
+ export declare type ParsedFrameWithoutPatch = Omit<ParsedFrame, 'patch'>;
67
+ export declare type ParsedGif = {
68
+ frames: (Application | Frame)[];
69
+ gct: [number, number, number][];
70
+ header: {
71
+ signature: string;
72
+ version: string;
73
+ };
74
+ lsd: {
75
+ backgroundColorIndex: number;
76
+ gct: {
77
+ exists: boolean;
78
+ resolution: number;
79
+ size: number;
80
+ sort: boolean;
81
+ };
82
+ height: number;
83
+ width: number;
84
+ pixelAspectRatio: number;
85
+ };
86
+ };
87
+ export declare type Image = {
88
+ pixels: number[];
89
+ dims: Dimensions;
90
+ delay?: number;
91
+ transparentIndex?: number;
92
+ colorTable?: [number, number, number][] | Lct;
93
+ disposalType?: unknown;
94
+ patch?: Uint8ClampedArray;
95
+ };
96
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/dist/index.d.ts CHANGED
@@ -1,2 +1,4 @@
1
- export * from './Gif';
2
- export * from './props';
1
+ export { getGifDurationInSeconds } from './get-gif-duration-in-seconds';
2
+ export { Gif } from './Gif';
3
+ export { preloadGif } from './preload-gif';
4
+ export { GifFillMode, RemotionGifProps } from './props';
package/dist/index.js CHANGED
@@ -1,18 +1,9 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
2
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./Gif"), exports);
18
- __exportStar(require("./props"), exports);
3
+ exports.preloadGif = exports.Gif = exports.getGifDurationInSeconds = void 0;
4
+ var get_gif_duration_in_seconds_1 = require("./get-gif-duration-in-seconds");
5
+ Object.defineProperty(exports, "getGifDurationInSeconds", { enumerable: true, get: function () { return get_gif_duration_in_seconds_1.getGifDurationInSeconds; } });
6
+ var Gif_1 = require("./Gif");
7
+ Object.defineProperty(exports, "Gif", { enumerable: true, get: function () { return Gif_1.Gif; } });
8
+ var preload_gif_1 = require("./preload-gif");
9
+ Object.defineProperty(exports, "preloadGif", { enumerable: true, get: function () { return preload_gif_1.preloadGif; } });
@@ -0,0 +1 @@
1
+ export declare const isCorsError: (error: Error) => boolean;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isCorsError = void 0;
4
+ const isCorsError = (error) => {
5
+ return (
6
+ // Chrome
7
+ error.message.includes('Failed to fetch') ||
8
+ // Safari
9
+ error.message.includes('Load failed') ||
10
+ // Firefox
11
+ error.message.includes('NetworkError when attempting to fetch resource'));
12
+ };
13
+ exports.isCorsError = isCorsError;
@@ -0,0 +1,18 @@
1
+ import type { GifState } from './props';
2
+ export declare const parse: (src: string, { signal, }: {
3
+ signal: AbortController['signal'];
4
+ }) => Promise<{
5
+ loaded: boolean;
6
+ delays: number[];
7
+ frames: Uint8ClampedArray[];
8
+ width: any;
9
+ height: any;
10
+ }>;
11
+ declare type ParserCallbackArgs = {
12
+ width: number;
13
+ height: number;
14
+ delays: number[];
15
+ frames: Uint8ClampedArray[];
16
+ };
17
+ export declare const generate: (info: ParserCallbackArgs) => GifState;
18
+ export {};
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generate = exports.parse = void 0;
4
+ const gifuct_1 = require("./gifuct");
5
+ const decompress_frames_1 = require("./parser/decompress-frames");
6
+ const validateAndFix = (gif) => {
7
+ let currentGce = null;
8
+ for (const frame of gif.frames) {
9
+ currentGce = frame.gce ? frame.gce : currentGce;
10
+ // fix loosing graphic control extension for same frames
11
+ if ('image' in frame && !('gce' in frame) && currentGce !== null) {
12
+ frame.gce = currentGce;
13
+ }
14
+ }
15
+ };
16
+ const parse = (src, { signal, }) => fetch(src, { signal })
17
+ .then((resp) => {
18
+ var _a;
19
+ if (!((_a = resp.headers.get('Content-Type')) === null || _a === void 0 ? void 0 : _a.includes('image/gif')))
20
+ throw Error(`Wrong content type: "${resp.headers.get('Content-Type')}"`);
21
+ return resp.arrayBuffer();
22
+ })
23
+ .then((buffer) => (0, gifuct_1.parseGIF)(buffer))
24
+ .then((gif) => {
25
+ validateAndFix(gif);
26
+ return gif;
27
+ })
28
+ .then((gif) => Promise.all([
29
+ (0, decompress_frames_1.decompressFrames)(gif),
30
+ { width: gif.lsd.width, height: gif.lsd.height },
31
+ ]))
32
+ .then(([frames, options]) => {
33
+ const readyFrames = [];
34
+ const size = options.width * options.height * 4;
35
+ let canvas = new Uint8ClampedArray(size);
36
+ for (let i = 0; i < frames.length; ++i) {
37
+ const frame = frames[i];
38
+ // Read about different disposal types
39
+ // https://giflib.sourceforge.net/whatsinagif/animation_and_transparency.html
40
+ const prevCanvas = frames[i].disposalType === 3 ? canvas.slice() : null;
41
+ readyFrames.push(putPixels(canvas, frame, options));
42
+ // Disposal type 2: The canvas should be restored to the background color
43
+ if (frames[i].disposalType === 2) {
44
+ canvas = new Uint8ClampedArray(size);
45
+ }
46
+ // Disposal type 3: The decoder should restore the canvas to its previous state before the current image was drawn
47
+ else if (frames[i].disposalType === 3) {
48
+ if (!prevCanvas) {
49
+ throw Error('Disposal type 3 without previous frame');
50
+ }
51
+ canvas = prevCanvas;
52
+ }
53
+ // Disposal type 1: Draw the next image on top of it
54
+ else {
55
+ canvas = readyFrames[i].slice();
56
+ }
57
+ }
58
+ return {
59
+ ...options,
60
+ loaded: true,
61
+ delays: frames.map((frame) => frame.delay),
62
+ frames: readyFrames,
63
+ };
64
+ });
65
+ exports.parse = parse;
66
+ const putPixels = (typedArray, frame, gifSize) => {
67
+ const { width, height, top: dy, left: dx } = frame.dims;
68
+ const offset = dy * gifSize.width + dx;
69
+ for (let y = 0; y < height; y++) {
70
+ for (let x = 0; x < width; x++) {
71
+ const pPos = y * width + x;
72
+ const colorIndex = frame.pixels[pPos];
73
+ if (colorIndex !== frame.transparentIndex) {
74
+ const taPos = offset + y * gifSize.width + x;
75
+ const color = frame.colorTable[colorIndex];
76
+ typedArray[taPos * 4] = color[0];
77
+ typedArray[taPos * 4 + 1] = color[1];
78
+ typedArray[taPos * 4 + 2] = color[2];
79
+ typedArray[taPos * 4 + 3] =
80
+ colorIndex === frame.transparentIndex ? 0 : 255;
81
+ }
82
+ }
83
+ }
84
+ return typedArray;
85
+ };
86
+ const generate = (info) => {
87
+ return {
88
+ ...info,
89
+ frames: info.frames.map((buffer) => {
90
+ const image = new ImageData(info.width, info.height);
91
+ image.data.set(new Uint8ClampedArray(buffer));
92
+ return image;
93
+ }),
94
+ };
95
+ };
96
+ exports.generate = generate;
@@ -0,0 +1,2 @@
1
+ import type { ParsedFrameWithoutPatch, ParsedGif } from '../gifuct/types';
2
+ export declare const decompressFrames: (parsedGif: ParsedGif) => ParsedFrameWithoutPatch[];
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.decompressFrames = void 0;
4
+ const gifuct_1 = require("../gifuct");
5
+ const decompressFrames = (parsedGif) => {
6
+ return parsedGif.frames
7
+ .filter((f) => {
8
+ return !('application' in f);
9
+ })
10
+ .map((f) => {
11
+ const fr = f.image
12
+ ? (0, gifuct_1.decompressFrame)(f, parsedGif.gct)
13
+ : null;
14
+ return fr;
15
+ })
16
+ .filter(Boolean)
17
+ .map((f) => f);
18
+ };
19
+ exports.decompressFrames = decompressFrames;
@@ -0,0 +1,4 @@
1
+ export declare const preloadGif: (src: string) => {
2
+ waitUntilDone: () => Promise<void>;
3
+ free: () => void;
4
+ };
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.preloadGif = void 0;
4
+ const gif_cache_1 = require("./gif-cache");
5
+ const react_tools_1 = require("./react-tools");
6
+ const resolve_gif_source_1 = require("./resolve-gif-source");
7
+ const preloadGif = (src) => {
8
+ const resolvedSrc = (0, resolve_gif_source_1.resolveGifSource)(src);
9
+ if (gif_cache_1.volatileGifCache.has(resolvedSrc)) {
10
+ return {
11
+ waitUntilDone: () => Promise.resolve(),
12
+ free: () => gif_cache_1.volatileGifCache.delete(resolvedSrc),
13
+ };
14
+ }
15
+ if (gif_cache_1.manuallyManagedGifCache.has(resolvedSrc)) {
16
+ return {
17
+ waitUntilDone: () => Promise.resolve(),
18
+ free: () => gif_cache_1.manuallyManagedGifCache.delete(resolvedSrc),
19
+ };
20
+ }
21
+ const { prom, cancel } = (0, react_tools_1.parseWithWorker)(resolvedSrc);
22
+ let deleted = false;
23
+ prom.then((p) => {
24
+ if (!deleted) {
25
+ gif_cache_1.manuallyManagedGifCache.set(resolvedSrc, p);
26
+ }
27
+ });
28
+ return {
29
+ waitUntilDone: () => prom.then(() => undefined),
30
+ free: () => {
31
+ cancel();
32
+ deleted = true;
33
+ gif_cache_1.manuallyManagedGifCache.delete(resolvedSrc);
34
+ },
35
+ };
36
+ };
37
+ exports.preloadGif = preloadGif;
package/dist/props.d.ts CHANGED
@@ -1,18 +1,19 @@
1
1
  /// <reference types="react" />
2
+ export declare type GifLoopBehavior = 'loop' | 'pause-after-finish' | 'unmount-after-finish';
2
3
  export declare type RemotionGifProps = {
3
4
  src: string;
4
5
  width?: number;
5
6
  height?: number;
6
7
  onLoad?: (info: {
7
- loaded: true;
8
8
  width: number;
9
9
  height: number;
10
10
  delays: number[];
11
11
  frames: ImageData[];
12
12
  }) => void;
13
13
  onError?: (error: Error) => void;
14
- fit?: 'contain' | 'fill' | 'cover';
14
+ fit?: GifFillMode;
15
15
  style?: React.CSSProperties;
16
+ loopBehavior?: GifLoopBehavior;
16
17
  };
17
18
  export declare type GifState = {
18
19
  delays: number[];
@@ -20,3 +21,4 @@ export declare type GifState = {
20
21
  width: number;
21
22
  height: number;
22
23
  };
24
+ export declare type GifFillMode = 'contain' | 'cover' | 'fill';
package/dist/props.js CHANGED
File without changes
@@ -0,0 +1,9 @@
1
+ import type { GifState } from './props';
2
+ export declare const parseGif: ({ src, controller, }: {
3
+ src: string;
4
+ controller: AbortController;
5
+ }) => Promise<GifState>;
6
+ export declare const parseWithWorker: (src: string) => {
7
+ prom: Promise<GifState>;
8
+ cancel: () => void;
9
+ };
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseWithWorker = exports.parseGif = void 0;
4
+ const parse_generate_1 = require("./parse-generate");
5
+ const worker_1 = require("./worker");
6
+ const parseGif = async ({ src, controller, }) => {
7
+ const raw = await (0, parse_generate_1.parse)(src, { signal: controller.signal });
8
+ return (0, parse_generate_1.generate)(raw);
9
+ };
10
+ exports.parseGif = parseGif;
11
+ const parseWithWorker = (src) => {
12
+ const worker = (0, worker_1.makeWorker)();
13
+ let handler = null;
14
+ const prom = new Promise((resolve, reject) => {
15
+ handler = (e) => {
16
+ const message = e.data || e;
17
+ if (message.src === src) {
18
+ if (message.error) {
19
+ reject(new Error(message.error));
20
+ }
21
+ else {
22
+ const data = message.error ? message : (0, parse_generate_1.generate)(message);
23
+ resolve(data);
24
+ }
25
+ }
26
+ };
27
+ worker.addEventListener('message', handler);
28
+ worker.postMessage({ src, type: 'parse' });
29
+ });
30
+ return {
31
+ prom,
32
+ cancel: () => {
33
+ worker.postMessage({ src, type: 'cancel' });
34
+ worker.removeEventListener('message', handler);
35
+ worker.terminate();
36
+ },
37
+ };
38
+ };
39
+ exports.parseWithWorker = parseWithWorker;
@@ -0,0 +1 @@
1
+ export declare const resolveGifSource: (src: string) => string;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveGifSource = void 0;
4
+ const resolveGifSource = (src) => {
5
+ return new URL(src, typeof window === 'undefined' ? undefined : window.location.origin).href;
6
+ };
7
+ exports.resolveGifSource = resolveGifSource;
@@ -0,0 +1,6 @@
1
+ export declare type Size = {
2
+ width: number;
3
+ height: number;
4
+ };
5
+ export declare const updateAllElementsSizes: () => void;
6
+ export declare const useElementSize: (ref: React.RefObject<HTMLElement>) => Size | null;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useElementSize = exports.updateAllElementsSizes = void 0;
4
+ const react_1 = require("react");
5
+ let elementSizeHooks = [];
6
+ const updateAllElementsSizes = () => {
7
+ for (const listener of elementSizeHooks) {
8
+ listener();
9
+ }
10
+ };
11
+ exports.updateAllElementsSizes = updateAllElementsSizes;
12
+ const useElementSize = (ref) => {
13
+ const [size, setSize] = (0, react_1.useState)(null);
14
+ const observer = (0, react_1.useMemo)(() => {
15
+ if (typeof ResizeObserver === 'undefined') {
16
+ return null;
17
+ }
18
+ return new ResizeObserver((entries) => {
19
+ // The contentRect returns the width without any `scale()`'s being applied. The height is wrong
20
+ const { contentRect } = entries[0];
21
+ // The clientRect returns the size with `scale()` being applied.
22
+ const newSize = entries[0].target.getClientRects();
23
+ if (!newSize || !newSize[0]) {
24
+ setSize(null);
25
+ return;
26
+ }
27
+ const probableCssParentScale = newSize[0].width / contentRect.width;
28
+ const width = newSize[0].width * (1 / probableCssParentScale);
29
+ const height = newSize[0].height * (1 / probableCssParentScale);
30
+ setSize({
31
+ width,
32
+ height,
33
+ });
34
+ });
35
+ }, []);
36
+ const updateSize = (0, react_1.useCallback)(() => {
37
+ if (!ref.current) {
38
+ return;
39
+ }
40
+ const rect = ref.current.getClientRects();
41
+ if (!rect[0]) {
42
+ setSize(null);
43
+ return;
44
+ }
45
+ setSize({
46
+ width: rect[0].width,
47
+ height: rect[0].height,
48
+ });
49
+ }, [ref]);
50
+ (0, react_1.useEffect)(() => {
51
+ if (!observer) {
52
+ return;
53
+ }
54
+ updateSize();
55
+ const { current } = ref;
56
+ if (ref.current) {
57
+ observer.observe(ref.current);
58
+ }
59
+ return () => {
60
+ if (current) {
61
+ observer.unobserve(current);
62
+ }
63
+ };
64
+ }, [observer, ref, updateSize]);
65
+ (0, react_1.useEffect)(() => {
66
+ elementSizeHooks.push(updateSize);
67
+ return () => {
68
+ elementSizeHooks = elementSizeHooks.filter((e) => e !== updateSize);
69
+ };
70
+ }, [updateSize]);
71
+ return size;
72
+ };
73
+ exports.useElementSize = useElementSize;
@@ -1,2 +1,2 @@
1
- declare function useCurrentGifIndex(delays: number[]): number;
2
- export { useCurrentGifIndex };
1
+ import type { GifLoopBehavior } from './props';
2
+ export declare function useCurrentGifIndex(delays: number[], loopBehavior: GifLoopBehavior): number;