yet-another-react-lightbox 3.5.4 → 3.6.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/dist/index.d.ts +240 -4
- package/dist/index.js +1317 -4
- package/dist/plugins/captions/captions.css +1 -33
- package/dist/plugins/captions/captions.css.d.ts +2 -0
- package/dist/plugins/captions/index.d.ts +8 -4
- package/dist/plugins/captions/index.js +104 -3
- package/dist/plugins/counter/counter.css +1 -16
- package/dist/plugins/counter/counter.css.d.ts +2 -0
- package/dist/plugins/counter/index.d.ts +8 -3
- package/dist/plugins/counter/index.js +18 -2
- package/dist/plugins/download/index.d.ts +6 -3
- package/dist/plugins/download/index.js +90 -3
- package/dist/plugins/fullscreen/index.d.ts +8 -4
- package/dist/plugins/fullscreen/index.js +128 -3
- package/dist/plugins/index.d.ts +9 -9
- package/dist/plugins/index.js +9 -9
- package/dist/plugins/inline/index.d.ts +8 -3
- package/dist/plugins/inline/index.js +26 -2
- package/dist/plugins/slideshow/index.d.ts +8 -4
- package/dist/plugins/slideshow/index.js +113 -3
- package/dist/plugins/thumbnails/index.d.ts +7 -4
- package/dist/plugins/thumbnails/index.js +262 -3
- package/dist/plugins/thumbnails/thumbnails.css +1 -139
- package/dist/plugins/thumbnails/thumbnails.css.d.ts +2 -0
- package/dist/plugins/video/index.d.ts +7 -2
- package/dist/plugins/video/index.js +109 -2
- package/dist/plugins/zoom/index.d.ts +7 -4
- package/dist/plugins/zoom/index.js +499 -3
- package/dist/styles.css +1 -281
- package/dist/styles.css.d.ts +2 -0
- package/dist/types.d.ts +123 -47
- package/dist/types.js +51 -1
- package/package.json +34 -10
- package/dist/Lightbox.d.ts +0 -4
- package/dist/Lightbox.js +0 -46
- package/dist/core/components/IconButton.d.ts +0 -7
- package/dist/core/components/IconButton.js +0 -8
- package/dist/core/components/Icons.d.ts +0 -29
- package/dist/core/components/Icons.js +0 -27
- package/dist/core/components/ImageSlide.d.ts +0 -13
- package/dist/core/components/ImageSlide.js +0 -68
- package/dist/core/components/index.d.ts +0 -3
- package/dist/core/components/index.js +0 -3
- package/dist/core/config.d.ts +0 -7
- package/dist/core/config.js +0 -93
- package/dist/core/consts.d.ts +0 -50
- package/dist/core/consts.js +0 -49
- package/dist/core/contexts/Events.d.ts +0 -17
- package/dist/core/contexts/Events.js +0 -29
- package/dist/core/contexts/LightboxProps.d.ts +0 -6
- package/dist/core/contexts/LightboxProps.js +0 -7
- package/dist/core/contexts/LightboxState.d.ts +0 -27
- package/dist/core/contexts/LightboxState.js +0 -49
- package/dist/core/contexts/Timeouts.d.ts +0 -8
- package/dist/core/contexts/Timeouts.js +0 -32
- package/dist/core/contexts/index.d.ts +0 -4
- package/dist/core/contexts/index.js +0 -4
- package/dist/core/hooks/index.d.ts +0 -11
- package/dist/core/hooks/index.js +0 -11
- package/dist/core/hooks/useAnimation.d.ts +0 -15
- package/dist/core/hooks/useAnimation.js +0 -57
- package/dist/core/hooks/useContainerRect.d.ts +0 -7
- package/dist/core/hooks/useContainerRect.js +0 -36
- package/dist/core/hooks/useDelay.d.ts +0 -1
- package/dist/core/hooks/useDelay.js +0 -10
- package/dist/core/hooks/useEventCallback.d.ts +0 -1
- package/dist/core/hooks/useEventCallback.js +0 -9
- package/dist/core/hooks/useForkRef.d.ts +0 -3
- package/dist/core/hooks/useForkRef.js +0 -17
- package/dist/core/hooks/useLayoutEffect.d.ts +0 -2
- package/dist/core/hooks/useLayoutEffect.js +0 -3
- package/dist/core/hooks/useLoseFocus.d.ts +0 -4
- package/dist/core/hooks/useLoseFocus.js +0 -19
- package/dist/core/hooks/useMotionPreference.d.ts +0 -1
- package/dist/core/hooks/useMotionPreference.js +0 -13
- package/dist/core/hooks/useRTL.d.ts +0 -1
- package/dist/core/hooks/useRTL.js +0 -9
- package/dist/core/hooks/useSensors.d.ts +0 -14
- package/dist/core/hooks/useSensors.js +0 -38
- package/dist/core/hooks/useThrottle.d.ts +0 -1
- package/dist/core/hooks/useThrottle.js +0 -16
- package/dist/core/index.d.ts +0 -7
- package/dist/core/index.js +0 -7
- package/dist/core/modules/Carousel.d.ts +0 -4
- package/dist/core/modules/Carousel.js +0 -72
- package/dist/core/modules/Controller.d.ts +0 -31
- package/dist/core/modules/Controller.js +0 -215
- package/dist/core/modules/Navigation.d.ts +0 -13
- package/dist/core/modules/Navigation.js +0 -35
- package/dist/core/modules/NoScroll.d.ts +0 -4
- package/dist/core/modules/NoScroll.js +0 -52
- package/dist/core/modules/Portal.d.ts +0 -4
- package/dist/core/modules/Portal.js +0 -92
- package/dist/core/modules/Root.d.ts +0 -4
- package/dist/core/modules/Root.js +0 -7
- package/dist/core/modules/Toolbar.d.ts +0 -4
- package/dist/core/modules/Toolbar.js +0 -25
- package/dist/core/modules/controller/index.d.ts +0 -8
- package/dist/core/modules/controller/index.js +0 -9
- package/dist/core/modules/controller/usePointerSwipe.d.ts +0 -2
- package/dist/core/modules/controller/usePointerSwipe.js +0 -72
- package/dist/core/modules/controller/usePreventSwipeNavigation.d.ts +0 -3
- package/dist/core/modules/controller/usePreventSwipeNavigation.js +0 -20
- package/dist/core/modules/controller/useWheelSwipe.d.ts +0 -3
- package/dist/core/modules/controller/useWheelSwipe.js +0 -92
- package/dist/core/modules/index.d.ts +0 -7
- package/dist/core/modules/index.js +0 -7
- package/dist/core/utils.d.ts +0 -36
- package/dist/core/utils.js +0 -70
- package/dist/plugins/captions/Captions.d.ts +0 -3
- package/dist/plugins/captions/Captions.js +0 -25
- package/dist/plugins/captions/CaptionsButton.d.ts +0 -2
- package/dist/plugins/captions/CaptionsButton.js +0 -16
- package/dist/plugins/captions/CaptionsContext.d.ts +0 -5
- package/dist/plugins/captions/CaptionsContext.js +0 -16
- package/dist/plugins/captions/Description.d.ts +0 -4
- package/dist/plugins/captions/Description.js +0 -27
- package/dist/plugins/captions/Title.d.ts +0 -4
- package/dist/plugins/captions/Title.js +0 -16
- package/dist/plugins/captions/props.d.ts +0 -19
- package/dist/plugins/captions/props.js +0 -14
- package/dist/plugins/captions/utils.d.ts +0 -1
- package/dist/plugins/captions/utils.js +0 -2
- package/dist/plugins/counter/Counter.d.ts +0 -5
- package/dist/plugins/counter/Counter.js +0 -14
- package/dist/plugins/download/Download.d.ts +0 -2
- package/dist/plugins/download/Download.js +0 -9
- package/dist/plugins/download/DownloadButton.d.ts +0 -2
- package/dist/plugins/download/DownloadButton.js +0 -19
- package/dist/plugins/download/FileSaver.d.ts +0 -1
- package/dist/plugins/download/FileSaver.js +0 -60
- package/dist/plugins/fullscreen/Fullscreen.d.ts +0 -3
- package/dist/plugins/fullscreen/Fullscreen.js +0 -13
- package/dist/plugins/fullscreen/FullscreenButton.d.ts +0 -3
- package/dist/plugins/fullscreen/FullscreenButton.js +0 -16
- package/dist/plugins/fullscreen/FullscreenContext.d.ts +0 -5
- package/dist/plugins/fullscreen/FullscreenContext.js +0 -93
- package/dist/plugins/fullscreen/props.d.ts +0 -10
- package/dist/plugins/fullscreen/props.js +0 -8
- package/dist/plugins/inline/Inline.d.ts +0 -3
- package/dist/plugins/inline/Inline.js +0 -18
- package/dist/plugins/inline/InlineContainer.d.ts +0 -4
- package/dist/plugins/inline/InlineContainer.js +0 -5
- package/dist/plugins/slideshow/Slideshow.d.ts +0 -3
- package/dist/plugins/slideshow/Slideshow.js +0 -13
- package/dist/plugins/slideshow/SlideshowButton.d.ts +0 -2
- package/dist/plugins/slideshow/SlideshowButton.js +0 -14
- package/dist/plugins/slideshow/SlideshowContext.d.ts +0 -5
- package/dist/plugins/slideshow/SlideshowContext.js +0 -79
- package/dist/plugins/slideshow/props.d.ts +0 -12
- package/dist/plugins/slideshow/props.js +0 -9
- package/dist/plugins/thumbnails/Thumbnail.d.ts +0 -15
- package/dist/plugins/thumbnails/Thumbnail.js +0 -51
- package/dist/plugins/thumbnails/Thumbnails.d.ts +0 -3
- package/dist/plugins/thumbnails/Thumbnails.js +0 -22
- package/dist/plugins/thumbnails/ThumbnailsButton.d.ts +0 -2
- package/dist/plugins/thumbnails/ThumbnailsButton.js +0 -16
- package/dist/plugins/thumbnails/ThumbnailsContext.d.ts +0 -6
- package/dist/plugins/thumbnails/ThumbnailsContext.js +0 -24
- package/dist/plugins/thumbnails/ThumbnailsTrack.d.ts +0 -5
- package/dist/plugins/thumbnails/ThumbnailsTrack.js +0 -141
- package/dist/plugins/thumbnails/props.d.ts +0 -40
- package/dist/plugins/thumbnails/props.js +0 -21
- package/dist/plugins/thumbnails/utils.d.ts +0 -2
- package/dist/plugins/thumbnails/utils.js +0 -4
- package/dist/plugins/video/Video.d.ts +0 -3
- package/dist/plugins/video/Video.js +0 -21
- package/dist/plugins/video/VideoSlide.d.ts +0 -8
- package/dist/plugins/video/VideoSlide.js +0 -74
- package/dist/plugins/video/props.d.ts +0 -29
- package/dist/plugins/video/props.js +0 -13
- package/dist/plugins/zoom/ResponsiveImage.d.ts +0 -11
- package/dist/plugins/zoom/ResponsiveImage.js +0 -58
- package/dist/plugins/zoom/Zoom.d.ts +0 -3
- package/dist/plugins/zoom/Zoom.js +0 -18
- package/dist/plugins/zoom/ZoomButton.d.ts +0 -8
- package/dist/plugins/zoom/ZoomButton.js +0 -27
- package/dist/plugins/zoom/ZoomButtonsGroup.d.ts +0 -2
- package/dist/plugins/zoom/ZoomButtonsGroup.js +0 -22
- package/dist/plugins/zoom/ZoomController.d.ts +0 -12
- package/dist/plugins/zoom/ZoomController.js +0 -17
- package/dist/plugins/zoom/ZoomToolbarControl.d.ts +0 -2
- package/dist/plugins/zoom/ZoomToolbarControl.js +0 -12
- package/dist/plugins/zoom/ZoomWrapper.d.ts +0 -5
- package/dist/plugins/zoom/ZoomWrapper.js +0 -36
- package/dist/plugins/zoom/hooks/index.d.ts +0 -6
- package/dist/plugins/zoom/hooks/index.js +0 -6
- package/dist/plugins/zoom/hooks/useZoomAnimation.d.ts +0 -2
- package/dist/plugins/zoom/hooks/useZoomAnimation.js +0 -39
- package/dist/plugins/zoom/hooks/useZoomCallback.d.ts +0 -1
- package/dist/plugins/zoom/hooks/useZoomCallback.js +0 -12
- package/dist/plugins/zoom/hooks/useZoomImageRect.d.ts +0 -5
- package/dist/plugins/zoom/hooks/useZoomImageRect.js +0 -41
- package/dist/plugins/zoom/hooks/useZoomProps.d.ts +0 -13
- package/dist/plugins/zoom/hooks/useZoomProps.js +0 -6
- package/dist/plugins/zoom/hooks/useZoomSensors.d.ts +0 -3
- package/dist/plugins/zoom/hooks/useZoomSensors.js +0 -154
- package/dist/plugins/zoom/hooks/useZoomState.d.ts +0 -12
- package/dist/plugins/zoom/hooks/useZoomState.js +0 -63
- package/dist/plugins/zoom/props.d.ts +0 -25
- package/dist/plugins/zoom/props.js +0 -15
- package/dist/props.d.ts +0 -2
- package/dist/props.js +0 -38
|
@@ -1,2 +1,109 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useLightboxProps, useEvents, useContainerRect, useEventCallback, clsx, cssClass } from '../../index.js';
|
|
3
|
+
import { ACTIVE_SLIDE_LOADING, CLASS_FLEX_CENTER, ACTIVE_SLIDE_PLAYING, ACTIVE_SLIDE_COMPLETE } from '../../types.js';
|
|
4
|
+
|
|
5
|
+
const defaultVideoProps = {
|
|
6
|
+
controls: true,
|
|
7
|
+
playsInline: true,
|
|
8
|
+
};
|
|
9
|
+
const resolveVideoProps = (video) => ({
|
|
10
|
+
...defaultVideoProps,
|
|
11
|
+
...video,
|
|
12
|
+
});
|
|
13
|
+
function useVideoProps() {
|
|
14
|
+
const { video } = useLightboxProps();
|
|
15
|
+
return resolveVideoProps(video);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function VideoSlide({ slide, offset }) {
|
|
19
|
+
const video = useVideoProps();
|
|
20
|
+
const { publish } = useEvents();
|
|
21
|
+
const { setContainerRef, containerRect } = useContainerRect();
|
|
22
|
+
const videoRef = React.useRef(null);
|
|
23
|
+
React.useEffect(() => {
|
|
24
|
+
if (offset !== 0 && videoRef.current && !videoRef.current.paused) {
|
|
25
|
+
videoRef.current.pause();
|
|
26
|
+
}
|
|
27
|
+
}, [offset]);
|
|
28
|
+
React.useEffect(() => {
|
|
29
|
+
if (offset === 0 && videoRef.current && (slide.autoPlay || video.autoPlay)) {
|
|
30
|
+
publish(ACTIVE_SLIDE_LOADING);
|
|
31
|
+
videoRef.current.play().catch(() => { });
|
|
32
|
+
}
|
|
33
|
+
}, [offset, video.autoPlay, slide.autoPlay, publish]);
|
|
34
|
+
const handleVideoRef = useEventCallback((node) => {
|
|
35
|
+
if (offset === 0 && (video.autoPlay || slide.autoPlay) && node.paused) {
|
|
36
|
+
node.play().catch(() => { });
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
const setVideoRef = React.useCallback((node) => {
|
|
40
|
+
videoRef.current = node;
|
|
41
|
+
if (node) {
|
|
42
|
+
handleVideoRef(node);
|
|
43
|
+
}
|
|
44
|
+
}, [handleVideoRef]);
|
|
45
|
+
const { width, height, poster, sources } = slide;
|
|
46
|
+
const scaleWidthAndHeight = () => {
|
|
47
|
+
const scalingProps = {};
|
|
48
|
+
scalingProps.style = { maxWidth: "100%", maxHeight: "100%" };
|
|
49
|
+
if (width && height && containerRect) {
|
|
50
|
+
const widthBound = width / height > containerRect.width / containerRect.height;
|
|
51
|
+
const elementWidth = widthBound ? containerRect.width : Math.round((containerRect.height / height) * width);
|
|
52
|
+
const elementHeight = !widthBound
|
|
53
|
+
? containerRect.height
|
|
54
|
+
: Math.round((containerRect.width / width) * height);
|
|
55
|
+
scalingProps.width = elementWidth;
|
|
56
|
+
scalingProps.height = elementHeight;
|
|
57
|
+
scalingProps.style.width = elementWidth;
|
|
58
|
+
scalingProps.style.height = elementHeight;
|
|
59
|
+
}
|
|
60
|
+
return scalingProps;
|
|
61
|
+
};
|
|
62
|
+
const resolveBoolean = (attr) => {
|
|
63
|
+
if (slide[attr] === false)
|
|
64
|
+
return null;
|
|
65
|
+
if (slide[attr] === true)
|
|
66
|
+
return { [attr]: true };
|
|
67
|
+
if (video[attr] === false)
|
|
68
|
+
return null;
|
|
69
|
+
if (video[attr] === true)
|
|
70
|
+
return { [attr]: true };
|
|
71
|
+
return null;
|
|
72
|
+
};
|
|
73
|
+
const resolveString = (attr) => {
|
|
74
|
+
if (video[attr] || slide[attr]) {
|
|
75
|
+
return { [attr]: slide[attr] || video[attr] };
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
};
|
|
79
|
+
return (React.createElement(React.Fragment, null, sources && (React.createElement("div", { ref: setContainerRef, style: {
|
|
80
|
+
width: "100%",
|
|
81
|
+
height: "100%",
|
|
82
|
+
...(width ? { maxWidth: `${width}px` } : null),
|
|
83
|
+
}, className: clsx(cssClass("video_container"), cssClass(CLASS_FLEX_CENTER)) }, containerRect && (React.createElement("video", { ref: setVideoRef, poster: poster, ...scaleWidthAndHeight(), ...resolveBoolean("controls"), ...resolveBoolean("playsInline"), ...resolveBoolean("loop"), ...resolveBoolean("muted"), ...resolveBoolean("playsInline"), ...resolveBoolean("disablePictureInPicture"), ...resolveBoolean("disableRemotePlayback"), ...resolveString("controlsList"), ...resolveString("crossOrigin"), ...resolveString("preload"), onPlay: () => {
|
|
84
|
+
publish(ACTIVE_SLIDE_PLAYING);
|
|
85
|
+
}, onEnded: () => {
|
|
86
|
+
publish(ACTIVE_SLIDE_COMPLETE);
|
|
87
|
+
} }, sources.map(({ src, type }, index) => (React.createElement("source", { key: index, src: src, type: type })))))))));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function isVideoSlide(slide) {
|
|
91
|
+
return slide.type === "video";
|
|
92
|
+
}
|
|
93
|
+
function Video({ augment }) {
|
|
94
|
+
augment(({ render: { slide: renderSlide, ...restRender }, video, ...restProps }) => ({
|
|
95
|
+
render: {
|
|
96
|
+
slide: ({ slide, offset, rect }) => {
|
|
97
|
+
if (isVideoSlide(slide)) {
|
|
98
|
+
return (React.createElement(VideoSlide, { key: `${slide.sources.map((source) => source.src).join(" ")}`, slide: slide, offset: offset }));
|
|
99
|
+
}
|
|
100
|
+
return renderSlide === null || renderSlide === void 0 ? void 0 : renderSlide({ slide, offset, rect });
|
|
101
|
+
},
|
|
102
|
+
...restRender,
|
|
103
|
+
},
|
|
104
|
+
video: resolveVideoProps(video),
|
|
105
|
+
...restProps,
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export { Video as default };
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { Plugin, PLUGIN_ZOOM } from '../../types.js';
|
|
2
|
+
|
|
3
|
+
/** Zoom plugin */
|
|
4
|
+
declare const Zoom: Plugin;
|
|
5
|
+
|
|
4
6
|
declare module "../../types.js" {
|
|
5
7
|
interface LightboxProps {
|
|
6
8
|
/** Zoom plugin settings */
|
|
@@ -75,4 +77,5 @@ declare module "../../types.js" {
|
|
|
75
77
|
zoomOut: Callback;
|
|
76
78
|
}
|
|
77
79
|
}
|
|
78
|
-
|
|
80
|
+
|
|
81
|
+
export { Zoom as default };
|
|
@@ -1,3 +1,499 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
|
|
1
|
+
import { useLightboxProps, useMotionPreference, useEventCallback, useLayoutEffect, useLightboxState, isImageSlide, isImageFitCover, round, useController, cleanup, makeUseContext, createIcon, IconButton, devicePixelRatio, ImageSlide, clsx, cssClass, addToolbarButton, createModule } from '../../index.js';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { EVENT_ON_KEY_DOWN, EVENT_ON_WHEEL, EVENT_ON_POINTER_DOWN, EVENT_ON_POINTER_MOVE, EVENT_ON_POINTER_UP, EVENT_ON_POINTER_LEAVE, EVENT_ON_POINTER_CANCEL, UNKNOWN_ACTION_TYPE, CLASS_FULLSIZE, CLASS_FLEX_CENTER, PLUGIN_ZOOM } from '../../types.js';
|
|
4
|
+
|
|
5
|
+
const defaultZoomProps = {
|
|
6
|
+
maxZoomPixelRatio: 1,
|
|
7
|
+
zoomInMultiplier: 2,
|
|
8
|
+
doubleTapDelay: 300,
|
|
9
|
+
doubleClickDelay: 500,
|
|
10
|
+
doubleClickMaxStops: 2,
|
|
11
|
+
keyboardMoveDistance: 50,
|
|
12
|
+
wheelZoomDistanceFactor: 100,
|
|
13
|
+
pinchZoomDistanceFactor: 100,
|
|
14
|
+
scrollToZoom: false,
|
|
15
|
+
};
|
|
16
|
+
const resolveZoomProps = (zoom) => ({
|
|
17
|
+
...defaultZoomProps,
|
|
18
|
+
...zoom,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
function useZoomAnimation(zoom, offsetX, offsetY, zoomWrapperRef) {
|
|
22
|
+
const zoomAnimation = React.useRef();
|
|
23
|
+
const zoomAnimationStart = React.useRef();
|
|
24
|
+
const { zoom: zoomAnimationDuration } = useLightboxProps().animation;
|
|
25
|
+
const reduceMotion = useMotionPreference();
|
|
26
|
+
const playZoomAnimation = useEventCallback(() => {
|
|
27
|
+
var _a, _b, _c;
|
|
28
|
+
(_a = zoomAnimation.current) === null || _a === void 0 ? void 0 : _a.cancel();
|
|
29
|
+
zoomAnimation.current = undefined;
|
|
30
|
+
if (zoomAnimationStart.current && (zoomWrapperRef === null || zoomWrapperRef === void 0 ? void 0 : zoomWrapperRef.current)) {
|
|
31
|
+
try {
|
|
32
|
+
zoomAnimation.current = (_c = (_b = zoomWrapperRef.current).animate) === null || _c === void 0 ? void 0 : _c.call(_b, [
|
|
33
|
+
{ transform: zoomAnimationStart.current },
|
|
34
|
+
{ transform: `scale(${zoom}) translateX(${offsetX}px) translateY(${offsetY}px)` },
|
|
35
|
+
], {
|
|
36
|
+
duration: !reduceMotion ? zoomAnimationDuration !== null && zoomAnimationDuration !== void 0 ? zoomAnimationDuration : 500 : 0,
|
|
37
|
+
easing: zoomAnimation.current ? "ease-out" : "ease-in-out",
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
console.error(err);
|
|
42
|
+
}
|
|
43
|
+
zoomAnimationStart.current = undefined;
|
|
44
|
+
if (zoomAnimation.current) {
|
|
45
|
+
zoomAnimation.current.onfinish = () => {
|
|
46
|
+
zoomAnimation.current = undefined;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
useLayoutEffect(playZoomAnimation, [zoom, offsetX, offsetY, playZoomAnimation]);
|
|
52
|
+
return React.useCallback(() => {
|
|
53
|
+
zoomAnimationStart.current = (zoomWrapperRef === null || zoomWrapperRef === void 0 ? void 0 : zoomWrapperRef.current)
|
|
54
|
+
? window.getComputedStyle(zoomWrapperRef.current).transform
|
|
55
|
+
: undefined;
|
|
56
|
+
}, [zoomWrapperRef]);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function useZoomCallback(zoom, disabled) {
|
|
60
|
+
const { on } = useLightboxProps();
|
|
61
|
+
const onZoomCallback = useEventCallback(() => {
|
|
62
|
+
var _a;
|
|
63
|
+
if (!disabled) {
|
|
64
|
+
(_a = on.zoom) === null || _a === void 0 ? void 0 : _a.call(on, { zoom });
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
React.useEffect(onZoomCallback, [zoom, onZoomCallback]);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function useZoomProps() {
|
|
71
|
+
const { zoom } = useLightboxProps();
|
|
72
|
+
return resolveZoomProps(zoom);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function useZoomImageRect(slideRect, imageDimensions) {
|
|
76
|
+
var _a, _b;
|
|
77
|
+
let imageRect = { width: 0, height: 0 };
|
|
78
|
+
let maxImageRect = { width: 0, height: 0 };
|
|
79
|
+
const { slides, currentIndex } = useLightboxState();
|
|
80
|
+
const { imageFit } = useLightboxProps().carousel;
|
|
81
|
+
const { maxZoomPixelRatio } = useZoomProps();
|
|
82
|
+
if (slideRect && currentIndex < slides.length) {
|
|
83
|
+
const slide = { ...slides[currentIndex], ...imageDimensions };
|
|
84
|
+
if (isImageSlide(slide)) {
|
|
85
|
+
const cover = isImageFitCover(slide, imageFit);
|
|
86
|
+
const width = Math.max(...(((_a = slide.srcSet) === null || _a === void 0 ? void 0 : _a.map((x) => x.width)) || []).concat(slide.width ? [slide.width] : []));
|
|
87
|
+
const height = Math.max(...(((_b = slide.srcSet) === null || _b === void 0 ? void 0 : _b.map((x) => x.height)) || []).concat(slide.height ? [slide.height] : []));
|
|
88
|
+
if (width > 0 && height > 0 && slideRect.width > 0 && slideRect.height > 0) {
|
|
89
|
+
maxImageRect = cover
|
|
90
|
+
? {
|
|
91
|
+
width: Math.round(Math.min(width, (slideRect.width / slideRect.height) * height)),
|
|
92
|
+
height: Math.round(Math.min(height, (slideRect.height / slideRect.width) * width)),
|
|
93
|
+
}
|
|
94
|
+
: { width, height };
|
|
95
|
+
maxImageRect = {
|
|
96
|
+
width: maxImageRect.width * maxZoomPixelRatio,
|
|
97
|
+
height: maxImageRect.height * maxZoomPixelRatio,
|
|
98
|
+
};
|
|
99
|
+
imageRect = cover
|
|
100
|
+
? {
|
|
101
|
+
width: Math.min(slideRect.width, maxImageRect.width, width),
|
|
102
|
+
height: Math.min(slideRect.height, maxImageRect.height, height),
|
|
103
|
+
}
|
|
104
|
+
: {
|
|
105
|
+
width: Math.round(Math.min(slideRect.width, (slideRect.height / height) * width, width)),
|
|
106
|
+
height: Math.round(Math.min(slideRect.height, (slideRect.width / width) * height, height)),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const maxZoom = imageRect.width ? Math.max(round(maxImageRect.width / imageRect.width, 5), 1) : 1;
|
|
112
|
+
return { imageRect, maxZoom };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function distance(pointerA, pointerB) {
|
|
116
|
+
return ((pointerA.clientX - pointerB.clientX) ** 2 + (pointerA.clientY - pointerB.clientY) ** 2) ** 0.5;
|
|
117
|
+
}
|
|
118
|
+
function useZoomSensors(zoom, maxZoom, disabled, changeZoom, changeOffsets, zoomWrapperRef) {
|
|
119
|
+
const activePointers = React.useRef([]);
|
|
120
|
+
const lastPointerDown = React.useRef(0);
|
|
121
|
+
const pinchZoomDistance = React.useRef();
|
|
122
|
+
const { globalIndex } = useLightboxState();
|
|
123
|
+
const { containerRef, subscribeSensors } = useController();
|
|
124
|
+
const { keyboardMoveDistance, zoomInMultiplier, wheelZoomDistanceFactor, scrollToZoom, doubleTapDelay, doubleClickDelay, doubleClickMaxStops, pinchZoomDistanceFactor, } = useZoomProps();
|
|
125
|
+
const translateCoordinates = React.useCallback((event) => {
|
|
126
|
+
if (containerRef.current) {
|
|
127
|
+
const { pageX, pageY } = event;
|
|
128
|
+
const { scrollX, scrollY } = window;
|
|
129
|
+
const { left, top, width, height } = containerRef.current.getBoundingClientRect();
|
|
130
|
+
return [pageX - left - scrollX - width / 2, pageY - top - scrollY - height / 2];
|
|
131
|
+
}
|
|
132
|
+
return [];
|
|
133
|
+
}, [containerRef]);
|
|
134
|
+
const onKeyDown = useEventCallback((event) => {
|
|
135
|
+
const preventDefault = () => {
|
|
136
|
+
event.preventDefault();
|
|
137
|
+
event.stopPropagation();
|
|
138
|
+
};
|
|
139
|
+
if (zoom > 1) {
|
|
140
|
+
const move = (deltaX, deltaY) => {
|
|
141
|
+
preventDefault();
|
|
142
|
+
changeOffsets(deltaX, deltaY);
|
|
143
|
+
};
|
|
144
|
+
if (event.key === "ArrowDown") {
|
|
145
|
+
move(0, keyboardMoveDistance);
|
|
146
|
+
}
|
|
147
|
+
else if (event.key === "ArrowUp") {
|
|
148
|
+
move(0, -keyboardMoveDistance);
|
|
149
|
+
}
|
|
150
|
+
else if (event.key === "ArrowLeft") {
|
|
151
|
+
move(-keyboardMoveDistance, 0);
|
|
152
|
+
}
|
|
153
|
+
else if (event.key === "ArrowRight") {
|
|
154
|
+
move(keyboardMoveDistance, 0);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const handleChangeZoom = (zoomValue) => {
|
|
158
|
+
preventDefault();
|
|
159
|
+
changeZoom(zoomValue);
|
|
160
|
+
};
|
|
161
|
+
const hasMeta = () => event.getModifierState("Meta");
|
|
162
|
+
if (event.key === "+" || (event.key === "=" && hasMeta())) {
|
|
163
|
+
handleChangeZoom(zoom * zoomInMultiplier);
|
|
164
|
+
}
|
|
165
|
+
else if (event.key === "-" || (event.key === "_" && hasMeta())) {
|
|
166
|
+
handleChangeZoom(zoom / zoomInMultiplier);
|
|
167
|
+
}
|
|
168
|
+
else if (event.key === "0" && hasMeta()) {
|
|
169
|
+
handleChangeZoom(1);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
const onWheel = useEventCallback((event) => {
|
|
173
|
+
if (event.ctrlKey || scrollToZoom) {
|
|
174
|
+
if (Math.abs(event.deltaY) > Math.abs(event.deltaX)) {
|
|
175
|
+
event.stopPropagation();
|
|
176
|
+
changeZoom(zoom * (1 - event.deltaY / wheelZoomDistanceFactor), true, ...translateCoordinates(event));
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (zoom > 1) {
|
|
181
|
+
event.stopPropagation();
|
|
182
|
+
if (!scrollToZoom) {
|
|
183
|
+
changeOffsets(event.deltaX, event.deltaY);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
const clearPointer = React.useCallback((event) => {
|
|
188
|
+
const pointers = activePointers.current;
|
|
189
|
+
pointers.splice(0, pointers.length, ...pointers.filter((p) => p.pointerId !== event.pointerId));
|
|
190
|
+
}, []);
|
|
191
|
+
const replacePointer = React.useCallback((event) => {
|
|
192
|
+
clearPointer(event);
|
|
193
|
+
event.persist();
|
|
194
|
+
activePointers.current.push(event);
|
|
195
|
+
}, [clearPointer]);
|
|
196
|
+
const onPointerDown = useEventCallback((event) => {
|
|
197
|
+
var _a;
|
|
198
|
+
const pointers = activePointers.current;
|
|
199
|
+
if (!((_a = zoomWrapperRef === null || zoomWrapperRef === void 0 ? void 0 : zoomWrapperRef.current) === null || _a === void 0 ? void 0 : _a.contains(event.target))) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (zoom > 1) {
|
|
203
|
+
event.stopPropagation();
|
|
204
|
+
}
|
|
205
|
+
const { timeStamp } = event;
|
|
206
|
+
if (pointers.length === 0 &&
|
|
207
|
+
timeStamp - lastPointerDown.current < (event.pointerType === "touch" ? doubleTapDelay : doubleClickDelay)) {
|
|
208
|
+
lastPointerDown.current = 0;
|
|
209
|
+
changeZoom(zoom !== maxZoom ? zoom * Math.max(maxZoom ** (1 / doubleClickMaxStops), zoomInMultiplier) : 1, false, ...translateCoordinates(event));
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
lastPointerDown.current = timeStamp;
|
|
213
|
+
}
|
|
214
|
+
replacePointer(event);
|
|
215
|
+
if (pointers.length === 2) {
|
|
216
|
+
pinchZoomDistance.current = distance(pointers[0], pointers[1]);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
const onPointerMove = useEventCallback((event) => {
|
|
220
|
+
const pointers = activePointers.current;
|
|
221
|
+
const activePointer = pointers.find((p) => p.pointerId === event.pointerId);
|
|
222
|
+
if (pointers.length === 2 && pinchZoomDistance.current) {
|
|
223
|
+
event.stopPropagation();
|
|
224
|
+
replacePointer(event);
|
|
225
|
+
const currentDistance = distance(pointers[0], pointers[1]);
|
|
226
|
+
const delta = currentDistance - pinchZoomDistance.current;
|
|
227
|
+
if (Math.abs(delta) > 0) {
|
|
228
|
+
changeZoom(zoom * (1 + delta / pinchZoomDistanceFactor), true, ...pointers
|
|
229
|
+
.map((x) => translateCoordinates(x))
|
|
230
|
+
.reduce((acc, coordinate) => coordinate.map((x, i) => acc[i] + x / 2)));
|
|
231
|
+
pinchZoomDistance.current = currentDistance;
|
|
232
|
+
}
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (zoom > 1) {
|
|
236
|
+
event.stopPropagation();
|
|
237
|
+
if (activePointer) {
|
|
238
|
+
if (pointers.length === 1) {
|
|
239
|
+
changeOffsets((activePointer.clientX - event.clientX) / zoom, (activePointer.clientY - event.clientY) / zoom);
|
|
240
|
+
}
|
|
241
|
+
replacePointer(event);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
const onPointerUp = React.useCallback((event) => {
|
|
246
|
+
const pointers = activePointers.current;
|
|
247
|
+
if (pointers.length === 2 && pointers.find((p) => p.pointerId === event.pointerId)) {
|
|
248
|
+
pinchZoomDistance.current = undefined;
|
|
249
|
+
}
|
|
250
|
+
clearPointer(event);
|
|
251
|
+
}, [clearPointer]);
|
|
252
|
+
const cleanupSensors = React.useCallback(() => {
|
|
253
|
+
const pointers = activePointers.current;
|
|
254
|
+
pointers.splice(0, pointers.length);
|
|
255
|
+
lastPointerDown.current = 0;
|
|
256
|
+
pinchZoomDistance.current = undefined;
|
|
257
|
+
}, []);
|
|
258
|
+
React.useEffect(cleanupSensors, [globalIndex, cleanupSensors]);
|
|
259
|
+
React.useEffect(() => {
|
|
260
|
+
if (!disabled) {
|
|
261
|
+
return cleanup(cleanupSensors, subscribeSensors(EVENT_ON_KEY_DOWN, onKeyDown), subscribeSensors(EVENT_ON_WHEEL, onWheel), subscribeSensors(EVENT_ON_POINTER_DOWN, onPointerDown), subscribeSensors(EVENT_ON_POINTER_MOVE, onPointerMove), subscribeSensors(EVENT_ON_POINTER_UP, onPointerUp), subscribeSensors(EVENT_ON_POINTER_LEAVE, onPointerUp), subscribeSensors(EVENT_ON_POINTER_CANCEL, onPointerUp));
|
|
262
|
+
}
|
|
263
|
+
return () => { };
|
|
264
|
+
}, [disabled, subscribeSensors, cleanupSensors, onKeyDown, onWheel, onPointerDown, onPointerMove, onPointerUp]);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function getCurrentSource(slides, currentIndex) {
|
|
268
|
+
if (currentIndex < slides.length) {
|
|
269
|
+
const slide = slides[currentIndex];
|
|
270
|
+
if (isImageSlide(slide))
|
|
271
|
+
return slide.src;
|
|
272
|
+
}
|
|
273
|
+
return undefined;
|
|
274
|
+
}
|
|
275
|
+
function useZoomState(imageRect, maxZoom, zoomWrapperRef) {
|
|
276
|
+
const [zoom, setZoom] = React.useState(1);
|
|
277
|
+
const [offsetX, setOffsetX] = React.useState(0);
|
|
278
|
+
const [offsetY, setOffsetY] = React.useState(0);
|
|
279
|
+
const animate = useZoomAnimation(zoom, offsetX, offsetY, zoomWrapperRef);
|
|
280
|
+
const { slides, currentIndex, globalIndex } = useLightboxState();
|
|
281
|
+
const { containerRect, slideRect } = useController();
|
|
282
|
+
const { zoomInMultiplier } = useZoomProps();
|
|
283
|
+
const currentSource = getCurrentSource(slides, currentIndex);
|
|
284
|
+
const disabled = !currentSource || !(zoomWrapperRef === null || zoomWrapperRef === void 0 ? void 0 : zoomWrapperRef.current);
|
|
285
|
+
useLayoutEffect(() => {
|
|
286
|
+
setZoom(1);
|
|
287
|
+
setOffsetX(0);
|
|
288
|
+
setOffsetY(0);
|
|
289
|
+
}, [globalIndex, currentSource]);
|
|
290
|
+
const changeOffsets = React.useCallback((dx, dy, targetZoom) => {
|
|
291
|
+
const newZoom = targetZoom || zoom;
|
|
292
|
+
const newOffsetX = offsetX - (dx || 0);
|
|
293
|
+
const newOffsetY = offsetY - (dy || 0);
|
|
294
|
+
const maxOffsetX = (imageRect.width * newZoom - slideRect.width) / 2 / newZoom;
|
|
295
|
+
const maxOffsetY = (imageRect.height * newZoom - slideRect.height) / 2 / newZoom;
|
|
296
|
+
setOffsetX(Math.min(Math.abs(newOffsetX), Math.max(maxOffsetX, 0)) * Math.sign(newOffsetX));
|
|
297
|
+
setOffsetY(Math.min(Math.abs(newOffsetY), Math.max(maxOffsetY, 0)) * Math.sign(newOffsetY));
|
|
298
|
+
}, [zoom, offsetX, offsetY, slideRect, imageRect.width, imageRect.height]);
|
|
299
|
+
const changeZoom = React.useCallback((value, rapid, dx, dy) => {
|
|
300
|
+
const newZoom = round(Math.min(Math.max(value + 0.001 < maxZoom ? value : maxZoom, 1), maxZoom), 5);
|
|
301
|
+
if (newZoom === zoom)
|
|
302
|
+
return;
|
|
303
|
+
if (!rapid) {
|
|
304
|
+
animate();
|
|
305
|
+
}
|
|
306
|
+
changeOffsets(dx ? dx * (1 / zoom - 1 / newZoom) : 0, dy ? dy * (1 / zoom - 1 / newZoom) : 0, newZoom);
|
|
307
|
+
setZoom(newZoom);
|
|
308
|
+
}, [zoom, maxZoom, changeOffsets, animate]);
|
|
309
|
+
const handleControllerRectChange = useEventCallback(() => {
|
|
310
|
+
if (zoom > 1) {
|
|
311
|
+
if (zoom > maxZoom) {
|
|
312
|
+
changeZoom(maxZoom, true);
|
|
313
|
+
}
|
|
314
|
+
changeOffsets();
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
useLayoutEffect(handleControllerRectChange, [
|
|
318
|
+
containerRect.width,
|
|
319
|
+
containerRect.height,
|
|
320
|
+
handleControllerRectChange,
|
|
321
|
+
]);
|
|
322
|
+
const zoomIn = React.useCallback(() => changeZoom(zoom * zoomInMultiplier), [zoom, zoomInMultiplier, changeZoom]);
|
|
323
|
+
const zoomOut = React.useCallback(() => changeZoom(zoom / zoomInMultiplier), [zoom, zoomInMultiplier, changeZoom]);
|
|
324
|
+
return { zoom, offsetX, offsetY, disabled, changeOffsets, changeZoom, zoomIn, zoomOut };
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const ZoomControllerContext = React.createContext(null);
|
|
328
|
+
const useZoom = makeUseContext("useZoom", "ZoomControllerContext", ZoomControllerContext);
|
|
329
|
+
function ZoomContextProvider({ children }) {
|
|
330
|
+
const [zoomWrapper, setZoomWrapper] = React.useState();
|
|
331
|
+
const { slideRect } = useController();
|
|
332
|
+
const { imageRect, maxZoom } = useZoomImageRect(slideRect, zoomWrapper === null || zoomWrapper === void 0 ? void 0 : zoomWrapper.imageDimensions);
|
|
333
|
+
const { zoom, offsetX, offsetY, disabled, changeZoom, changeOffsets, zoomIn, zoomOut } = useZoomState(imageRect, maxZoom, zoomWrapper === null || zoomWrapper === void 0 ? void 0 : zoomWrapper.zoomWrapperRef);
|
|
334
|
+
useZoomCallback(zoom, disabled);
|
|
335
|
+
useZoomSensors(zoom, maxZoom, disabled, changeZoom, changeOffsets, zoomWrapper === null || zoomWrapper === void 0 ? void 0 : zoomWrapper.zoomWrapperRef);
|
|
336
|
+
const zoomRef = React.useMemo(() => ({ zoom, maxZoom, offsetX, offsetY, disabled, zoomIn, zoomOut }), [zoom, maxZoom, offsetX, offsetY, disabled, zoomIn, zoomOut]);
|
|
337
|
+
React.useImperativeHandle(useZoomProps().ref, () => zoomRef, [zoomRef]);
|
|
338
|
+
const context = React.useMemo(() => ({ ...zoomRef, setZoomWrapper }), [zoomRef, setZoomWrapper]);
|
|
339
|
+
return React.createElement(ZoomControllerContext.Provider, { value: context }, children);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const ZoomInIcon = createIcon("ZoomIn", React.createElement(React.Fragment, null,
|
|
343
|
+
React.createElement("path", { d: "M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" }),
|
|
344
|
+
React.createElement("path", { d: "M12 10h-2v2H9v-2H7V9h2V7h1v2h2v1z" })));
|
|
345
|
+
const ZoomOutIcon = createIcon("ZoomOut", React.createElement("path", { d: "M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zM7 9h5v1H7z" }));
|
|
346
|
+
const ZoomButton = React.forwardRef(function ZoomButton({ zoomIn, onLoseFocus }, ref) {
|
|
347
|
+
const wasEnabled = React.useRef(false);
|
|
348
|
+
const wasFocused = React.useRef(false);
|
|
349
|
+
const { zoom, maxZoom, zoomIn: zoomInCallback, zoomOut: zoomOutCallback, disabled: zoomDisabled } = useZoom();
|
|
350
|
+
const { render } = useLightboxProps();
|
|
351
|
+
const disabled = zoomDisabled || (zoomIn ? zoom >= maxZoom : zoom <= 1);
|
|
352
|
+
React.useEffect(() => {
|
|
353
|
+
if (disabled && wasEnabled.current && wasFocused.current) {
|
|
354
|
+
onLoseFocus();
|
|
355
|
+
}
|
|
356
|
+
if (!disabled) {
|
|
357
|
+
wasEnabled.current = true;
|
|
358
|
+
}
|
|
359
|
+
}, [disabled, onLoseFocus]);
|
|
360
|
+
return (React.createElement(IconButton, { ref: ref, disabled: disabled, label: zoomIn ? "Zoom in" : "Zoom out", icon: zoomIn ? ZoomInIcon : ZoomOutIcon, renderIcon: zoomIn ? render.iconZoomIn : render.iconZoomOut, onClick: zoomIn ? zoomInCallback : zoomOutCallback, onFocus: () => {
|
|
361
|
+
wasFocused.current = true;
|
|
362
|
+
}, onBlur: () => {
|
|
363
|
+
wasFocused.current = false;
|
|
364
|
+
} }));
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
function ZoomButtonsGroup() {
|
|
368
|
+
const zoomInRef = React.useRef(null);
|
|
369
|
+
const zoomOutRef = React.useRef(null);
|
|
370
|
+
const { focus } = useController();
|
|
371
|
+
const focusSibling = React.useCallback((sibling) => {
|
|
372
|
+
var _a, _b;
|
|
373
|
+
if (!((_a = sibling.current) === null || _a === void 0 ? void 0 : _a.disabled)) {
|
|
374
|
+
(_b = sibling.current) === null || _b === void 0 ? void 0 : _b.focus();
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
focus();
|
|
378
|
+
}
|
|
379
|
+
}, [focus]);
|
|
380
|
+
const focusZoomIn = React.useCallback(() => focusSibling(zoomInRef), [focusSibling]);
|
|
381
|
+
const focusZoomOut = React.useCallback(() => focusSibling(zoomOutRef), [focusSibling]);
|
|
382
|
+
return (React.createElement(React.Fragment, null,
|
|
383
|
+
React.createElement(ZoomButton, { zoomIn: true, ref: zoomInRef, onLoseFocus: focusZoomOut }),
|
|
384
|
+
React.createElement(ZoomButton, { ref: zoomOutRef, onLoseFocus: focusZoomIn })));
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function ZoomToolbarControl() {
|
|
388
|
+
const { render } = useLightboxProps();
|
|
389
|
+
const zoomRef = useZoom();
|
|
390
|
+
if (render.buttonZoom) {
|
|
391
|
+
return React.createElement(React.Fragment, null, render.buttonZoom(zoomRef));
|
|
392
|
+
}
|
|
393
|
+
return React.createElement(ZoomButtonsGroup, null);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
function isResponsiveImageSlide(slide) {
|
|
397
|
+
var _a;
|
|
398
|
+
return (((_a = slide.srcSet) === null || _a === void 0 ? void 0 : _a.length) || 0) > 0;
|
|
399
|
+
}
|
|
400
|
+
function reducer({ current, preload }, { type, source }) {
|
|
401
|
+
switch (type) {
|
|
402
|
+
case "fetch":
|
|
403
|
+
if (!current) {
|
|
404
|
+
return { current: source };
|
|
405
|
+
}
|
|
406
|
+
return { current, preload: source };
|
|
407
|
+
case "done":
|
|
408
|
+
if (source === preload) {
|
|
409
|
+
return { current: source };
|
|
410
|
+
}
|
|
411
|
+
return { current, preload };
|
|
412
|
+
default:
|
|
413
|
+
throw new Error(UNKNOWN_ACTION_TYPE);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
function ResponsiveImage(props) {
|
|
417
|
+
var _a, _b;
|
|
418
|
+
const [{ current, preload }, dispatch] = React.useReducer(reducer, {});
|
|
419
|
+
const { slide: image, rect, imageFit, render } = props;
|
|
420
|
+
const srcSet = image.srcSet.sort((a, b) => a.width - b.width);
|
|
421
|
+
const width = (_a = image.width) !== null && _a !== void 0 ? _a : srcSet[srcSet.length - 1].width;
|
|
422
|
+
const height = (_b = image.height) !== null && _b !== void 0 ? _b : srcSet[srcSet.length - 1].height;
|
|
423
|
+
const cover = isImageFitCover(image, imageFit);
|
|
424
|
+
const maxWidth = Math.max(...srcSet.map((x) => x.width));
|
|
425
|
+
const targetWidth = Math.min((cover ? Math.max : Math.min)(rect.width, width * (rect.height / height)), maxWidth);
|
|
426
|
+
const pixelDensity = devicePixelRatio();
|
|
427
|
+
const handleResize = useEventCallback(() => {
|
|
428
|
+
var _a;
|
|
429
|
+
const targetSource = (_a = srcSet.find((x) => x.width >= targetWidth * pixelDensity)) !== null && _a !== void 0 ? _a : srcSet[srcSet.length - 1];
|
|
430
|
+
if (!current || srcSet.findIndex((x) => x.src === current) < srcSet.findIndex((x) => x === targetSource)) {
|
|
431
|
+
dispatch({ type: "fetch", source: targetSource.src });
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
useLayoutEffect(handleResize, [rect.width, rect.height, pixelDensity, handleResize]);
|
|
435
|
+
const handlePreload = useEventCallback((currentPreload) => dispatch({ type: "done", source: currentPreload }));
|
|
436
|
+
const style = {
|
|
437
|
+
WebkitTransform: "translateZ(0)",
|
|
438
|
+
};
|
|
439
|
+
if (!cover) {
|
|
440
|
+
Object.assign(style, rect.width / rect.height < width / height
|
|
441
|
+
? { width: "100%", height: "auto" }
|
|
442
|
+
: { width: "auto", height: "100%" });
|
|
443
|
+
}
|
|
444
|
+
return (React.createElement(React.Fragment, null,
|
|
445
|
+
preload && preload !== current && (React.createElement(ImageSlide, { key: "preload", ...props, slide: { ...image, src: preload, srcSet: undefined }, style: { position: "absolute", visibility: "hidden", ...style }, onLoad: () => handlePreload(preload), render: {
|
|
446
|
+
...render,
|
|
447
|
+
iconLoading: () => null,
|
|
448
|
+
iconError: () => null,
|
|
449
|
+
} })),
|
|
450
|
+
current && (React.createElement(ImageSlide, { key: "current", ...props, slide: { ...image, src: current, srcSet: undefined }, style: style }))));
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
function ZoomWrapper({ render, slide, offset, rect }) {
|
|
454
|
+
var _a;
|
|
455
|
+
const [imageDimensions, setImageDimensions] = React.useState();
|
|
456
|
+
const zoomWrapperRef = React.useRef(null);
|
|
457
|
+
const { zoom, maxZoom, offsetX, offsetY, setZoomWrapper } = useZoom();
|
|
458
|
+
const { carousel, on } = useLightboxProps();
|
|
459
|
+
const { currentIndex } = useLightboxState();
|
|
460
|
+
useLayoutEffect(() => {
|
|
461
|
+
if (offset === 0) {
|
|
462
|
+
setZoomWrapper({ zoomWrapperRef, imageDimensions });
|
|
463
|
+
return () => setZoomWrapper(undefined);
|
|
464
|
+
}
|
|
465
|
+
return () => { };
|
|
466
|
+
}, [offset, imageDimensions, setZoomWrapper]);
|
|
467
|
+
let rendered = (_a = render.slide) === null || _a === void 0 ? void 0 : _a.call(render, { slide, offset, rect, zoom, maxZoom });
|
|
468
|
+
if (!rendered && isImageSlide(slide)) {
|
|
469
|
+
const slideProps = {
|
|
470
|
+
slide,
|
|
471
|
+
offset,
|
|
472
|
+
rect,
|
|
473
|
+
render,
|
|
474
|
+
imageFit: carousel.imageFit,
|
|
475
|
+
onClick: offset === 0 ? () => { var _a; return (_a = on.click) === null || _a === void 0 ? void 0 : _a.call(on, { index: currentIndex }); } : undefined,
|
|
476
|
+
};
|
|
477
|
+
rendered = isResponsiveImageSlide(slide) ? (React.createElement(ResponsiveImage, { key: slide.src, ...slideProps, slide: slide, rect: offset === 0 ? { width: rect.width * zoom, height: rect.height * zoom } : rect })) : (React.createElement(ImageSlide, { key: slide.src, onLoad: (img) => setImageDimensions({ width: img.naturalWidth, height: img.naturalHeight }), ...slideProps }));
|
|
478
|
+
}
|
|
479
|
+
if (!rendered)
|
|
480
|
+
return null;
|
|
481
|
+
return (React.createElement("div", { ref: zoomWrapperRef, className: clsx(cssClass(CLASS_FULLSIZE), cssClass(CLASS_FLEX_CENTER)), style: offset === 0
|
|
482
|
+
? { transform: `scale(${zoom}) translateX(${offsetX}px) translateY(${offsetY}px)` }
|
|
483
|
+
: undefined }, rendered));
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
const Zoom = ({ augment, addModule }) => {
|
|
487
|
+
augment(({ toolbar, render, zoom, ...restProps }) => ({
|
|
488
|
+
zoom: resolveZoomProps(zoom),
|
|
489
|
+
toolbar: addToolbarButton(toolbar, PLUGIN_ZOOM, React.createElement(ZoomToolbarControl, null)),
|
|
490
|
+
render: {
|
|
491
|
+
...render,
|
|
492
|
+
slide: (props) => { var _a; return isImageSlide(props.slide) ? React.createElement(ZoomWrapper, { render: render, ...props }) : (_a = render.slide) === null || _a === void 0 ? void 0 : _a.call(render, props); },
|
|
493
|
+
},
|
|
494
|
+
...restProps,
|
|
495
|
+
}));
|
|
496
|
+
addModule(createModule(PLUGIN_ZOOM, ZoomContextProvider));
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
export { Zoom as default };
|