@remotion/transitions 4.0.454 → 4.0.455
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/TransitionSeries.d.ts +1 -0
- package/dist/TransitionSeries.js +53 -5
- package/dist/esm/index.mjs +62 -6
- package/dist/esm/zoom-blur.mjs +395 -0
- package/dist/html-in-canvas-presentation.d.ts +24 -0
- package/dist/html-in-canvas-presentation.js +156 -0
- package/dist/presentations/zoom-blur.d.ts +10 -0
- package/dist/presentations/zoom-blur.js +210 -0
- package/dist/types.d.ts +5 -0
- package/package.json +17 -8
- package/zoom-blur.js +2 -0
|
@@ -15,6 +15,7 @@ type SeriesSequenceProps = PropsWithChildren<{
|
|
|
15
15
|
readonly stack?: string;
|
|
16
16
|
} & LayoutBasedProps & Pick<SequencePropsWithoutDuration, 'name'>>;
|
|
17
17
|
declare const SeriesSequence: ({ children }: SeriesSequenceProps) => import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export type DrawFunction = (prevImage: ElementImage | null, nextImage: ElementImage | null, progress: number) => void;
|
|
18
19
|
declare const TransitionSeries: FC<SequencePropsWithoutDuration> & {
|
|
19
20
|
Sequence: typeof SeriesSequence;
|
|
20
21
|
Transition: typeof TransitionSeriesTransition;
|
package/dist/TransitionSeries.js
CHANGED
|
@@ -22,10 +22,44 @@ const SeriesSequence = ({ children }) => {
|
|
|
22
22
|
const TransitionSeriesChildren = ({ children, }) => {
|
|
23
23
|
const { fps } = (0, remotion_1.useVideoConfig)();
|
|
24
24
|
const frame = (0, remotion_1.useCurrentFrame)();
|
|
25
|
+
const prevImageRef = (0, react_1.useRef)({});
|
|
26
|
+
const nextImageRef = (0, react_1.useRef)({});
|
|
27
|
+
const flattedChildren = (0, react_1.useMemo)(() => {
|
|
28
|
+
return (0, flatten_children_js_1.flattenChildren)(children);
|
|
29
|
+
}, [children]);
|
|
30
|
+
const drawIfSynced = (0, react_1.useCallback)((index) => {
|
|
31
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
32
|
+
var _j, _k, _l, _m, _o, _p;
|
|
33
|
+
const prevImage = (_a = prevImageRef === null || prevImageRef === void 0 ? void 0 : prevImageRef.current) === null || _a === void 0 ? void 0 : _a[index];
|
|
34
|
+
const nextImage = (_b = nextImageRef === null || nextImageRef === void 0 ? void 0 : nextImageRef.current) === null || _b === void 0 ? void 0 : _b[index];
|
|
35
|
+
if (!(nextImage === null || nextImage === void 0 ? void 0 : nextImage.elementImage) && (prevImage === null || prevImage === void 0 ? void 0 : prevImage.elementImage)) {
|
|
36
|
+
(_c = nextImage === null || nextImage === void 0 ? void 0 : nextImage.draw) === null || _c === void 0 ? void 0 : _c.call(nextImage, null, null, 0);
|
|
37
|
+
(_d = prevImage === null || prevImage === void 0 ? void 0 : prevImage.draw) === null || _d === void 0 ? void 0 : _d.call(prevImage, (_j = prevImage === null || prevImage === void 0 ? void 0 : prevImage.elementImage) !== null && _j !== void 0 ? _j : null, null, 0);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (!(prevImage === null || prevImage === void 0 ? void 0 : prevImage.elementImage) && (nextImage === null || nextImage === void 0 ? void 0 : nextImage.elementImage)) {
|
|
41
|
+
(_e = prevImage === null || prevImage === void 0 ? void 0 : prevImage.draw) === null || _e === void 0 ? void 0 : _e.call(prevImage, null, null, 0);
|
|
42
|
+
(_f = nextImage === null || nextImage === void 0 ? void 0 : nextImage.draw) === null || _f === void 0 ? void 0 : _f.call(nextImage, null, (_k = nextImage === null || nextImage === void 0 ? void 0 : nextImage.elementImage) !== null && _k !== void 0 ? _k : null, 0);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if ((prevImage && nextImage && prevImage.progress === nextImage.progress) ||
|
|
46
|
+
!(prevImage === null || prevImage === void 0 ? void 0 : prevImage.elementImage) ||
|
|
47
|
+
!(nextImage === null || nextImage === void 0 ? void 0 : nextImage.elementImage)) {
|
|
48
|
+
(_g = prevImage === null || prevImage === void 0 ? void 0 : prevImage.draw) === null || _g === void 0 ? void 0 : _g.call(prevImage, (_l = prevImage === null || prevImage === void 0 ? void 0 : prevImage.elementImage) !== null && _l !== void 0 ? _l : null, (_m = nextImage === null || nextImage === void 0 ? void 0 : nextImage.elementImage) !== null && _m !== void 0 ? _m : null, (_p = (_o = prevImage === null || prevImage === void 0 ? void 0 : prevImage.progress) !== null && _o !== void 0 ? _o : nextImage === null || nextImage === void 0 ? void 0 : nextImage.progress) !== null && _p !== void 0 ? _p : 0);
|
|
49
|
+
(_h = nextImage === null || nextImage === void 0 ? void 0 : nextImage.draw) === null || _h === void 0 ? void 0 : _h.call(nextImage, null, null, 0);
|
|
50
|
+
}
|
|
51
|
+
}, []);
|
|
52
|
+
const onNextElementImage = (0, react_1.useCallback)((elementImage, progress, draw, index) => {
|
|
53
|
+
prevImageRef.current[index] = { elementImage, progress, draw };
|
|
54
|
+
drawIfSynced(index);
|
|
55
|
+
}, [drawIfSynced]);
|
|
56
|
+
const onPrevElementImage = (0, react_1.useCallback)((elementImage, progress, draw, index) => {
|
|
57
|
+
nextImageRef.current[index] = { elementImage, progress, draw };
|
|
58
|
+
drawIfSynced(index);
|
|
59
|
+
}, [drawIfSynced]);
|
|
25
60
|
const childrenValue = (0, react_1.useMemo)(() => {
|
|
26
61
|
let transitionOffsets = 0;
|
|
27
62
|
let startFrame = 0;
|
|
28
|
-
const flattedChildren = (0, flatten_children_js_1.flattenChildren)(children);
|
|
29
63
|
// Collect overlay render info to emit after the main loop
|
|
30
64
|
const overlayRenders = [];
|
|
31
65
|
// Track sequence durations for overlay validation
|
|
@@ -209,21 +243,35 @@ const TransitionSeriesChildren = ({ children, }) => {
|
|
|
209
243
|
const UppercasePrevPresentation = prevPresentation.component;
|
|
210
244
|
return (jsx_runtime_1.jsx(remotion_1.Sequence
|
|
211
245
|
// eslint-disable-next-line react/no-array-index-key
|
|
212
|
-
, { from: actualStartFrame, durationInFrames: durationInFramesProp, ...passedProps, name: passedProps.name || '<TS.Sequence>', children: jsx_runtime_1.jsx(UppercaseNextPresentation, { passedProps: (_e = nextPresentation.props) !== null && _e !== void 0 ? _e : {}, presentationDirection: "exiting", presentationProgress: nextProgress, presentationDurationInFrames: next.props.timing.getDurationInFrames({ fps }),
|
|
246
|
+
, { from: actualStartFrame, durationInFrames: durationInFramesProp, ...passedProps, name: passedProps.name || '<TS.Sequence>', children: jsx_runtime_1.jsx(UppercaseNextPresentation, { passedProps: (_e = nextPresentation.props) !== null && _e !== void 0 ? _e : {}, presentationDirection: "exiting", presentationProgress: nextProgress, presentationDurationInFrames: next.props.timing.getDurationInFrames({ fps }), onElementImage: () => {
|
|
247
|
+
throw new Error('Should not call when exiting');
|
|
248
|
+
}, onUnmount: () => {
|
|
249
|
+
throw new Error('Should not call when exiting');
|
|
250
|
+
}, bothEnteringAndExiting: true, children: jsx_runtime_1.jsx(context_js_1.WrapInExitingProgressContext, { presentationProgress: nextProgress, children: jsx_runtime_1.jsx(UppercasePrevPresentation, { passedProps: (_f = prevPresentation.props) !== null && _f !== void 0 ? _f : {}, presentationDirection: "entering", presentationProgress: prevProgress, presentationDurationInFrames: prev.props.timing.getDurationInFrames({ fps }), onElementImage: (elementImage, draw) => {
|
|
251
|
+
onPrevElementImage(elementImage, nextProgress, draw, i + 1);
|
|
252
|
+
onNextElementImage(elementImage, prevProgress, draw, i - 1);
|
|
253
|
+
}, onUnmount: () => {
|
|
254
|
+
onPrevElementImage(null, null, null, i + 1);
|
|
255
|
+
onNextElementImage(null, null, null, i - 1);
|
|
256
|
+
}, bothEnteringAndExiting: true, children: jsx_runtime_1.jsx(context_js_1.WrapInEnteringProgressContext, { presentationProgress: prevProgress, children: child }) }) }) }) }, i));
|
|
213
257
|
}
|
|
214
258
|
if (prevProgress !== null && prev) {
|
|
215
259
|
const prevPresentation = (_g = prev.props.presentation) !== null && _g !== void 0 ? _g : (0, slide_js_1.slide)();
|
|
216
260
|
const UppercasePrevPresentation = prevPresentation.component;
|
|
217
261
|
return (jsx_runtime_1.jsx(remotion_1.Sequence
|
|
218
262
|
// eslint-disable-next-line react/no-array-index-key
|
|
219
|
-
, { from: actualStartFrame, durationInFrames: durationInFramesProp, ...passedProps, name: passedProps.name || '<TS.Sequence>', children: jsx_runtime_1.jsx(UppercasePrevPresentation, { passedProps: (_h = prevPresentation.props) !== null && _h !== void 0 ? _h : {}, presentationDirection: "entering", presentationProgress: prevProgress, presentationDurationInFrames: prev.props.timing.getDurationInFrames({ fps }),
|
|
263
|
+
, { from: actualStartFrame, durationInFrames: durationInFramesProp, ...passedProps, name: passedProps.name || '<TS.Sequence>', children: jsx_runtime_1.jsx(UppercasePrevPresentation, { passedProps: (_h = prevPresentation.props) !== null && _h !== void 0 ? _h : {}, presentationDirection: "entering", presentationProgress: prevProgress, presentationDurationInFrames: prev.props.timing.getDurationInFrames({ fps }), onElementImage: (elementImage, draw) => onNextElementImage(elementImage, prevProgress, draw, i - 1), onUnmount: () => {
|
|
264
|
+
onNextElementImage(null, null, null, i - 1);
|
|
265
|
+
}, bothEnteringAndExiting: false, children: jsx_runtime_1.jsx(context_js_1.WrapInEnteringProgressContext, { presentationProgress: prevProgress, children: child }) }) }, i));
|
|
220
266
|
}
|
|
221
267
|
if (nextProgress !== null && next) {
|
|
222
268
|
const nextPresentation = (_j = next.props.presentation) !== null && _j !== void 0 ? _j : (0, slide_js_1.slide)();
|
|
223
269
|
const UppercaseNextPresentation = nextPresentation.component;
|
|
224
270
|
return (jsx_runtime_1.jsx(remotion_1.Sequence
|
|
225
271
|
// eslint-disable-next-line react/no-array-index-key
|
|
226
|
-
, { from: actualStartFrame, durationInFrames: durationInFramesProp, ...passedProps, name: passedProps.name || '<TS.Sequence>', children: jsx_runtime_1.jsx(UppercaseNextPresentation, { passedProps: (_k = nextPresentation.props) !== null && _k !== void 0 ? _k : {}, presentationDirection: "exiting", presentationProgress: nextProgress, presentationDurationInFrames: next.props.timing.getDurationInFrames({ fps }),
|
|
272
|
+
, { from: actualStartFrame, durationInFrames: durationInFramesProp, ...passedProps, name: passedProps.name || '<TS.Sequence>', children: jsx_runtime_1.jsx(UppercaseNextPresentation, { passedProps: (_k = nextPresentation.props) !== null && _k !== void 0 ? _k : {}, presentationDirection: "exiting", presentationProgress: nextProgress, presentationDurationInFrames: next.props.timing.getDurationInFrames({ fps }), onElementImage: (elementImage, draw) => onPrevElementImage(elementImage, nextProgress, draw, i + 1), onUnmount: () => {
|
|
273
|
+
onPrevElementImage(null, null, null, i + 1);
|
|
274
|
+
}, bothEnteringAndExiting: false, children: jsx_runtime_1.jsx(context_js_1.WrapInExitingProgressContext, { presentationProgress: nextProgress, children: child }) }) }, i));
|
|
227
275
|
}
|
|
228
276
|
return (jsx_runtime_1.jsx(remotion_1.Sequence
|
|
229
277
|
// eslint-disable-next-line react/no-array-index-key
|
|
@@ -235,7 +283,7 @@ const TransitionSeriesChildren = ({ children, }) => {
|
|
|
235
283
|
return (jsx_runtime_1.jsx(remotion_1.Sequence, { from: Math.round(info.overlayFrom), durationInFrames: info.durationInFrames, name: "<TS.Overlay>", layout: "absolute-fill", ...(info.stack ? { stack: info.stack } : {}), children: info.children }, `overlay-${info.index}`));
|
|
236
284
|
});
|
|
237
285
|
return [...(mainChildren || []), ...overlayElements];
|
|
238
|
-
}, [
|
|
286
|
+
}, [flattedChildren, fps, frame, onPrevElementImage, onNextElementImage]);
|
|
239
287
|
// eslint-disable-next-line react/jsx-no-useless-fragment
|
|
240
288
|
return jsx_runtime_1.jsx(jsx_runtime_1.Fragment, { children: childrenValue });
|
|
241
289
|
};
|
package/dist/esm/index.mjs
CHANGED
|
@@ -123,7 +123,7 @@ var springTiming = (options = {}) => {
|
|
|
123
123
|
};
|
|
124
124
|
};
|
|
125
125
|
// src/TransitionSeries.tsx
|
|
126
|
-
import { Children, useMemo as useMemo3 } from "react";
|
|
126
|
+
import { Children, useCallback, useMemo as useMemo3, useRef } from "react";
|
|
127
127
|
import { Internals, Sequence, useCurrentFrame, useVideoConfig } from "remotion";
|
|
128
128
|
import { NoReactInternals as NoReactInternals2 } from "remotion/no-react";
|
|
129
129
|
|
|
@@ -190,10 +190,40 @@ var TransitionSeriesChildren = ({
|
|
|
190
190
|
}) => {
|
|
191
191
|
const { fps } = useVideoConfig();
|
|
192
192
|
const frame = useCurrentFrame();
|
|
193
|
+
const prevImageRef = useRef({});
|
|
194
|
+
const nextImageRef = useRef({});
|
|
195
|
+
const flattedChildren = useMemo3(() => {
|
|
196
|
+
return flattenChildren(children);
|
|
197
|
+
}, [children]);
|
|
198
|
+
const drawIfSynced = useCallback((index) => {
|
|
199
|
+
const prevImage = prevImageRef?.current?.[index];
|
|
200
|
+
const nextImage = nextImageRef?.current?.[index];
|
|
201
|
+
if (!nextImage?.elementImage && prevImage?.elementImage) {
|
|
202
|
+
nextImage?.draw?.(null, null, 0);
|
|
203
|
+
prevImage?.draw?.(prevImage?.elementImage ?? null, null, 0);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
if (!prevImage?.elementImage && nextImage?.elementImage) {
|
|
207
|
+
prevImage?.draw?.(null, null, 0);
|
|
208
|
+
nextImage?.draw?.(null, nextImage?.elementImage ?? null, 0);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
if (prevImage && nextImage && prevImage.progress === nextImage.progress || !prevImage?.elementImage || !nextImage?.elementImage) {
|
|
212
|
+
prevImage?.draw?.(prevImage?.elementImage ?? null, nextImage?.elementImage ?? null, prevImage?.progress ?? nextImage?.progress ?? 0);
|
|
213
|
+
nextImage?.draw?.(null, null, 0);
|
|
214
|
+
}
|
|
215
|
+
}, []);
|
|
216
|
+
const onNextElementImage = useCallback((elementImage, progress, draw, index) => {
|
|
217
|
+
prevImageRef.current[index] = { elementImage, progress, draw };
|
|
218
|
+
drawIfSynced(index);
|
|
219
|
+
}, [drawIfSynced]);
|
|
220
|
+
const onPrevElementImage = useCallback((elementImage, progress, draw, index) => {
|
|
221
|
+
nextImageRef.current[index] = { elementImage, progress, draw };
|
|
222
|
+
drawIfSynced(index);
|
|
223
|
+
}, [drawIfSynced]);
|
|
193
224
|
const childrenValue = useMemo3(() => {
|
|
194
225
|
let transitionOffsets = 0;
|
|
195
226
|
let startFrame = 0;
|
|
196
|
-
const flattedChildren = flattenChildren(children);
|
|
197
227
|
const overlayRenders = [];
|
|
198
228
|
const sequenceDurations = [];
|
|
199
229
|
let pendingOverlayValidation = false;
|
|
@@ -352,6 +382,13 @@ var TransitionSeriesChildren = ({
|
|
|
352
382
|
presentationDirection: "exiting",
|
|
353
383
|
presentationProgress: nextProgress,
|
|
354
384
|
presentationDurationInFrames: next.props.timing.getDurationInFrames({ fps }),
|
|
385
|
+
onElementImage: () => {
|
|
386
|
+
throw new Error("Should not call when exiting");
|
|
387
|
+
},
|
|
388
|
+
onUnmount: () => {
|
|
389
|
+
throw new Error("Should not call when exiting");
|
|
390
|
+
},
|
|
391
|
+
bothEnteringAndExiting: true,
|
|
355
392
|
children: /* @__PURE__ */ jsx3(WrapInExitingProgressContext, {
|
|
356
393
|
presentationProgress: nextProgress,
|
|
357
394
|
children: /* @__PURE__ */ jsx3(UppercasePrevPresentation, {
|
|
@@ -359,6 +396,15 @@ var TransitionSeriesChildren = ({
|
|
|
359
396
|
presentationDirection: "entering",
|
|
360
397
|
presentationProgress: prevProgress,
|
|
361
398
|
presentationDurationInFrames: prev.props.timing.getDurationInFrames({ fps }),
|
|
399
|
+
onElementImage: (elementImage, draw) => {
|
|
400
|
+
onPrevElementImage(elementImage, nextProgress, draw, i + 1);
|
|
401
|
+
onNextElementImage(elementImage, prevProgress, draw, i - 1);
|
|
402
|
+
},
|
|
403
|
+
onUnmount: () => {
|
|
404
|
+
onPrevElementImage(null, null, null, i + 1);
|
|
405
|
+
onNextElementImage(null, null, null, i - 1);
|
|
406
|
+
},
|
|
407
|
+
bothEnteringAndExiting: true,
|
|
362
408
|
children: /* @__PURE__ */ jsx3(WrapInEnteringProgressContext, {
|
|
363
409
|
presentationProgress: prevProgress,
|
|
364
410
|
children: child
|
|
@@ -381,6 +427,11 @@ var TransitionSeriesChildren = ({
|
|
|
381
427
|
presentationDirection: "entering",
|
|
382
428
|
presentationProgress: prevProgress,
|
|
383
429
|
presentationDurationInFrames: prev.props.timing.getDurationInFrames({ fps }),
|
|
430
|
+
onElementImage: (elementImage, draw) => onNextElementImage(elementImage, prevProgress, draw, i - 1),
|
|
431
|
+
onUnmount: () => {
|
|
432
|
+
onNextElementImage(null, null, null, i - 1);
|
|
433
|
+
},
|
|
434
|
+
bothEnteringAndExiting: false,
|
|
384
435
|
children: /* @__PURE__ */ jsx3(WrapInEnteringProgressContext, {
|
|
385
436
|
presentationProgress: prevProgress,
|
|
386
437
|
children: child
|
|
@@ -401,6 +452,11 @@ var TransitionSeriesChildren = ({
|
|
|
401
452
|
presentationDirection: "exiting",
|
|
402
453
|
presentationProgress: nextProgress,
|
|
403
454
|
presentationDurationInFrames: next.props.timing.getDurationInFrames({ fps }),
|
|
455
|
+
onElementImage: (elementImage, draw) => onPrevElementImage(elementImage, nextProgress, draw, i + 1),
|
|
456
|
+
onUnmount: () => {
|
|
457
|
+
onPrevElementImage(null, null, null, i + 1);
|
|
458
|
+
},
|
|
459
|
+
bothEnteringAndExiting: false,
|
|
404
460
|
children: /* @__PURE__ */ jsx3(WrapInExitingProgressContext, {
|
|
405
461
|
presentationProgress: nextProgress,
|
|
406
462
|
children: child
|
|
@@ -428,7 +484,7 @@ var TransitionSeriesChildren = ({
|
|
|
428
484
|
}, `overlay-${info.index}`);
|
|
429
485
|
});
|
|
430
486
|
return [...mainChildren || [], ...overlayElements];
|
|
431
|
-
}, [
|
|
487
|
+
}, [flattedChildren, fps, frame, onPrevElementImage, onNextElementImage]);
|
|
432
488
|
return /* @__PURE__ */ jsx3(Fragment, {
|
|
433
489
|
children: childrenValue
|
|
434
490
|
});
|
|
@@ -455,10 +511,10 @@ Internals.addSequenceStackTraces(TransitionSeries);
|
|
|
455
511
|
Internals.addSequenceStackTraces(SeriesSequence);
|
|
456
512
|
Internals.addSequenceStackTraces(SeriesOverlay);
|
|
457
513
|
// src/use-transition-progress.ts
|
|
458
|
-
import
|
|
514
|
+
import React5 from "react";
|
|
459
515
|
var useTransitionProgress = () => {
|
|
460
|
-
const entering =
|
|
461
|
-
const exiting =
|
|
516
|
+
const entering = React5.useContext(EnteringContext);
|
|
517
|
+
const exiting = React5.useContext(ExitingContext);
|
|
462
518
|
if (!entering && !exiting) {
|
|
463
519
|
return {
|
|
464
520
|
isInTransitionSeries: false,
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
// src/html-in-canvas-presentation.tsx
|
|
2
|
+
import { useLayoutEffect, useMemo, useRef, useState, useCallback } from "react";
|
|
3
|
+
import { HtmlInCanvas, useDelayRender } from "remotion";
|
|
4
|
+
import { AbsoluteFill, Internals, useCurrentFrame } from "remotion";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
var HtmlInCanvasPresentation = ({
|
|
7
|
+
children,
|
|
8
|
+
onElementImage,
|
|
9
|
+
onUnmount,
|
|
10
|
+
presentationProgress,
|
|
11
|
+
presentationDirection,
|
|
12
|
+
shader,
|
|
13
|
+
_experimentalEffects,
|
|
14
|
+
passedProps,
|
|
15
|
+
bothEnteringAndExiting
|
|
16
|
+
}) => {
|
|
17
|
+
if (!HtmlInCanvas.isHtmlInCanvasSupported()) {
|
|
18
|
+
throw new Error("HTML in Canvas is not supported. Open this page in Chrome Canary with chrome://flags/#canvas-draw-element enabled.");
|
|
19
|
+
}
|
|
20
|
+
const canvasRef = useRef(null);
|
|
21
|
+
const canvasSubtreeStyle = useMemo(() => {
|
|
22
|
+
return {
|
|
23
|
+
width: "100%",
|
|
24
|
+
height: "100%",
|
|
25
|
+
position: "absolute",
|
|
26
|
+
top: 0,
|
|
27
|
+
left: 0,
|
|
28
|
+
right: 0,
|
|
29
|
+
bottom: 0
|
|
30
|
+
};
|
|
31
|
+
}, []);
|
|
32
|
+
const [offscreenCanvas] = useState(() => new OffscreenCanvas(1, 1));
|
|
33
|
+
const passedPropsRef = useRef(passedProps);
|
|
34
|
+
passedPropsRef.current = passedProps;
|
|
35
|
+
const frame = useCurrentFrame();
|
|
36
|
+
const frameRef = useRef(frame);
|
|
37
|
+
frameRef.current = frame;
|
|
38
|
+
const effectsRef = useRef(_experimentalEffects);
|
|
39
|
+
effectsRef.current = _experimentalEffects;
|
|
40
|
+
const [instance] = useState(() => shader());
|
|
41
|
+
useLayoutEffect(() => {
|
|
42
|
+
instance.init(offscreenCanvas);
|
|
43
|
+
return () => {
|
|
44
|
+
instance.cleanup();
|
|
45
|
+
};
|
|
46
|
+
}, [offscreenCanvas, instance]);
|
|
47
|
+
const chainState = Internals.useEffectChainState();
|
|
48
|
+
const { delayRender, continueRender } = useDelayRender();
|
|
49
|
+
const draw = useCallback(async (prevImage, nextImage, progress) => {
|
|
50
|
+
if (!canvasRef.current) {
|
|
51
|
+
throw new Error("Canvas not found");
|
|
52
|
+
}
|
|
53
|
+
const handle = delayRender("onPaint");
|
|
54
|
+
if (!prevImage && !nextImage) {
|
|
55
|
+
continueRender(handle);
|
|
56
|
+
instance.clear();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const width = prevImage?.width ?? nextImage?.width ?? 0;
|
|
60
|
+
const height = prevImage?.height ?? nextImage?.height ?? 0;
|
|
61
|
+
if (width === 0 || height === 0) {
|
|
62
|
+
continueRender(handle);
|
|
63
|
+
instance.clear();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
offscreenCanvas.width = width;
|
|
67
|
+
offscreenCanvas.height = height;
|
|
68
|
+
instance.draw({
|
|
69
|
+
prevImage,
|
|
70
|
+
nextImage,
|
|
71
|
+
width,
|
|
72
|
+
height,
|
|
73
|
+
time: progress,
|
|
74
|
+
passedProps: passedPropsRef.current
|
|
75
|
+
});
|
|
76
|
+
await Internals.runEffectChain({
|
|
77
|
+
state: chainState.get(width, height),
|
|
78
|
+
source: offscreenCanvas,
|
|
79
|
+
effects: effectsRef.current ?? [],
|
|
80
|
+
frame: frameRef.current,
|
|
81
|
+
width,
|
|
82
|
+
height,
|
|
83
|
+
output: canvasRef.current
|
|
84
|
+
});
|
|
85
|
+
continueRender(handle);
|
|
86
|
+
}, [chainState, instance, offscreenCanvas, continueRender, delayRender]);
|
|
87
|
+
const passThrough = bothEnteringAndExiting && presentationDirection === "exiting";
|
|
88
|
+
useLayoutEffect(() => {
|
|
89
|
+
if (passThrough) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const canvas = canvasRef.current;
|
|
93
|
+
if (!canvas) {
|
|
94
|
+
throw new Error("Canvas not found");
|
|
95
|
+
}
|
|
96
|
+
canvas.layoutSubtree = true;
|
|
97
|
+
const onPaint = () => {
|
|
98
|
+
const firstChild = canvas.firstChild;
|
|
99
|
+
if (!firstChild) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const elementImage = canvas.captureElementImage(firstChild);
|
|
103
|
+
onElementImage(elementImage, draw);
|
|
104
|
+
};
|
|
105
|
+
canvas.addEventListener("paint", onPaint);
|
|
106
|
+
return () => {
|
|
107
|
+
canvas.removeEventListener("paint", onPaint);
|
|
108
|
+
};
|
|
109
|
+
}, [onElementImage, presentationDirection, draw, passThrough]);
|
|
110
|
+
useLayoutEffect(() => {
|
|
111
|
+
if (passThrough) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const canvas = canvasRef.current;
|
|
115
|
+
if (!canvas) {
|
|
116
|
+
throw new Error("Canvas not found");
|
|
117
|
+
}
|
|
118
|
+
canvas.requestPaint?.();
|
|
119
|
+
}, [presentationProgress, passThrough]);
|
|
120
|
+
useLayoutEffect(() => {
|
|
121
|
+
if (passThrough) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
return () => {
|
|
125
|
+
onUnmount();
|
|
126
|
+
};
|
|
127
|
+
}, [onUnmount, passThrough]);
|
|
128
|
+
useLayoutEffect(() => {
|
|
129
|
+
if (passThrough) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const canvas = canvasRef.current;
|
|
133
|
+
if (!canvas) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const observer = new ResizeObserver(([entry]) => {
|
|
137
|
+
canvas.width = entry.devicePixelContentBoxSize[0].inlineSize;
|
|
138
|
+
canvas.height = entry.devicePixelContentBoxSize[0].blockSize;
|
|
139
|
+
});
|
|
140
|
+
observer.observe(canvas, { box: "device-pixel-content-box" });
|
|
141
|
+
}, [passThrough]);
|
|
142
|
+
if (passThrough) {
|
|
143
|
+
return children;
|
|
144
|
+
}
|
|
145
|
+
return /* @__PURE__ */ jsx(AbsoluteFill, {
|
|
146
|
+
children: /* @__PURE__ */ jsx("canvas", {
|
|
147
|
+
ref: canvasRef,
|
|
148
|
+
style: canvasSubtreeStyle,
|
|
149
|
+
children
|
|
150
|
+
})
|
|
151
|
+
});
|
|
152
|
+
};
|
|
153
|
+
var makeHtmlInCanvasPresentation = (shader) => {
|
|
154
|
+
const CompWithShader = (props) => {
|
|
155
|
+
const { passedProps, ...otherProps } = props;
|
|
156
|
+
const { _experimentalEffects, ...restPassedProps } = props.passedProps;
|
|
157
|
+
return /* @__PURE__ */ jsx(HtmlInCanvasPresentation, {
|
|
158
|
+
shader,
|
|
159
|
+
passedProps: restPassedProps,
|
|
160
|
+
_experimentalEffects,
|
|
161
|
+
...otherProps
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
return (props) => {
|
|
165
|
+
return {
|
|
166
|
+
component: CompWithShader,
|
|
167
|
+
props
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
// src/presentations/zoom-blur.tsx
|
|
173
|
+
var VERTEX_SHADER = `#version 300 es
|
|
174
|
+
in vec2 a_pos;
|
|
175
|
+
out vec2 v_uv;
|
|
176
|
+
void main() {
|
|
177
|
+
v_uv = vec2(a_pos.x * 0.5 + 0.5, 0.5 - a_pos.y * 0.5);
|
|
178
|
+
gl_Position = vec4(a_pos, 0.0, 1.0);
|
|
179
|
+
}`;
|
|
180
|
+
var FRAGMENT_SHADER = `#version 300 es
|
|
181
|
+
precision highp float;
|
|
182
|
+
|
|
183
|
+
uniform sampler2D u_prev;
|
|
184
|
+
uniform sampler2D u_next;
|
|
185
|
+
uniform float u_time;
|
|
186
|
+
uniform float u_aspect;
|
|
187
|
+
uniform float u_max_angle;
|
|
188
|
+
|
|
189
|
+
in vec2 v_uv;
|
|
190
|
+
out vec4 outColor;
|
|
191
|
+
|
|
192
|
+
const int SAMPLES = 16;
|
|
193
|
+
const float STRENGTH = 0.35;
|
|
194
|
+
|
|
195
|
+
vec2 transformUV(vec2 uv, float angle, float scale) {
|
|
196
|
+
vec2 p = uv - 0.5;
|
|
197
|
+
p.x *= u_aspect;
|
|
198
|
+
p /= scale;
|
|
199
|
+
float c = cos(-angle);
|
|
200
|
+
float s = sin(-angle);
|
|
201
|
+
p = vec2(p.x * c - p.y * s, p.x * s + p.y * c);
|
|
202
|
+
p.x /= u_aspect;
|
|
203
|
+
return p + 0.5;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
float coverScale(float angle) {
|
|
207
|
+
float c = abs(cos(angle));
|
|
208
|
+
float s = abs(sin(angle));
|
|
209
|
+
float ar = max(u_aspect, 1.0 / u_aspect);
|
|
210
|
+
return c + ar * s;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
vec4 zoomBlur(sampler2D tex, vec2 uv, float strength) {
|
|
214
|
+
vec2 dir = uv - 0.5;
|
|
215
|
+
vec4 acc = vec4(0.0);
|
|
216
|
+
for (int i = 0; i < SAMPLES; i++) {
|
|
217
|
+
float t = float(i) / float(SAMPLES - 1);
|
|
218
|
+
float scale = 1.0 - strength * t;
|
|
219
|
+
acc += texture(tex, 0.5 + dir * scale);
|
|
220
|
+
}
|
|
221
|
+
return acc / float(SAMPLES);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
void main() {
|
|
225
|
+
float mixT = u_time;
|
|
226
|
+
|
|
227
|
+
float nextAngle = u_max_angle * mixT;
|
|
228
|
+
float prevAngle = -u_max_angle * (1.0 - mixT);
|
|
229
|
+
|
|
230
|
+
vec2 prevUV = transformUV(v_uv, prevAngle, coverScale(prevAngle));
|
|
231
|
+
vec2 nextUV = transformUV(v_uv, nextAngle, coverScale(nextAngle));
|
|
232
|
+
|
|
233
|
+
vec4 prev = zoomBlur(u_prev, prevUV, STRENGTH * (1.0 - mixT));
|
|
234
|
+
vec4 next = zoomBlur(u_next, nextUV, STRENGTH * mixT);
|
|
235
|
+
outColor = mix(prev, next, (1.0 - mixT));
|
|
236
|
+
}`;
|
|
237
|
+
var compileShader = (gl, source, type) => {
|
|
238
|
+
const shader = gl.createShader(type);
|
|
239
|
+
if (!shader) {
|
|
240
|
+
throw new Error("Failed to create shader");
|
|
241
|
+
}
|
|
242
|
+
gl.shaderSource(shader, source);
|
|
243
|
+
gl.compileShader(shader);
|
|
244
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
245
|
+
const log = gl.getShaderInfoLog(shader);
|
|
246
|
+
gl.deleteShader(shader);
|
|
247
|
+
throw new Error(`Failed to compile shader: ${log}`);
|
|
248
|
+
}
|
|
249
|
+
return shader;
|
|
250
|
+
};
|
|
251
|
+
var createProgram = (gl) => {
|
|
252
|
+
const program = gl.createProgram();
|
|
253
|
+
if (!program) {
|
|
254
|
+
throw new Error("Failed to create WebGL program");
|
|
255
|
+
}
|
|
256
|
+
const vs = compileShader(gl, VERTEX_SHADER, gl.VERTEX_SHADER);
|
|
257
|
+
const fs = compileShader(gl, FRAGMENT_SHADER, gl.FRAGMENT_SHADER);
|
|
258
|
+
gl.attachShader(program, vs);
|
|
259
|
+
gl.attachShader(program, fs);
|
|
260
|
+
gl.linkProgram(program);
|
|
261
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
262
|
+
const log = gl.getProgramInfoLog(program);
|
|
263
|
+
gl.deleteProgram(program);
|
|
264
|
+
throw new Error(`Failed to link program: ${log}`);
|
|
265
|
+
}
|
|
266
|
+
return program;
|
|
267
|
+
};
|
|
268
|
+
var createTexture = (gl) => {
|
|
269
|
+
const tex = gl.createTexture();
|
|
270
|
+
if (!tex) {
|
|
271
|
+
throw new Error("Failed to create texture");
|
|
272
|
+
}
|
|
273
|
+
gl.bindTexture(gl.TEXTURE_2D, tex);
|
|
274
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
275
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
276
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
277
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
278
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 0, 0]));
|
|
279
|
+
return tex;
|
|
280
|
+
};
|
|
281
|
+
var zoomBlurShader = () => {
|
|
282
|
+
let state = null;
|
|
283
|
+
const init = (canvas) => {
|
|
284
|
+
const gl = canvas.getContext("webgl2", { premultipliedAlpha: true });
|
|
285
|
+
if (!gl) {
|
|
286
|
+
return () => {};
|
|
287
|
+
}
|
|
288
|
+
const program = createProgram(gl);
|
|
289
|
+
const prevTex = createTexture(gl);
|
|
290
|
+
const nextTex = createTexture(gl);
|
|
291
|
+
const vao = gl.createVertexArray();
|
|
292
|
+
gl.bindVertexArray(vao);
|
|
293
|
+
const buffer = gl.createBuffer();
|
|
294
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
295
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);
|
|
296
|
+
const aPos = gl.getAttribLocation(program, "a_pos");
|
|
297
|
+
gl.enableVertexAttribArray(aPos);
|
|
298
|
+
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);
|
|
299
|
+
state = {
|
|
300
|
+
gl,
|
|
301
|
+
program,
|
|
302
|
+
prevTex,
|
|
303
|
+
nextTex,
|
|
304
|
+
uTime: gl.getUniformLocation(program, "u_time"),
|
|
305
|
+
uPrev: gl.getUniformLocation(program, "u_prev"),
|
|
306
|
+
uNext: gl.getUniformLocation(program, "u_next"),
|
|
307
|
+
uAspect: gl.getUniformLocation(program, "u_aspect"),
|
|
308
|
+
uMaxAngle: gl.getUniformLocation(program, "u_max_angle")
|
|
309
|
+
};
|
|
310
|
+
return () => {};
|
|
311
|
+
};
|
|
312
|
+
const cleanup = () => {
|
|
313
|
+
if (!state) {
|
|
314
|
+
throw new Error("Zoom blur state not initialized");
|
|
315
|
+
}
|
|
316
|
+
const { gl, program, prevTex, nextTex } = state;
|
|
317
|
+
gl.deleteProgram(program);
|
|
318
|
+
gl.deleteTexture(prevTex);
|
|
319
|
+
gl.deleteTexture(nextTex);
|
|
320
|
+
state = null;
|
|
321
|
+
};
|
|
322
|
+
const clear = () => {
|
|
323
|
+
if (!state) {
|
|
324
|
+
throw new Error("Zoom blur state not initialized");
|
|
325
|
+
}
|
|
326
|
+
const { gl } = state;
|
|
327
|
+
gl.clearColor(0, 0, 0, 0);
|
|
328
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
329
|
+
};
|
|
330
|
+
const draw = ({
|
|
331
|
+
prevImage,
|
|
332
|
+
nextImage,
|
|
333
|
+
width,
|
|
334
|
+
height,
|
|
335
|
+
time,
|
|
336
|
+
passedProps
|
|
337
|
+
}) => {
|
|
338
|
+
if (!state) {
|
|
339
|
+
throw new Error("Zoom blur state not initialized");
|
|
340
|
+
}
|
|
341
|
+
const { rotation = Math.PI / 6 } = passedProps;
|
|
342
|
+
const {
|
|
343
|
+
gl,
|
|
344
|
+
program,
|
|
345
|
+
prevTex,
|
|
346
|
+
nextTex,
|
|
347
|
+
uTime,
|
|
348
|
+
uPrev,
|
|
349
|
+
uNext,
|
|
350
|
+
uAspect,
|
|
351
|
+
uMaxAngle
|
|
352
|
+
} = state;
|
|
353
|
+
if (!prevImage && !nextImage) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
if (prevImage && (prevImage.width === 0 || prevImage.height === 0)) {
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
if (nextImage && (nextImage.width === 0 || nextImage.height === 0)) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
const effectiveTime = !prevImage ? 0 : !nextImage ? 1 : time;
|
|
363
|
+
gl.viewport(0, 0, width, height);
|
|
364
|
+
gl.clearColor(0, 0, 0, 0);
|
|
365
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
366
|
+
gl.useProgram(program);
|
|
367
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
368
|
+
gl.bindTexture(gl.TEXTURE_2D, prevTex);
|
|
369
|
+
if (prevImage) {
|
|
370
|
+
gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, prevImage);
|
|
371
|
+
}
|
|
372
|
+
gl.uniform1i(uPrev, 0);
|
|
373
|
+
gl.activeTexture(gl.TEXTURE1);
|
|
374
|
+
gl.bindTexture(gl.TEXTURE_2D, nextTex);
|
|
375
|
+
if (nextImage) {
|
|
376
|
+
gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, nextImage);
|
|
377
|
+
}
|
|
378
|
+
gl.uniform1i(uNext, 1);
|
|
379
|
+
gl.uniform1f(uTime, effectiveTime);
|
|
380
|
+
gl.uniform1f(uAspect, width / height);
|
|
381
|
+
gl.uniform1f(uMaxAngle, rotation);
|
|
382
|
+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
383
|
+
};
|
|
384
|
+
return {
|
|
385
|
+
init,
|
|
386
|
+
clear,
|
|
387
|
+
draw,
|
|
388
|
+
cleanup
|
|
389
|
+
};
|
|
390
|
+
};
|
|
391
|
+
var zoomBlur = makeHtmlInCanvasPresentation(zoomBlurShader);
|
|
392
|
+
export {
|
|
393
|
+
zoomBlurShader,
|
|
394
|
+
zoomBlur
|
|
395
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type EffectsProp } from 'remotion';
|
|
2
|
+
import type { TransitionPresentation, TransitionPresentationComponentProps } from './types';
|
|
3
|
+
export declare const HtmlInCanvasPresentation: <TPassedProps extends Record<string, unknown>>({ children, onElementImage, onUnmount, presentationProgress, presentationDirection, shader, _experimentalEffects, passedProps, bothEnteringAndExiting, }: TransitionPresentationComponentProps<TPassedProps> & {
|
|
4
|
+
readonly shader: () => HtmlInCanvasShader<TPassedProps>;
|
|
5
|
+
readonly _experimentalEffects?: EffectsProp | undefined;
|
|
6
|
+
}) => string | number | bigint | boolean | import("react/jsx-runtime").JSX.Element | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | Iterable<import("react").ReactNode> | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | null | undefined> | null | undefined;
|
|
7
|
+
export type HtmlInCanvasShader<TPassedProps> = {
|
|
8
|
+
init: (canvas: OffscreenCanvas) => void;
|
|
9
|
+
clear: () => void;
|
|
10
|
+
draw: (params: {
|
|
11
|
+
prevImage: ElementImage | null;
|
|
12
|
+
nextImage: ElementImage | null;
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
time: number;
|
|
16
|
+
passedProps: TPassedProps;
|
|
17
|
+
}) => void;
|
|
18
|
+
cleanup: () => void;
|
|
19
|
+
};
|
|
20
|
+
export declare const makeHtmlInCanvasPresentation: <TPassedProps extends Record<string, unknown>>(shader: () => HtmlInCanvasShader<TPassedProps>) => (props: TPassedProps & {
|
|
21
|
+
_experimentalEffects?: EffectsProp | undefined;
|
|
22
|
+
}) => TransitionPresentation<TPassedProps & {
|
|
23
|
+
_experimentalEffects?: EffectsProp | undefined;
|
|
24
|
+
}>;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeHtmlInCanvasPresentation = exports.HtmlInCanvasPresentation = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const remotion_1 = require("remotion");
|
|
7
|
+
const remotion_2 = require("remotion");
|
|
8
|
+
const HtmlInCanvasPresentation = ({ children, onElementImage, onUnmount, presentationProgress, presentationDirection, shader, _experimentalEffects, passedProps, bothEnteringAndExiting, }) => {
|
|
9
|
+
if (!remotion_1.HtmlInCanvas.isHtmlInCanvasSupported()) {
|
|
10
|
+
throw new Error('HTML in Canvas is not supported. Open this page in Chrome Canary with chrome://flags/#canvas-draw-element enabled.');
|
|
11
|
+
}
|
|
12
|
+
const canvasRef = (0, react_1.useRef)(null);
|
|
13
|
+
const canvasSubtreeStyle = (0, react_1.useMemo)(() => {
|
|
14
|
+
return {
|
|
15
|
+
width: '100%',
|
|
16
|
+
height: '100%',
|
|
17
|
+
position: 'absolute',
|
|
18
|
+
top: 0,
|
|
19
|
+
left: 0,
|
|
20
|
+
right: 0,
|
|
21
|
+
bottom: 0,
|
|
22
|
+
};
|
|
23
|
+
}, []);
|
|
24
|
+
const [offscreenCanvas] = (0, react_1.useState)(() => new OffscreenCanvas(1, 1));
|
|
25
|
+
const passedPropsRef = (0, react_1.useRef)(passedProps);
|
|
26
|
+
passedPropsRef.current = passedProps;
|
|
27
|
+
const frame = (0, remotion_2.useCurrentFrame)();
|
|
28
|
+
const frameRef = (0, react_1.useRef)(frame);
|
|
29
|
+
frameRef.current = frame;
|
|
30
|
+
const effectsRef = (0, react_1.useRef)(_experimentalEffects);
|
|
31
|
+
effectsRef.current = _experimentalEffects;
|
|
32
|
+
const [instance] = (0, react_1.useState)(() => shader());
|
|
33
|
+
(0, react_1.useLayoutEffect)(() => {
|
|
34
|
+
instance.init(offscreenCanvas);
|
|
35
|
+
return () => {
|
|
36
|
+
instance.cleanup();
|
|
37
|
+
};
|
|
38
|
+
}, [offscreenCanvas, instance]);
|
|
39
|
+
const chainState = remotion_2.Internals.useEffectChainState();
|
|
40
|
+
const { delayRender, continueRender } = (0, remotion_1.useDelayRender)();
|
|
41
|
+
const draw = (0, react_1.useCallback)(async (prevImage, nextImage, progress) => {
|
|
42
|
+
var _a, _b, _c, _d, _e;
|
|
43
|
+
if (!canvasRef.current) {
|
|
44
|
+
throw new Error('Canvas not found');
|
|
45
|
+
}
|
|
46
|
+
const handle = delayRender('onPaint');
|
|
47
|
+
if (!prevImage && !nextImage) {
|
|
48
|
+
continueRender(handle);
|
|
49
|
+
instance.clear();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const width = (_b = (_a = prevImage === null || prevImage === void 0 ? void 0 : prevImage.width) !== null && _a !== void 0 ? _a : nextImage === null || nextImage === void 0 ? void 0 : nextImage.width) !== null && _b !== void 0 ? _b : 0;
|
|
53
|
+
const height = (_d = (_c = prevImage === null || prevImage === void 0 ? void 0 : prevImage.height) !== null && _c !== void 0 ? _c : nextImage === null || nextImage === void 0 ? void 0 : nextImage.height) !== null && _d !== void 0 ? _d : 0;
|
|
54
|
+
if (width === 0 || height === 0) {
|
|
55
|
+
continueRender(handle);
|
|
56
|
+
instance.clear();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
offscreenCanvas.width = width;
|
|
60
|
+
offscreenCanvas.height = height;
|
|
61
|
+
instance.draw({
|
|
62
|
+
prevImage,
|
|
63
|
+
nextImage,
|
|
64
|
+
width,
|
|
65
|
+
height,
|
|
66
|
+
time: progress,
|
|
67
|
+
passedProps: passedPropsRef.current,
|
|
68
|
+
});
|
|
69
|
+
await remotion_2.Internals.runEffectChain({
|
|
70
|
+
state: chainState.get(width, height),
|
|
71
|
+
source: offscreenCanvas,
|
|
72
|
+
effects: (_e = effectsRef.current) !== null && _e !== void 0 ? _e : [],
|
|
73
|
+
frame: frameRef.current,
|
|
74
|
+
width,
|
|
75
|
+
height,
|
|
76
|
+
output: canvasRef.current,
|
|
77
|
+
});
|
|
78
|
+
continueRender(handle);
|
|
79
|
+
}, [chainState, instance, offscreenCanvas, continueRender, delayRender]);
|
|
80
|
+
const passThrough = bothEnteringAndExiting && presentationDirection === 'exiting';
|
|
81
|
+
(0, react_1.useLayoutEffect)(() => {
|
|
82
|
+
if (passThrough) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const canvas = canvasRef.current;
|
|
86
|
+
if (!canvas) {
|
|
87
|
+
throw new Error('Canvas not found');
|
|
88
|
+
}
|
|
89
|
+
canvas.layoutSubtree = true;
|
|
90
|
+
const onPaint = () => {
|
|
91
|
+
const firstChild = canvas.firstChild;
|
|
92
|
+
if (!firstChild) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const elementImage = canvas.captureElementImage(firstChild);
|
|
96
|
+
onElementImage(elementImage, draw);
|
|
97
|
+
};
|
|
98
|
+
canvas.addEventListener('paint', onPaint);
|
|
99
|
+
return () => {
|
|
100
|
+
canvas.removeEventListener('paint', onPaint);
|
|
101
|
+
};
|
|
102
|
+
}, [onElementImage, presentationDirection, draw, passThrough]);
|
|
103
|
+
(0, react_1.useLayoutEffect)(() => {
|
|
104
|
+
var _a;
|
|
105
|
+
if (passThrough) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const canvas = canvasRef.current;
|
|
109
|
+
if (!canvas) {
|
|
110
|
+
throw new Error('Canvas not found');
|
|
111
|
+
}
|
|
112
|
+
(_a = canvas.requestPaint) === null || _a === void 0 ? void 0 : _a.call(canvas);
|
|
113
|
+
}, [presentationProgress, passThrough]);
|
|
114
|
+
(0, react_1.useLayoutEffect)(() => {
|
|
115
|
+
if (passThrough) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
return () => {
|
|
119
|
+
onUnmount();
|
|
120
|
+
};
|
|
121
|
+
}, [onUnmount, passThrough]);
|
|
122
|
+
(0, react_1.useLayoutEffect)(() => {
|
|
123
|
+
if (passThrough) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const canvas = canvasRef.current;
|
|
127
|
+
if (!canvas) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
// Size the canvas grid to match the device scale factor to prevent blurriness.
|
|
131
|
+
const observer = new ResizeObserver(([entry]) => {
|
|
132
|
+
canvas.width = entry.devicePixelContentBoxSize[0].inlineSize;
|
|
133
|
+
canvas.height = entry.devicePixelContentBoxSize[0].blockSize;
|
|
134
|
+
});
|
|
135
|
+
observer.observe(canvas, { box: 'device-pixel-content-box' });
|
|
136
|
+
}, [passThrough]);
|
|
137
|
+
if (passThrough) {
|
|
138
|
+
return children;
|
|
139
|
+
}
|
|
140
|
+
return (jsx_runtime_1.jsx(remotion_2.AbsoluteFill, { children: jsx_runtime_1.jsx("canvas", { ref: canvasRef, style: canvasSubtreeStyle, children: children }) }));
|
|
141
|
+
};
|
|
142
|
+
exports.HtmlInCanvasPresentation = HtmlInCanvasPresentation;
|
|
143
|
+
const makeHtmlInCanvasPresentation = (shader) => {
|
|
144
|
+
const CompWithShader = (props) => {
|
|
145
|
+
const { passedProps, ...otherProps } = props;
|
|
146
|
+
const { _experimentalEffects, ...restPassedProps } = props.passedProps;
|
|
147
|
+
return (jsx_runtime_1.jsx(exports.HtmlInCanvasPresentation, { shader: shader, passedProps: restPassedProps, _experimentalEffects: _experimentalEffects, ...otherProps }));
|
|
148
|
+
};
|
|
149
|
+
return (props) => {
|
|
150
|
+
return {
|
|
151
|
+
component: CompWithShader,
|
|
152
|
+
props,
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
exports.makeHtmlInCanvasPresentation = makeHtmlInCanvasPresentation;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { HtmlInCanvasShader } from '../html-in-canvas-presentation';
|
|
2
|
+
export type ZoomBlurProps = {
|
|
3
|
+
rotation?: number;
|
|
4
|
+
};
|
|
5
|
+
export declare const zoomBlurShader: () => HtmlInCanvasShader<ZoomBlurProps>;
|
|
6
|
+
export declare const zoomBlur: (props: ZoomBlurProps & {
|
|
7
|
+
_experimentalEffects?: import("remotion").EffectsProp | undefined;
|
|
8
|
+
}) => import("..").TransitionPresentation<ZoomBlurProps & {
|
|
9
|
+
_experimentalEffects?: import("remotion").EffectsProp | undefined;
|
|
10
|
+
}>;
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.zoomBlur = exports.zoomBlurShader = void 0;
|
|
4
|
+
const html_in_canvas_presentation_1 = require("../html-in-canvas-presentation");
|
|
5
|
+
const VERTEX_SHADER = `#version 300 es
|
|
6
|
+
in vec2 a_pos;
|
|
7
|
+
out vec2 v_uv;
|
|
8
|
+
void main() {
|
|
9
|
+
v_uv = vec2(a_pos.x * 0.5 + 0.5, 0.5 - a_pos.y * 0.5);
|
|
10
|
+
gl_Position = vec4(a_pos, 0.0, 1.0);
|
|
11
|
+
}`;
|
|
12
|
+
const FRAGMENT_SHADER = `#version 300 es
|
|
13
|
+
precision highp float;
|
|
14
|
+
|
|
15
|
+
uniform sampler2D u_prev;
|
|
16
|
+
uniform sampler2D u_next;
|
|
17
|
+
uniform float u_time;
|
|
18
|
+
uniform float u_aspect;
|
|
19
|
+
uniform float u_max_angle;
|
|
20
|
+
|
|
21
|
+
in vec2 v_uv;
|
|
22
|
+
out vec4 outColor;
|
|
23
|
+
|
|
24
|
+
const int SAMPLES = 16;
|
|
25
|
+
const float STRENGTH = 0.35;
|
|
26
|
+
|
|
27
|
+
vec2 transformUV(vec2 uv, float angle, float scale) {
|
|
28
|
+
vec2 p = uv - 0.5;
|
|
29
|
+
p.x *= u_aspect;
|
|
30
|
+
p /= scale;
|
|
31
|
+
float c = cos(-angle);
|
|
32
|
+
float s = sin(-angle);
|
|
33
|
+
p = vec2(p.x * c - p.y * s, p.x * s + p.y * c);
|
|
34
|
+
p.x /= u_aspect;
|
|
35
|
+
return p + 0.5;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
float coverScale(float angle) {
|
|
39
|
+
float c = abs(cos(angle));
|
|
40
|
+
float s = abs(sin(angle));
|
|
41
|
+
float ar = max(u_aspect, 1.0 / u_aspect);
|
|
42
|
+
return c + ar * s;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
vec4 zoomBlur(sampler2D tex, vec2 uv, float strength) {
|
|
46
|
+
vec2 dir = uv - 0.5;
|
|
47
|
+
vec4 acc = vec4(0.0);
|
|
48
|
+
for (int i = 0; i < SAMPLES; i++) {
|
|
49
|
+
float t = float(i) / float(SAMPLES - 1);
|
|
50
|
+
float scale = 1.0 - strength * t;
|
|
51
|
+
acc += texture(tex, 0.5 + dir * scale);
|
|
52
|
+
}
|
|
53
|
+
return acc / float(SAMPLES);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
void main() {
|
|
57
|
+
float mixT = u_time;
|
|
58
|
+
|
|
59
|
+
float nextAngle = u_max_angle * mixT;
|
|
60
|
+
float prevAngle = -u_max_angle * (1.0 - mixT);
|
|
61
|
+
|
|
62
|
+
vec2 prevUV = transformUV(v_uv, prevAngle, coverScale(prevAngle));
|
|
63
|
+
vec2 nextUV = transformUV(v_uv, nextAngle, coverScale(nextAngle));
|
|
64
|
+
|
|
65
|
+
vec4 prev = zoomBlur(u_prev, prevUV, STRENGTH * (1.0 - mixT));
|
|
66
|
+
vec4 next = zoomBlur(u_next, nextUV, STRENGTH * mixT);
|
|
67
|
+
outColor = mix(prev, next, (1.0 - mixT));
|
|
68
|
+
}`;
|
|
69
|
+
const compileShader = (gl, source, type) => {
|
|
70
|
+
const shader = gl.createShader(type);
|
|
71
|
+
if (!shader) {
|
|
72
|
+
throw new Error('Failed to create shader');
|
|
73
|
+
}
|
|
74
|
+
gl.shaderSource(shader, source);
|
|
75
|
+
gl.compileShader(shader);
|
|
76
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
77
|
+
const log = gl.getShaderInfoLog(shader);
|
|
78
|
+
gl.deleteShader(shader);
|
|
79
|
+
throw new Error(`Failed to compile shader: ${log}`);
|
|
80
|
+
}
|
|
81
|
+
return shader;
|
|
82
|
+
};
|
|
83
|
+
const createProgram = (gl) => {
|
|
84
|
+
const program = gl.createProgram();
|
|
85
|
+
if (!program) {
|
|
86
|
+
throw new Error('Failed to create WebGL program');
|
|
87
|
+
}
|
|
88
|
+
const vs = compileShader(gl, VERTEX_SHADER, gl.VERTEX_SHADER);
|
|
89
|
+
const fs = compileShader(gl, FRAGMENT_SHADER, gl.FRAGMENT_SHADER);
|
|
90
|
+
gl.attachShader(program, vs);
|
|
91
|
+
gl.attachShader(program, fs);
|
|
92
|
+
gl.linkProgram(program);
|
|
93
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
94
|
+
const log = gl.getProgramInfoLog(program);
|
|
95
|
+
gl.deleteProgram(program);
|
|
96
|
+
throw new Error(`Failed to link program: ${log}`);
|
|
97
|
+
}
|
|
98
|
+
return program;
|
|
99
|
+
};
|
|
100
|
+
const createTexture = (gl) => {
|
|
101
|
+
const tex = gl.createTexture();
|
|
102
|
+
if (!tex) {
|
|
103
|
+
throw new Error('Failed to create texture');
|
|
104
|
+
}
|
|
105
|
+
gl.bindTexture(gl.TEXTURE_2D, tex);
|
|
106
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
107
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
108
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
109
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
110
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 0, 0]));
|
|
111
|
+
return tex;
|
|
112
|
+
};
|
|
113
|
+
const zoomBlurShader = () => {
|
|
114
|
+
let state = null;
|
|
115
|
+
const init = (canvas) => {
|
|
116
|
+
const gl = canvas.getContext('webgl2', { premultipliedAlpha: true });
|
|
117
|
+
if (!gl) {
|
|
118
|
+
return () => { };
|
|
119
|
+
}
|
|
120
|
+
const program = createProgram(gl);
|
|
121
|
+
const prevTex = createTexture(gl);
|
|
122
|
+
const nextTex = createTexture(gl);
|
|
123
|
+
const vao = gl.createVertexArray();
|
|
124
|
+
gl.bindVertexArray(vao);
|
|
125
|
+
const buffer = gl.createBuffer();
|
|
126
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
127
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);
|
|
128
|
+
const aPos = gl.getAttribLocation(program, 'a_pos');
|
|
129
|
+
gl.enableVertexAttribArray(aPos);
|
|
130
|
+
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);
|
|
131
|
+
state = {
|
|
132
|
+
gl,
|
|
133
|
+
program,
|
|
134
|
+
prevTex,
|
|
135
|
+
nextTex,
|
|
136
|
+
uTime: gl.getUniformLocation(program, 'u_time'),
|
|
137
|
+
uPrev: gl.getUniformLocation(program, 'u_prev'),
|
|
138
|
+
uNext: gl.getUniformLocation(program, 'u_next'),
|
|
139
|
+
uAspect: gl.getUniformLocation(program, 'u_aspect'),
|
|
140
|
+
uMaxAngle: gl.getUniformLocation(program, 'u_max_angle'),
|
|
141
|
+
};
|
|
142
|
+
return () => { };
|
|
143
|
+
};
|
|
144
|
+
const cleanup = () => {
|
|
145
|
+
if (!state) {
|
|
146
|
+
throw new Error('Zoom blur state not initialized');
|
|
147
|
+
}
|
|
148
|
+
const { gl, program, prevTex, nextTex } = state;
|
|
149
|
+
gl.deleteProgram(program);
|
|
150
|
+
gl.deleteTexture(prevTex);
|
|
151
|
+
gl.deleteTexture(nextTex);
|
|
152
|
+
state = null;
|
|
153
|
+
};
|
|
154
|
+
const clear = () => {
|
|
155
|
+
if (!state) {
|
|
156
|
+
throw new Error('Zoom blur state not initialized');
|
|
157
|
+
}
|
|
158
|
+
const { gl } = state;
|
|
159
|
+
gl.clearColor(0, 0, 0, 0);
|
|
160
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
161
|
+
};
|
|
162
|
+
const draw = ({ prevImage, nextImage, width, height, time, passedProps, }) => {
|
|
163
|
+
if (!state) {
|
|
164
|
+
throw new Error('Zoom blur state not initialized');
|
|
165
|
+
}
|
|
166
|
+
const { rotation = Math.PI / 6 } = passedProps;
|
|
167
|
+
const { gl, program, prevTex, nextTex, uTime, uPrev, uNext, uAspect, uMaxAngle, } = state;
|
|
168
|
+
if (!prevImage && !nextImage) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (prevImage && (prevImage.width === 0 || prevImage.height === 0)) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (nextImage && (nextImage.width === 0 || nextImage.height === 0)) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
// When one side is missing, force the mix to fully show the other.
|
|
178
|
+
// At time=0 the shader outputs nextImage (and nextAngle = 0).
|
|
179
|
+
// At time=1 the shader outputs prevImage (and prevAngle = 0).
|
|
180
|
+
const effectiveTime = !prevImage ? 0 : !nextImage ? 1 : time;
|
|
181
|
+
gl.viewport(0, 0, width, height);
|
|
182
|
+
gl.clearColor(0, 0, 0, 0);
|
|
183
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
184
|
+
gl.useProgram(program);
|
|
185
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
186
|
+
gl.bindTexture(gl.TEXTURE_2D, prevTex);
|
|
187
|
+
if (prevImage) {
|
|
188
|
+
gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, prevImage);
|
|
189
|
+
}
|
|
190
|
+
gl.uniform1i(uPrev, 0);
|
|
191
|
+
gl.activeTexture(gl.TEXTURE1);
|
|
192
|
+
gl.bindTexture(gl.TEXTURE_2D, nextTex);
|
|
193
|
+
if (nextImage) {
|
|
194
|
+
gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, nextImage);
|
|
195
|
+
}
|
|
196
|
+
gl.uniform1i(uNext, 1);
|
|
197
|
+
gl.uniform1f(uTime, effectiveTime);
|
|
198
|
+
gl.uniform1f(uAspect, width / height);
|
|
199
|
+
gl.uniform1f(uMaxAngle, rotation);
|
|
200
|
+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
201
|
+
};
|
|
202
|
+
return {
|
|
203
|
+
init,
|
|
204
|
+
clear,
|
|
205
|
+
draw,
|
|
206
|
+
cleanup,
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
exports.zoomBlurShader = zoomBlurShader;
|
|
210
|
+
exports.zoomBlur = (0, html_in_canvas_presentation_1.makeHtmlInCanvasPresentation)(exports.zoomBlurShader);
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { ComponentType } from 'react';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
import type { DrawFunction } from './TransitionSeries';
|
|
2
4
|
export type PresentationDirection = 'entering' | 'exiting';
|
|
3
5
|
export type TransitionTiming = {
|
|
4
6
|
getDurationInFrames: (options: {
|
|
@@ -24,6 +26,9 @@ export type TransitionPresentationComponentProps<PresentationProps extends Recor
|
|
|
24
26
|
presentationDirection: PresentationDirection;
|
|
25
27
|
passedProps: PresentationProps;
|
|
26
28
|
presentationDurationInFrames: number;
|
|
29
|
+
onElementImage: (elementImage: ElementImage, draw: DrawFunction) => void;
|
|
30
|
+
onUnmount: () => void;
|
|
31
|
+
bothEnteringAndExiting: boolean;
|
|
27
32
|
};
|
|
28
33
|
export type TransitionSeriesOverlayProps = {
|
|
29
34
|
readonly durationInFrames: number;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/transitions"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/transitions",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.455",
|
|
7
7
|
"description": "Library for creating transitions in Remotion",
|
|
8
8
|
"sideEffects": false,
|
|
9
9
|
"main": "dist/esm/index.mjs",
|
|
@@ -23,18 +23,18 @@
|
|
|
23
23
|
"url": "https://github.com/remotion-dev/remotion/issues"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"remotion": "4.0.
|
|
27
|
-
"@remotion/shapes": "4.0.
|
|
28
|
-
"@remotion/paths": "4.0.
|
|
26
|
+
"remotion": "4.0.455",
|
|
27
|
+
"@remotion/shapes": "4.0.455",
|
|
28
|
+
"@remotion/paths": "4.0.455"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@happy-dom/global-registrator": "14.5.1",
|
|
32
|
-
"remotion": "4.0.
|
|
32
|
+
"remotion": "4.0.455",
|
|
33
33
|
"react": "19.2.3",
|
|
34
34
|
"react-dom": "19.2.3",
|
|
35
|
-
"@remotion/test-utils": "4.0.
|
|
36
|
-
"@remotion/player": "4.0.
|
|
37
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
35
|
+
"@remotion/test-utils": "4.0.455",
|
|
36
|
+
"@remotion/player": "4.0.455",
|
|
37
|
+
"@remotion/eslint-config-internal": "4.0.455",
|
|
38
38
|
"eslint": "9.19.0",
|
|
39
39
|
"@typescript/native-preview": "7.0.0-dev.20260217.1"
|
|
40
40
|
},
|
|
@@ -86,6 +86,12 @@
|
|
|
86
86
|
"import": "./dist/esm/clock-wipe.mjs",
|
|
87
87
|
"require": "./dist/presentations/clock-wipe.js"
|
|
88
88
|
},
|
|
89
|
+
"./zoom-blur": {
|
|
90
|
+
"types": "./dist/presentations/zoom-blur.d.ts",
|
|
91
|
+
"module": "./dist/esm/zoom-blur.mjs",
|
|
92
|
+
"import": "./dist/esm/zoom-blur.mjs",
|
|
93
|
+
"require": "./dist/presentations/zoom-blur.js"
|
|
94
|
+
},
|
|
89
95
|
"./none": {
|
|
90
96
|
"types": "./dist/presentations/none.d.ts",
|
|
91
97
|
"module": "./dist/esm/none.mjs",
|
|
@@ -122,6 +128,9 @@
|
|
|
122
128
|
],
|
|
123
129
|
"iris": [
|
|
124
130
|
"dist/presentations/iris.d.ts"
|
|
131
|
+
],
|
|
132
|
+
"zoom-blur": [
|
|
133
|
+
"dist/presentations/zoom-blur.d.ts"
|
|
125
134
|
]
|
|
126
135
|
}
|
|
127
136
|
},
|
package/zoom-blur.js
ADDED