@depup/lottie-react 2.4.1-depup.0 → 3.0.0-depup.0
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/LICENSE.md +9 -0
- package/README.md +4 -10
- package/build/_virtual/_rolldown/runtime.cjs +23 -0
- package/build/animation/Lottie.cjs +39 -0
- package/build/animation/Lottie.d.cts +47 -0
- package/build/animation/Lottie.d.ts +47 -0
- package/build/animation/Lottie.js +37 -0
- package/build/animation/LottieDisplay.cjs +55 -0
- package/build/animation/LottieDisplay.d.cts +46 -0
- package/build/animation/LottieDisplay.d.ts +46 -0
- package/build/animation/LottieDisplay.js +53 -0
- package/build/animation/LottieInstanceContext.cjs +16 -0
- package/build/animation/LottieInstanceContext.js +17 -0
- package/build/animation/LottieLight.cjs +19 -0
- package/build/animation/LottieLight.d.cts +23 -0
- package/build/animation/LottieLight.d.ts +23 -0
- package/build/animation/LottieLight.js +17 -0
- package/build/animation/LottieRegistryContext.cjs +36 -0
- package/build/animation/LottieRegistryContext.js +35 -0
- package/build/animation/LottieSvg.cjs +20 -0
- package/build/animation/LottieSvg.d.cts +24 -0
- package/build/animation/LottieSvg.d.ts +24 -0
- package/build/animation/LottieSvg.js +18 -0
- package/build/animation/collectMarkerCrossings.cjs +38 -0
- package/build/animation/collectMarkerCrossings.js +38 -0
- package/build/animation/createLottieComponent.cjs +131 -0
- package/build/animation/createLottieComponent.d.cts +45 -0
- package/build/animation/createLottieComponent.d.ts +45 -0
- package/build/animation/createLottieComponent.js +131 -0
- package/build/animation/hasExpressions.cjs +25 -0
- package/build/animation/hasExpressions.js +25 -0
- package/build/animation/normalizeAnimationSource.cjs +38 -0
- package/build/animation/normalizeAnimationSource.js +38 -0
- package/build/animation/polymorphicForwardRef.cjs +18 -0
- package/build/animation/polymorphicForwardRef.js +19 -0
- package/build/animation/renderStyledElement.cjs +31 -0
- package/build/animation/renderStyledElement.js +31 -0
- package/build/animation/resolveSeekTarget.cjs +97 -0
- package/build/animation/resolveSeekTarget.js +95 -0
- package/build/animation/styleLayer.cjs +24 -0
- package/build/animation/styleLayer.js +24 -0
- package/build/animation/stylePrecedence.cjs +12 -0
- package/build/animation/stylePrecedence.js +12 -0
- package/build/animation/types.cjs +71 -0
- package/build/animation/types.d.cts +461 -0
- package/build/animation/types.d.ts +461 -0
- package/build/animation/types.js +68 -0
- package/build/animation/useLottie.cjs +40 -0
- package/build/animation/useLottie.d.cts +36 -0
- package/build/animation/useLottie.d.ts +36 -0
- package/build/animation/useLottie.js +38 -0
- package/build/animation/useLottieAnimation.cjs +434 -0
- package/build/animation/useLottieAnimation.d.cts +40 -0
- package/build/animation/useLottieAnimation.d.ts +40 -0
- package/build/animation/useLottieAnimation.js +434 -0
- package/build/animation/useLottieInstance.cjs +20 -0
- package/build/animation/useLottieInstance.d.cts +14 -0
- package/build/animation/useLottieInstance.d.ts +14 -0
- package/build/animation/useLottieInstance.js +20 -0
- package/build/animation/useLottieLight.cjs +20 -0
- package/build/animation/useLottieLight.d.cts +16 -0
- package/build/animation/useLottieLight.d.ts +16 -0
- package/build/animation/useLottieLight.js +18 -0
- package/build/animation/useLottieSvg.cjs +18 -0
- package/build/animation/useLottieSvg.d.cts +14 -0
- package/build/animation/useLottieSvg.d.ts +14 -0
- package/build/animation/useLottieSvg.js +16 -0
- package/build/controls/LottieControls.cjs +180 -0
- package/build/controls/LottieControls.d.cts +58 -0
- package/build/controls/LottieControls.d.ts +58 -0
- package/build/controls/LottieControls.js +178 -0
- package/build/controls/LottieDirectionButton.cjs +36 -0
- package/build/controls/LottieDirectionButton.js +35 -0
- package/build/controls/LottieFullscreenButton.cjs +35 -0
- package/build/controls/LottieFullscreenButton.js +34 -0
- package/build/controls/LottieLoopButton.cjs +32 -0
- package/build/controls/LottieLoopButton.js +31 -0
- package/build/controls/LottiePlayButton.cjs +34 -0
- package/build/controls/LottiePlayButton.js +33 -0
- package/build/controls/LottieReadout.cjs +61 -0
- package/build/controls/LottieReadout.d.cts +13 -0
- package/build/controls/LottieReadout.d.ts +13 -0
- package/build/controls/LottieReadout.js +60 -0
- package/build/controls/LottieSeekBar.cjs +87 -0
- package/build/controls/LottieSeekBar.js +86 -0
- package/build/controls/LottieSpeedSelect.cjs +51 -0
- package/build/controls/LottieSpeedSelect.js +50 -0
- package/build/controls/LottieStopButton.cjs +29 -0
- package/build/controls/LottieStopButton.js +28 -0
- package/build/controls/controlIcon.cjs +25 -0
- package/build/controls/controlIcon.js +25 -0
- package/build/controls/useFullscreen.cjs +46 -0
- package/build/controls/useFullscreen.js +46 -0
- package/build/controls/useShortcuts.cjs +70 -0
- package/build/controls/useShortcuts.js +70 -0
- package/build/index.cjs +36 -0
- package/build/index.d.cts +19 -0
- package/build/index.d.ts +19 -80
- package/build/index.js +17 -667
- package/build/interactions/LottieInteractions.cjs +41 -0
- package/build/interactions/LottieInteractions.d.cts +37 -0
- package/build/interactions/LottieInteractions.d.ts +37 -0
- package/build/interactions/LottieInteractions.js +41 -0
- package/build/interactions/coverProgress.cjs +55 -0
- package/build/interactions/coverProgress.js +53 -0
- package/build/interactions/lottieInView.cjs +109 -0
- package/build/interactions/lottieInView.d.cts +44 -0
- package/build/interactions/lottieInView.d.ts +44 -0
- package/build/interactions/lottieInView.js +109 -0
- package/build/interactions/lottieScrollScrub.cjs +152 -0
- package/build/interactions/lottieScrollScrub.d.cts +47 -0
- package/build/interactions/lottieScrollScrub.d.ts +47 -0
- package/build/interactions/lottieScrollScrub.js +152 -0
- package/build/interactions/types.d.cts +46 -0
- package/build/interactions/types.d.ts +46 -0
- package/build/interactions/useInteractionsRunner.cjs +142 -0
- package/build/interactions/useInteractionsRunner.js +141 -0
- package/build/interactions/useLottieInteractions.cjs +21 -0
- package/build/interactions/useLottieInteractions.d.cts +19 -0
- package/build/interactions/useLottieInteractions.d.ts +19 -0
- package/build/interactions/useLottieInteractions.js +21 -0
- package/build/overlays/LottieError.cjs +74 -0
- package/build/overlays/LottieError.d.cts +40 -0
- package/build/overlays/LottieError.d.ts +40 -0
- package/build/overlays/LottieError.js +72 -0
- package/build/overlays/LottieLoading.cjs +89 -0
- package/build/overlays/LottieLoading.d.cts +45 -0
- package/build/overlays/LottieLoading.d.ts +45 -0
- package/build/overlays/LottieLoading.js +87 -0
- package/build/overlays/overlayStyles.cjs +33 -0
- package/build/overlays/overlayStyles.js +33 -0
- package/build/utils/SubscriptionManager.cjs +42 -0
- package/build/utils/SubscriptionManager.d.cts +30 -0
- package/build/utils/SubscriptionManager.d.ts +30 -0
- package/build/utils/SubscriptionManager.js +42 -0
- package/build/utils/createLogger.cjs +25 -0
- package/build/utils/createLogger.js +25 -0
- package/build/utils/isSameJson.cjs +37 -0
- package/build/utils/isSameJson.js +37 -0
- package/build/utils/mergeRefs.cjs +37 -0
- package/build/utils/mergeRefs.js +37 -0
- package/build/utils/useStableValue.cjs +26 -0
- package/build/utils/useStableValue.js +26 -0
- package/changes.json +3 -8
- package/package.json +144 -89
- package/LICENSE +0 -46
- package/build/index.es.js +0 -653
- package/build/index.es.js.map +0 -1
- package/build/index.es.min.js +0 -3
- package/build/index.js.map +0 -1
- package/build/index.min.js +0 -3
- package/build/index.umd.js +0 -670
- package/build/index.umd.js.map +0 -1
- package/build/index.umd.min.js +0 -3
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useLottieInstance } from "../animation/useLottieInstance.js";
|
|
2
|
+
import { controlIcon } from "./controlIcon.js";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/controls/LottieLoopButton.tsx
|
|
5
|
+
/** The class this control carries, which the bar's stylesheet targets. */
|
|
6
|
+
const lottieLoopClass = "lottie-loop";
|
|
7
|
+
const loopPath = "M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4z";
|
|
8
|
+
/**
|
|
9
|
+
* Turns looping on and off.
|
|
10
|
+
*
|
|
11
|
+
* The switching itself is handed in rather than done here, because the `l`
|
|
12
|
+
* shortcut does the same thing and the count in force has to be remembered
|
|
13
|
+
* across both. Two memories would mean pressing the key and then the button
|
|
14
|
+
* loses a `loop={3}`, which is the exact fault that got the old surface's
|
|
15
|
+
* `toggleLoop` dropped rather than rebuilt.
|
|
16
|
+
*/
|
|
17
|
+
function LottieLoopButton({ lottie, toggle, className, ...rest }) {
|
|
18
|
+
const looping = useLottieInstance(lottie).loop !== false;
|
|
19
|
+
return /* @__PURE__ */ jsx("button", {
|
|
20
|
+
"aria-label": "Loop",
|
|
21
|
+
title: "Loop",
|
|
22
|
+
...rest,
|
|
23
|
+
"aria-pressed": looping,
|
|
24
|
+
className: className ? `${lottieLoopClass} ${className}` : lottieLoopClass,
|
|
25
|
+
onClick: toggle,
|
|
26
|
+
type: "button",
|
|
27
|
+
children: controlIcon(loopPath)
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { LottieLoopButton, lottieLoopClass };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const require_useLottieInstance = require("../animation/useLottieInstance.cjs");
|
|
2
|
+
const require_types = require("../animation/types.cjs");
|
|
3
|
+
const require_controlIcon = require("./controlIcon.cjs");
|
|
4
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
|
+
//#region src/controls/LottiePlayButton.tsx
|
|
6
|
+
/** The class this control carries, which the bar's stylesheet targets. */
|
|
7
|
+
const lottiePlayClass = "lottie-play";
|
|
8
|
+
const playPath = "M8 5v14l11-7z";
|
|
9
|
+
const pausePath = "M6 5h4v14H6zm8 0h4v14h-4z";
|
|
10
|
+
/**
|
|
11
|
+
* Starts the animation, or stops it where it is.
|
|
12
|
+
*
|
|
13
|
+
* One button rather than two, so that pressing it does not unmount the element
|
|
14
|
+
* that has focus. The player this replaces rendered play and pause as separate
|
|
15
|
+
* components in separate positions, which dropped focus to the document body
|
|
16
|
+
* every time someone pressed either with the keyboard.
|
|
17
|
+
*/
|
|
18
|
+
function LottiePlayButton({ lottie, className, ...rest }) {
|
|
19
|
+
const instance = require_useLottieInstance.useLottieInstance(lottie);
|
|
20
|
+
const playing = instance.state === require_types.LottieState.playing;
|
|
21
|
+
const label = playing ? "Pause" : "Play";
|
|
22
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
23
|
+
"aria-label": label,
|
|
24
|
+
title: label,
|
|
25
|
+
...rest,
|
|
26
|
+
className: className ? `${lottiePlayClass} ${className}` : lottiePlayClass,
|
|
27
|
+
onClick: playing ? instance.pause : instance.play,
|
|
28
|
+
type: "button",
|
|
29
|
+
children: require_controlIcon.controlIcon(playing ? pausePath : playPath)
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
exports.LottiePlayButton = LottiePlayButton;
|
|
34
|
+
exports.lottiePlayClass = lottiePlayClass;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { useLottieInstance } from "../animation/useLottieInstance.js";
|
|
2
|
+
import { LottieState } from "../animation/types.js";
|
|
3
|
+
import { controlIcon } from "./controlIcon.js";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/controls/LottiePlayButton.tsx
|
|
6
|
+
/** The class this control carries, which the bar's stylesheet targets. */
|
|
7
|
+
const lottiePlayClass = "lottie-play";
|
|
8
|
+
const playPath = "M8 5v14l11-7z";
|
|
9
|
+
const pausePath = "M6 5h4v14H6zm8 0h4v14h-4z";
|
|
10
|
+
/**
|
|
11
|
+
* Starts the animation, or stops it where it is.
|
|
12
|
+
*
|
|
13
|
+
* One button rather than two, so that pressing it does not unmount the element
|
|
14
|
+
* that has focus. The player this replaces rendered play and pause as separate
|
|
15
|
+
* components in separate positions, which dropped focus to the document body
|
|
16
|
+
* every time someone pressed either with the keyboard.
|
|
17
|
+
*/
|
|
18
|
+
function LottiePlayButton({ lottie, className, ...rest }) {
|
|
19
|
+
const instance = useLottieInstance(lottie);
|
|
20
|
+
const playing = instance.state === LottieState.playing;
|
|
21
|
+
const label = playing ? "Pause" : "Play";
|
|
22
|
+
return /* @__PURE__ */ jsx("button", {
|
|
23
|
+
"aria-label": label,
|
|
24
|
+
title: label,
|
|
25
|
+
...rest,
|
|
26
|
+
className: className ? `${lottiePlayClass} ${className}` : lottiePlayClass,
|
|
27
|
+
onClick: playing ? instance.pause : instance.play,
|
|
28
|
+
type: "button",
|
|
29
|
+
children: controlIcon(playing ? pausePath : playPath)
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { LottiePlayButton, lottiePlayClass };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const require_useLottieInstance = require("../animation/useLottieInstance.cjs");
|
|
2
|
+
const require_types = require("../animation/types.cjs");
|
|
3
|
+
let react = require("react");
|
|
4
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
|
+
//#region src/controls/LottieReadout.tsx
|
|
6
|
+
/** The class this control carries, which the bar's stylesheet targets. */
|
|
7
|
+
const lottieReadoutClass = "lottie-readout";
|
|
8
|
+
/**
|
|
9
|
+
* One position, in whichever unit was asked for.
|
|
10
|
+
*
|
|
11
|
+
* Seconds carry one decimal rather than the `0:04` a video player would use.
|
|
12
|
+
* Most animations are a few seconds long, so minutes are always zero and the
|
|
13
|
+
* seconds place is the only one doing any work, which makes dragging look like
|
|
14
|
+
* it is doing nothing.
|
|
15
|
+
*/
|
|
16
|
+
function format(frames, secondsPerFrame, unit) {
|
|
17
|
+
return unit === "seconds" ? `${(frames * secondsPerFrame).toFixed(1)}s` : String(Math.round(frames));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Where the playhead is, and how far it has to go.
|
|
21
|
+
*
|
|
22
|
+
* Both numbers describe what is currently playable rather than the whole file,
|
|
23
|
+
* so a segment moves them together. With nothing loaded they are zeros, which
|
|
24
|
+
* keeps the element the same shape it will be a moment later.
|
|
25
|
+
*
|
|
26
|
+
* Like the seek bar, the moving half is written straight onto the element rather
|
|
27
|
+
* than held in state, because it changes on every rendered frame.
|
|
28
|
+
*/
|
|
29
|
+
function LottieReadout({ lottie, unit = "frames", className, ...rest }) {
|
|
30
|
+
const { subscribe, playableFrames, playableDuration, animationItem } = require_useLottieInstance.useLottieInstance(lottie);
|
|
31
|
+
const element = (0, react.useRef)(null);
|
|
32
|
+
const secondsPerFrame = playableFrames === 0 ? 0 : playableDuration / playableFrames;
|
|
33
|
+
(0, react.useEffect)(() => {
|
|
34
|
+
const write = (frame) => {
|
|
35
|
+
const node = element.current;
|
|
36
|
+
if (node !== null) node.textContent = format(frame, secondsPerFrame, unit);
|
|
37
|
+
};
|
|
38
|
+
write(animationItem === null ? 0 : animationItem.currentFrame);
|
|
39
|
+
return subscribe(require_types.LottieSubscription.frame, ({ currentFrame }) => {
|
|
40
|
+
write(currentFrame);
|
|
41
|
+
});
|
|
42
|
+
}, [
|
|
43
|
+
subscribe,
|
|
44
|
+
animationItem,
|
|
45
|
+
secondsPerFrame,
|
|
46
|
+
unit
|
|
47
|
+
]);
|
|
48
|
+
const total = format(Math.max(playableFrames - 1, 0), secondsPerFrame, unit);
|
|
49
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("output", {
|
|
50
|
+
...rest,
|
|
51
|
+
className: className ? `${lottieReadoutClass} ${className}` : lottieReadoutClass,
|
|
52
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
53
|
+
ref: element,
|
|
54
|
+
style: { minWidth: `${String(total.length)}ch` },
|
|
55
|
+
children: format(0, secondsPerFrame, unit)
|
|
56
|
+
}), ` / ${total}`]
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
exports.LottieReadout = LottieReadout;
|
|
61
|
+
exports.lottieReadoutClass = lottieReadoutClass;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import "../animation/types.cjs";
|
|
2
|
+
//#region src/controls/LottieReadout.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* What the position is counted in.
|
|
5
|
+
*
|
|
6
|
+
* A plain union rather than an object map, unlike the library's public
|
|
7
|
+
* vocabulary, because nothing reads it at runtime: it is only ever written as a
|
|
8
|
+
* literal at a call site, so a runtime object would ship to every consumer of
|
|
9
|
+
* the bar in order to serve nobody.
|
|
10
|
+
*/
|
|
11
|
+
type LottieReadoutUnit = "frames" | "seconds";
|
|
12
|
+
//#endregion
|
|
13
|
+
export { LottieReadoutUnit };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import "../animation/types.js";
|
|
2
|
+
//#region src/controls/LottieReadout.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* What the position is counted in.
|
|
5
|
+
*
|
|
6
|
+
* A plain union rather than an object map, unlike the library's public
|
|
7
|
+
* vocabulary, because nothing reads it at runtime: it is only ever written as a
|
|
8
|
+
* literal at a call site, so a runtime object would ship to every consumer of
|
|
9
|
+
* the bar in order to serve nobody.
|
|
10
|
+
*/
|
|
11
|
+
type LottieReadoutUnit = "frames" | "seconds";
|
|
12
|
+
//#endregion
|
|
13
|
+
export { LottieReadoutUnit };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { useLottieInstance } from "../animation/useLottieInstance.js";
|
|
2
|
+
import { LottieSubscription } from "../animation/types.js";
|
|
3
|
+
import { useEffect, useRef } from "react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/controls/LottieReadout.tsx
|
|
6
|
+
/** The class this control carries, which the bar's stylesheet targets. */
|
|
7
|
+
const lottieReadoutClass = "lottie-readout";
|
|
8
|
+
/**
|
|
9
|
+
* One position, in whichever unit was asked for.
|
|
10
|
+
*
|
|
11
|
+
* Seconds carry one decimal rather than the `0:04` a video player would use.
|
|
12
|
+
* Most animations are a few seconds long, so minutes are always zero and the
|
|
13
|
+
* seconds place is the only one doing any work, which makes dragging look like
|
|
14
|
+
* it is doing nothing.
|
|
15
|
+
*/
|
|
16
|
+
function format(frames, secondsPerFrame, unit) {
|
|
17
|
+
return unit === "seconds" ? `${(frames * secondsPerFrame).toFixed(1)}s` : String(Math.round(frames));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Where the playhead is, and how far it has to go.
|
|
21
|
+
*
|
|
22
|
+
* Both numbers describe what is currently playable rather than the whole file,
|
|
23
|
+
* so a segment moves them together. With nothing loaded they are zeros, which
|
|
24
|
+
* keeps the element the same shape it will be a moment later.
|
|
25
|
+
*
|
|
26
|
+
* Like the seek bar, the moving half is written straight onto the element rather
|
|
27
|
+
* than held in state, because it changes on every rendered frame.
|
|
28
|
+
*/
|
|
29
|
+
function LottieReadout({ lottie, unit = "frames", className, ...rest }) {
|
|
30
|
+
const { subscribe, playableFrames, playableDuration, animationItem } = useLottieInstance(lottie);
|
|
31
|
+
const element = useRef(null);
|
|
32
|
+
const secondsPerFrame = playableFrames === 0 ? 0 : playableDuration / playableFrames;
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
const write = (frame) => {
|
|
35
|
+
const node = element.current;
|
|
36
|
+
if (node !== null) node.textContent = format(frame, secondsPerFrame, unit);
|
|
37
|
+
};
|
|
38
|
+
write(animationItem === null ? 0 : animationItem.currentFrame);
|
|
39
|
+
return subscribe(LottieSubscription.frame, ({ currentFrame }) => {
|
|
40
|
+
write(currentFrame);
|
|
41
|
+
});
|
|
42
|
+
}, [
|
|
43
|
+
subscribe,
|
|
44
|
+
animationItem,
|
|
45
|
+
secondsPerFrame,
|
|
46
|
+
unit
|
|
47
|
+
]);
|
|
48
|
+
const total = format(Math.max(playableFrames - 1, 0), secondsPerFrame, unit);
|
|
49
|
+
return /* @__PURE__ */ jsxs("output", {
|
|
50
|
+
...rest,
|
|
51
|
+
className: className ? `${lottieReadoutClass} ${className}` : lottieReadoutClass,
|
|
52
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
53
|
+
ref: element,
|
|
54
|
+
style: { minWidth: `${String(total.length)}ch` },
|
|
55
|
+
children: format(0, secondsPerFrame, unit)
|
|
56
|
+
}), ` / ${total}`]
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
export { LottieReadout, lottieReadoutClass };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const require_useLottieInstance = require("../animation/useLottieInstance.cjs");
|
|
2
|
+
const require_types = require("../animation/types.cjs");
|
|
3
|
+
let react = require("react");
|
|
4
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
|
+
//#region src/controls/LottieSeekBar.tsx
|
|
6
|
+
/** The class this control carries, which the bar's stylesheet targets. */
|
|
7
|
+
const lottieSeekClass = "lottie-seek";
|
|
8
|
+
/**
|
|
9
|
+
* Shows where the playhead is, and moves it.
|
|
10
|
+
*
|
|
11
|
+
* A native range input, so the browser turns a frame number into a position on
|
|
12
|
+
* the track and nothing here computes geometry. That also means the element
|
|
13
|
+
* reports its own value to assistive technology, which is why no `aria-valuenow`
|
|
14
|
+
* is written: one hardcoded here is exactly the defect the old player shipped,
|
|
15
|
+
* where a screen reader was told the position was zero forever.
|
|
16
|
+
*
|
|
17
|
+
* The position is written straight onto the element rather than held in state,
|
|
18
|
+
* because it changes on every rendered frame and this component would otherwise
|
|
19
|
+
* re-render sixty times a second on top of the animation's own work. The input
|
|
20
|
+
* is uncontrolled, which is what stops React putting its own value back.
|
|
21
|
+
*/
|
|
22
|
+
function LottieSeekBar({ lottie, className, ...rest }) {
|
|
23
|
+
const instance = require_useLottieInstance.useLottieInstance(lottie);
|
|
24
|
+
const { subscribe, playableFrames, animationItem } = instance;
|
|
25
|
+
const element = (0, react.useRef)(null);
|
|
26
|
+
const dragging = (0, react.useRef)(false);
|
|
27
|
+
const stopWatching = (0, react.useRef)(() => void 0);
|
|
28
|
+
(0, react.useEffect)(() => () => {
|
|
29
|
+
stopWatching.current();
|
|
30
|
+
}, []);
|
|
31
|
+
(0, react.useEffect)(() => {
|
|
32
|
+
const write = (frame) => {
|
|
33
|
+
const node = element.current;
|
|
34
|
+
if (node !== null && !dragging.current) node.value = String(frame);
|
|
35
|
+
};
|
|
36
|
+
write(animationItem === null ? 0 : animationItem.currentFrame);
|
|
37
|
+
return subscribe(require_types.LottieSubscription.frame, ({ currentFrame }) => {
|
|
38
|
+
write(currentFrame);
|
|
39
|
+
});
|
|
40
|
+
}, [subscribe, animationItem]);
|
|
41
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
42
|
+
"aria-label": "Seek",
|
|
43
|
+
title: "Seek",
|
|
44
|
+
...rest,
|
|
45
|
+
className: className ? `${lottieSeekClass} ${className}` : lottieSeekClass,
|
|
46
|
+
defaultValue: 0,
|
|
47
|
+
max: Math.max(playableFrames - 1, 0),
|
|
48
|
+
min: 0,
|
|
49
|
+
onChange: (event) => {
|
|
50
|
+
const frame = Number(event.target.value);
|
|
51
|
+
if (dragging.current) instance.scrubTo(frame);
|
|
52
|
+
else instance.seek(frame);
|
|
53
|
+
},
|
|
54
|
+
onKeyDown: (event) => {
|
|
55
|
+
const forward = event.key === "ArrowRight" || event.key === "ArrowUp";
|
|
56
|
+
const back = event.key === "ArrowLeft" || event.key === "ArrowDown";
|
|
57
|
+
if (!forward && !back) return;
|
|
58
|
+
event.preventDefault();
|
|
59
|
+
instance.pause();
|
|
60
|
+
const node = element.current;
|
|
61
|
+
const from = node === null ? 0 : Number(node.value);
|
|
62
|
+
instance.seek(forward ? Math.floor(from) + 1 : Math.ceil(from) - 1);
|
|
63
|
+
},
|
|
64
|
+
onPointerDown: () => {
|
|
65
|
+
dragging.current = true;
|
|
66
|
+
instance.scrubStart();
|
|
67
|
+
const end = () => {
|
|
68
|
+
stopWatching.current();
|
|
69
|
+
dragging.current = false;
|
|
70
|
+
instance.scrubEnd();
|
|
71
|
+
};
|
|
72
|
+
stopWatching.current = () => {
|
|
73
|
+
stopWatching.current = () => void 0;
|
|
74
|
+
window.removeEventListener("pointerup", end);
|
|
75
|
+
window.removeEventListener("pointercancel", end);
|
|
76
|
+
};
|
|
77
|
+
window.addEventListener("pointerup", end);
|
|
78
|
+
window.addEventListener("pointercancel", end);
|
|
79
|
+
},
|
|
80
|
+
ref: element,
|
|
81
|
+
step: "any",
|
|
82
|
+
type: "range"
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
//#endregion
|
|
86
|
+
exports.LottieSeekBar = LottieSeekBar;
|
|
87
|
+
exports.lottieSeekClass = lottieSeekClass;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { useLottieInstance } from "../animation/useLottieInstance.js";
|
|
2
|
+
import { LottieSubscription } from "../animation/types.js";
|
|
3
|
+
import { useEffect, useRef } from "react";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/controls/LottieSeekBar.tsx
|
|
6
|
+
/** The class this control carries, which the bar's stylesheet targets. */
|
|
7
|
+
const lottieSeekClass = "lottie-seek";
|
|
8
|
+
/**
|
|
9
|
+
* Shows where the playhead is, and moves it.
|
|
10
|
+
*
|
|
11
|
+
* A native range input, so the browser turns a frame number into a position on
|
|
12
|
+
* the track and nothing here computes geometry. That also means the element
|
|
13
|
+
* reports its own value to assistive technology, which is why no `aria-valuenow`
|
|
14
|
+
* is written: one hardcoded here is exactly the defect the old player shipped,
|
|
15
|
+
* where a screen reader was told the position was zero forever.
|
|
16
|
+
*
|
|
17
|
+
* The position is written straight onto the element rather than held in state,
|
|
18
|
+
* because it changes on every rendered frame and this component would otherwise
|
|
19
|
+
* re-render sixty times a second on top of the animation's own work. The input
|
|
20
|
+
* is uncontrolled, which is what stops React putting its own value back.
|
|
21
|
+
*/
|
|
22
|
+
function LottieSeekBar({ lottie, className, ...rest }) {
|
|
23
|
+
const instance = useLottieInstance(lottie);
|
|
24
|
+
const { subscribe, playableFrames, animationItem } = instance;
|
|
25
|
+
const element = useRef(null);
|
|
26
|
+
const dragging = useRef(false);
|
|
27
|
+
const stopWatching = useRef(() => void 0);
|
|
28
|
+
useEffect(() => () => {
|
|
29
|
+
stopWatching.current();
|
|
30
|
+
}, []);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
const write = (frame) => {
|
|
33
|
+
const node = element.current;
|
|
34
|
+
if (node !== null && !dragging.current) node.value = String(frame);
|
|
35
|
+
};
|
|
36
|
+
write(animationItem === null ? 0 : animationItem.currentFrame);
|
|
37
|
+
return subscribe(LottieSubscription.frame, ({ currentFrame }) => {
|
|
38
|
+
write(currentFrame);
|
|
39
|
+
});
|
|
40
|
+
}, [subscribe, animationItem]);
|
|
41
|
+
return /* @__PURE__ */ jsx("input", {
|
|
42
|
+
"aria-label": "Seek",
|
|
43
|
+
title: "Seek",
|
|
44
|
+
...rest,
|
|
45
|
+
className: className ? `${lottieSeekClass} ${className}` : lottieSeekClass,
|
|
46
|
+
defaultValue: 0,
|
|
47
|
+
max: Math.max(playableFrames - 1, 0),
|
|
48
|
+
min: 0,
|
|
49
|
+
onChange: (event) => {
|
|
50
|
+
const frame = Number(event.target.value);
|
|
51
|
+
if (dragging.current) instance.scrubTo(frame);
|
|
52
|
+
else instance.seek(frame);
|
|
53
|
+
},
|
|
54
|
+
onKeyDown: (event) => {
|
|
55
|
+
const forward = event.key === "ArrowRight" || event.key === "ArrowUp";
|
|
56
|
+
const back = event.key === "ArrowLeft" || event.key === "ArrowDown";
|
|
57
|
+
if (!forward && !back) return;
|
|
58
|
+
event.preventDefault();
|
|
59
|
+
instance.pause();
|
|
60
|
+
const node = element.current;
|
|
61
|
+
const from = node === null ? 0 : Number(node.value);
|
|
62
|
+
instance.seek(forward ? Math.floor(from) + 1 : Math.ceil(from) - 1);
|
|
63
|
+
},
|
|
64
|
+
onPointerDown: () => {
|
|
65
|
+
dragging.current = true;
|
|
66
|
+
instance.scrubStart();
|
|
67
|
+
const end = () => {
|
|
68
|
+
stopWatching.current();
|
|
69
|
+
dragging.current = false;
|
|
70
|
+
instance.scrubEnd();
|
|
71
|
+
};
|
|
72
|
+
stopWatching.current = () => {
|
|
73
|
+
stopWatching.current = () => void 0;
|
|
74
|
+
window.removeEventListener("pointerup", end);
|
|
75
|
+
window.removeEventListener("pointercancel", end);
|
|
76
|
+
};
|
|
77
|
+
window.addEventListener("pointerup", end);
|
|
78
|
+
window.addEventListener("pointercancel", end);
|
|
79
|
+
},
|
|
80
|
+
ref: element,
|
|
81
|
+
step: "any",
|
|
82
|
+
type: "range"
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
//#endregion
|
|
86
|
+
export { LottieSeekBar, lottieSeekClass };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const require_useLottieInstance = require("../animation/useLottieInstance.cjs");
|
|
2
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
3
|
+
//#region src/controls/LottieSpeedSelect.tsx
|
|
4
|
+
/** The class this control carries, which the bar's stylesheet targets. */
|
|
5
|
+
const lottieSpeedClass = "lottie-speed";
|
|
6
|
+
/** The rates offered, slow ones included because inspecting a file needs them. */
|
|
7
|
+
const rates = [
|
|
8
|
+
.25,
|
|
9
|
+
.5,
|
|
10
|
+
.75,
|
|
11
|
+
1,
|
|
12
|
+
1.25,
|
|
13
|
+
1.5,
|
|
14
|
+
2
|
|
15
|
+
];
|
|
16
|
+
/**
|
|
17
|
+
* Chooses how fast the animation plays.
|
|
18
|
+
*
|
|
19
|
+
* A native `<select>`, which is what makes this control affordable at all. The
|
|
20
|
+
* player this replaces built a custom dropdown whose options stayed in the
|
|
21
|
+
* document when it was closed, so every animation on a page added seven
|
|
22
|
+
* invisible tab stops, and it carried none of the menu semantics that would have
|
|
23
|
+
* made a custom one usable. The native element has one tab stop and needs no
|
|
24
|
+
* semantics of ours.
|
|
25
|
+
*
|
|
26
|
+
* A rate set from somewhere else, a prop or `setSpeed`, is added to the list
|
|
27
|
+
* rather than ignored, so the control never sits blank or reports a rate the
|
|
28
|
+
* animation is not playing at.
|
|
29
|
+
*/
|
|
30
|
+
function LottieSpeedSelect({ lottie, className, ...rest }) {
|
|
31
|
+
const instance = require_useLottieInstance.useLottieInstance(lottie);
|
|
32
|
+
const { speed } = instance;
|
|
33
|
+
const offered = rates.includes(speed) ? rates : [...rates, speed].sort((first, second) => first - second);
|
|
34
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
35
|
+
"aria-label": "Playback speed",
|
|
36
|
+
title: "Playback speed",
|
|
37
|
+
...rest,
|
|
38
|
+
className: className ? `${lottieSpeedClass} ${className}` : lottieSpeedClass,
|
|
39
|
+
onChange: (event) => {
|
|
40
|
+
instance.setSpeed(Number(event.target.value));
|
|
41
|
+
},
|
|
42
|
+
value: String(speed),
|
|
43
|
+
children: offered.map((rate) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
|
|
44
|
+
value: String(rate),
|
|
45
|
+
children: [rate, "x"]
|
|
46
|
+
}, rate))
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
exports.LottieSpeedSelect = LottieSpeedSelect;
|
|
51
|
+
exports.lottieSpeedClass = lottieSpeedClass;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useLottieInstance } from "../animation/useLottieInstance.js";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
//#region src/controls/LottieSpeedSelect.tsx
|
|
4
|
+
/** The class this control carries, which the bar's stylesheet targets. */
|
|
5
|
+
const lottieSpeedClass = "lottie-speed";
|
|
6
|
+
/** The rates offered, slow ones included because inspecting a file needs them. */
|
|
7
|
+
const rates = [
|
|
8
|
+
.25,
|
|
9
|
+
.5,
|
|
10
|
+
.75,
|
|
11
|
+
1,
|
|
12
|
+
1.25,
|
|
13
|
+
1.5,
|
|
14
|
+
2
|
|
15
|
+
];
|
|
16
|
+
/**
|
|
17
|
+
* Chooses how fast the animation plays.
|
|
18
|
+
*
|
|
19
|
+
* A native `<select>`, which is what makes this control affordable at all. The
|
|
20
|
+
* player this replaces built a custom dropdown whose options stayed in the
|
|
21
|
+
* document when it was closed, so every animation on a page added seven
|
|
22
|
+
* invisible tab stops, and it carried none of the menu semantics that would have
|
|
23
|
+
* made a custom one usable. The native element has one tab stop and needs no
|
|
24
|
+
* semantics of ours.
|
|
25
|
+
*
|
|
26
|
+
* A rate set from somewhere else, a prop or `setSpeed`, is added to the list
|
|
27
|
+
* rather than ignored, so the control never sits blank or reports a rate the
|
|
28
|
+
* animation is not playing at.
|
|
29
|
+
*/
|
|
30
|
+
function LottieSpeedSelect({ lottie, className, ...rest }) {
|
|
31
|
+
const instance = useLottieInstance(lottie);
|
|
32
|
+
const { speed } = instance;
|
|
33
|
+
const offered = rates.includes(speed) ? rates : [...rates, speed].sort((first, second) => first - second);
|
|
34
|
+
return /* @__PURE__ */ jsx("select", {
|
|
35
|
+
"aria-label": "Playback speed",
|
|
36
|
+
title: "Playback speed",
|
|
37
|
+
...rest,
|
|
38
|
+
className: className ? `${lottieSpeedClass} ${className}` : lottieSpeedClass,
|
|
39
|
+
onChange: (event) => {
|
|
40
|
+
instance.setSpeed(Number(event.target.value));
|
|
41
|
+
},
|
|
42
|
+
value: String(speed),
|
|
43
|
+
children: offered.map((rate) => /* @__PURE__ */ jsxs("option", {
|
|
44
|
+
value: String(rate),
|
|
45
|
+
children: [rate, "x"]
|
|
46
|
+
}, rate))
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { LottieSpeedSelect, lottieSpeedClass };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const require_useLottieInstance = require("../animation/useLottieInstance.cjs");
|
|
2
|
+
const require_controlIcon = require("./controlIcon.cjs");
|
|
3
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
4
|
+
//#region src/controls/LottieStopButton.tsx
|
|
5
|
+
/** The class this control carries, which the bar's stylesheet targets. */
|
|
6
|
+
const lottieStopClass = "lottie-stop";
|
|
7
|
+
const stopPath = "M6 6h12v12H6z";
|
|
8
|
+
/**
|
|
9
|
+
* Stops the animation and returns it to the first frame of what is playable.
|
|
10
|
+
*
|
|
11
|
+
* Distinct from pausing, which leaves the playhead where it is. Both exist
|
|
12
|
+
* because this control set is for inspecting a file, where returning to a known
|
|
13
|
+
* position is something you do constantly.
|
|
14
|
+
*/
|
|
15
|
+
function LottieStopButton({ lottie, className, ...rest }) {
|
|
16
|
+
const instance = require_useLottieInstance.useLottieInstance(lottie);
|
|
17
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
18
|
+
"aria-label": "Stop",
|
|
19
|
+
title: "Stop",
|
|
20
|
+
...rest,
|
|
21
|
+
className: className ? `${lottieStopClass} ${className}` : lottieStopClass,
|
|
22
|
+
onClick: instance.stop,
|
|
23
|
+
type: "button",
|
|
24
|
+
children: require_controlIcon.controlIcon(stopPath)
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
exports.LottieStopButton = LottieStopButton;
|
|
29
|
+
exports.lottieStopClass = lottieStopClass;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { useLottieInstance } from "../animation/useLottieInstance.js";
|
|
2
|
+
import { controlIcon } from "./controlIcon.js";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/controls/LottieStopButton.tsx
|
|
5
|
+
/** The class this control carries, which the bar's stylesheet targets. */
|
|
6
|
+
const lottieStopClass = "lottie-stop";
|
|
7
|
+
const stopPath = "M6 6h12v12H6z";
|
|
8
|
+
/**
|
|
9
|
+
* Stops the animation and returns it to the first frame of what is playable.
|
|
10
|
+
*
|
|
11
|
+
* Distinct from pausing, which leaves the playhead where it is. Both exist
|
|
12
|
+
* because this control set is for inspecting a file, where returning to a known
|
|
13
|
+
* position is something you do constantly.
|
|
14
|
+
*/
|
|
15
|
+
function LottieStopButton({ lottie, className, ...rest }) {
|
|
16
|
+
const instance = useLottieInstance(lottie);
|
|
17
|
+
return /* @__PURE__ */ jsx("button", {
|
|
18
|
+
"aria-label": "Stop",
|
|
19
|
+
title: "Stop",
|
|
20
|
+
...rest,
|
|
21
|
+
className: className ? `${lottieStopClass} ${className}` : lottieStopClass,
|
|
22
|
+
onClick: instance.stop,
|
|
23
|
+
type: "button",
|
|
24
|
+
children: controlIcon(stopPath)
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { LottieStopButton, lottieStopClass };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
2
|
+
//#region src/controls/controlIcon.tsx
|
|
3
|
+
/**
|
|
4
|
+
* One control's icon, drawn from a single path on a 24 unit grid.
|
|
5
|
+
*
|
|
6
|
+
* Every icon in the bar is one shape, filled in `currentColor` so it takes the
|
|
7
|
+
* button's own colour, and hidden from assistive technology because the button
|
|
8
|
+
* already carries a label. Sharing the wrapper rather than repeating it is worth
|
|
9
|
+
* doing here: in the player this replaces, the identical `<svg>` opening tag was
|
|
10
|
+
* about two thirds of every icon's source.
|
|
11
|
+
*
|
|
12
|
+
* A function rather than a component, because nothing needs it to be one: it has
|
|
13
|
+
* no state, takes no children, and adding a component boundary would put a node
|
|
14
|
+
* in the tree for React to reconcile on every render of the bar.
|
|
15
|
+
*/
|
|
16
|
+
function controlIcon(path) {
|
|
17
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
18
|
+
viewBox: "0 0 24 24",
|
|
19
|
+
fill: "currentColor",
|
|
20
|
+
"aria-hidden": "true",
|
|
21
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: path })
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
exports.controlIcon = controlIcon;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
//#region src/controls/controlIcon.tsx
|
|
3
|
+
/**
|
|
4
|
+
* One control's icon, drawn from a single path on a 24 unit grid.
|
|
5
|
+
*
|
|
6
|
+
* Every icon in the bar is one shape, filled in `currentColor` so it takes the
|
|
7
|
+
* button's own colour, and hidden from assistive technology because the button
|
|
8
|
+
* already carries a label. Sharing the wrapper rather than repeating it is worth
|
|
9
|
+
* doing here: in the player this replaces, the identical `<svg>` opening tag was
|
|
10
|
+
* about two thirds of every icon's source.
|
|
11
|
+
*
|
|
12
|
+
* A function rather than a component, because nothing needs it to be one: it has
|
|
13
|
+
* no state, takes no children, and adding a component boundary would put a node
|
|
14
|
+
* in the tree for React to reconcile on every render of the bar.
|
|
15
|
+
*/
|
|
16
|
+
function controlIcon(path) {
|
|
17
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
18
|
+
viewBox: "0 0 24 24",
|
|
19
|
+
fill: "currentColor",
|
|
20
|
+
"aria-hidden": "true",
|
|
21
|
+
children: /* @__PURE__ */ jsx("path", { d: path })
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { controlIcon };
|