lightbox.js-react
Version:
React lightbox with animation and customization options
1 lines • 269 kB
Source Map (JSON)
{"version":3,"sources":["../lib/components/SlideshowLightbox/SlideshowLightbox.tsx","esbuild-css-modules-plugin-namespace:C:\\Users\\silvi\\AppData\\Local\\Temp\\tmp-2608-69ndXCHOiqoQ\\lightbox.js-react\\lib\\components\\SlideshowLightbox\\SlideshowLightbox.module.css.js","../lib/components/SlideshowLightbox/LightboxImage.jsx","esbuild-css-modules-plugin-namespace:C:\\Users\\silvi\\AppData\\Local\\Temp\\tmp-2608-galJLswSGYFe\\lightbox.js-react\\lib\\components\\SlideshowLightbox\\SlideshowLightbox.module.css.js","../lib/components/SlideshowLightbox/utility.js"],"sourcesContent":["import * as React from 'react'\r\nimport { useState, useEffect, useRef, useCallback, forwardRef, useImperativeHandle } from 'react'\r\nimport { motion, AnimatePresence, AnimateSharedLayout, useIsPresent, MotionGlobalConfig, } from 'framer-motion'\r\nimport styles from './SlideshowLightbox.module.css'\r\nimport {LightboxImage} from \"./LightboxImage.jsx\"\r\nimport type { ForwardRefExoticComponent } from 'react'; \r\n\r\nimport {\r\n wrapNums,\r\n getVideoHeight,\r\n getVideoWidth,\r\n shouldAutoplay,\r\n getScale,\r\n closeFullScreen,\r\n createCustomThumbnailBorder,\r\n areObjectsEqual\r\n} from './utility'\r\nimport {\r\n ZoomIn,\r\n ZoomOut,\r\n Fullscreen,\r\n PlayCircleFill,\r\n Search,\r\n Download,\r\n ArrowClockwise,\r\n PauseCircleFill,\r\n FullscreenExit,\r\n InfoCircle,\r\n XLg,\r\n GridFill\r\n} from 'react-bootstrap-icons'\r\nimport { ReactNode } from 'react';\r\nimport Magnifier from '@oemuap/react-magnifier'\r\nimport { Portal } from 'react-portal'\r\nimport { TransformWrapper, TransformComponent, ReactZoomPanPinchRef, } from 'react-zoom-pan-pinch'\r\n// import { saveAs } from 'file-saver-es'\r\nimport Div100vh from 'react-div-100vh'\r\nimport KeyHandler from '@banzai-inc/react-key-handler'\r\nimport { useInterval } from 'usehooks-ts'\r\nimport useEmblaCarousel from 'embla-carousel-react'\r\nimport YouTube from 'react-youtube';\r\nimport useResizeObserver from '@react-hook/resize-observer';\r\n//import exifr from 'exifr'\r\nimport JsFileDownloader from 'js-file-downloader';\r\nimport { use100vh } from 'react-div-100vh';\r\n\r\nlet thumbnailVariants: any = {\r\n visible: { opacity: 1, y: 0 },\r\n hidden: { opacity: 0, y: 100 }\r\n}\r\n\r\nconst themes: any = {\r\n day: {\r\n background: 'white',\r\n iconColor: 'black',\r\n thumbnailBorder: 'solid transparent 2px',\r\n textColor: 'black',\r\n metadataTextColor: \"black\"\r\n },\r\n night: {\r\n background: '#151515',\r\n iconColor: '#626b77',\r\n thumbnailBorder: 'solid rgb(107, 133, 206) 2px',\r\n textColor: 'silver',\r\n metadataTextColor: \"white\"\r\n\r\n },\r\n lightbox: {\r\n background: 'rgba(12, 12, 12, 0.93)',\r\n iconColor: '#626b77',\r\n thumbnailBorder: 'solid rgb(107, 133, 206) 2px',\r\n textColor: 'silver',\r\n metadataTextColor: \"white\"\r\n\r\n }\r\n}\r\n\r\n// const activeThumbnailBorder = 'solid rgba(107, 133, 206, 0.6) 2px'\r\nconst inactiveThumbnailBorder = 'solid transparent 2px'\r\n\r\nconst defaultTheme = 'night'\r\nconst mobileWidth = 768\r\nconst tabletWidth = 1100\r\n\r\nconst usePrevious = (value) => {\r\n // custom hook to get previous prop value\r\n const ref = useRef();\r\n\r\n useEffect(() => {\r\n ref.current = value;\r\n });\r\n\r\n return ref.current;\r\n}\r\n\r\ninterface SlideItem {\r\n src?: any,\r\n original?: string,\r\n type?: string,\r\n alt?: string,\r\n loaded?: boolean,\r\n thumbnailSrc?: string,\r\n}\r\n\r\ninterface ImageElement {\r\n src?: any,\r\n alt?: string,\r\n loaded?: boolean,\r\n}\r\n\r\ntype SlideshowLightboxHandle = {\r\n children?: ReactNode;\r\n reset: () => void;\r\n};\r\n\r\nexport interface SlideshowLightboxProps {\r\n children?: ReactNode;\r\n ref?: any;\r\n thumbnailBorder?: string;\r\n magnifyingGlass?: boolean;\r\n backgroundColor?: string;\r\n theme?: string;\r\n iconColor?: any;\r\n fullScreen?: boolean;\r\n showControls?: boolean;\r\n disableImageZoom?: boolean;\r\n slideshowInterval?: number;\r\n slideDuration?: number;\r\n lightboxHeight?: string;\r\n lightboxWidth?: string;\r\n showThumbnails?: boolean;\r\n open?: boolean;\r\n displayMetadata?: boolean;\r\n noWindow?: boolean;\r\n navigationDots?: boolean;\r\n animateThumbnails?: boolean;\r\n queryElems?: any;\r\n controlsPlacement?: string;\r\n showFullScreenIcon?: boolean;\r\n showThumbnailIcon?: boolean;\r\n showSlideshowIcon?: boolean;\r\n showMagnificationIcons?: boolean;\r\n roundedImages?: boolean;\r\n downloadImages?: boolean;\r\n singleClickZoom?: boolean;\r\n showNavigationDots?: boolean;\r\n rtl?: boolean;\r\n modalClose?: string;\r\n framework?: string;\r\n lightboxIdentifier?: string;\r\n nextArrow?: any;\r\n prevArrow?: any;\r\n arrowStyle?: any;\r\n showLoader?: boolean;\r\n useCoverMode?: boolean;\r\n disableAnim?: any;\r\n rightArrowStyle?: any;\r\n leftArrowStyle?: any;\r\n imgAnimation?: string;\r\n maxZoomScale?: number;\r\n textColor?: string;\r\n licenseKey?: string;\r\n images?: any;\r\n render?: any;\r\n imageComponent?: boolean;\r\n imgElemClassname?: string;\r\n showArrows?: boolean;\r\n showControlsBar?: boolean;\r\n toggleThumbnailDisplay?: boolean;\r\n rightSidebarComponent?: any;\r\n lightboxFooterComponent?: any;\r\n closeIconBtnStyle?: any;\r\n controlComponent?: any;\r\n zoomInComponent?: any;\r\n zoomOutComponent?: any;\r\n closeComponent?: any;\r\n lightboxImgClass?: string;\r\n iconStyle?: any;\r\n zoomCursor?: boolean;\r\n thumbnailImgAnim?: boolean;\r\n thumbnailImgClass?: string;\r\n coverImageInLightbox?: boolean;\r\n captionPlacement?: string;\r\n onOpen?: any;\r\n onClose?: any;\r\n onNext?: any;\r\n onPrev?: any;\r\n onSelect?: any;\r\n onRotate?: any;\r\n onThumbnailClick?: any;\r\n onImgError?: any;\r\n className?: string;\r\n imgWrapperClassName?: string;\r\n fullScreenFillMode?: string;\r\n imgClassName?: string;\r\n startingSlideIndex?: number;\r\n rotateIcon?: boolean;\r\n showAllImages?: any;\r\n rightArrowClassname?: string;\r\n leftArrowClassname?: string;\r\n displayedImages?: any;\r\n metadataTimeLocale?: string;\r\n captionStyle?: any;\r\n}\r\n\r\nexport const SlideshowLightbox: React.FC<SlideshowLightboxProps> = React.forwardRef<SlideshowLightboxHandle, SlideshowLightboxProps>((props, ref) => {\r\n\r\n useImperativeHandle(\r\n ref,\r\n () => ({\r\n reset() {\r\n initImages(true, true)\r\n }\r\n })\r\n )\r\n\r\n const [[imgSlideIndex, direction], setImgSlideIndex] = useState([0, 0])\r\n const [showModal, setShowModal] = useState(false)\r\n const [slideAnimDuration, setSlideAnimDuration] = useState(props.slideDuration ? props.slideDuration : 25)\r\n const [toggleThumbnails, setToggleThumbnails] = useState(props.toggleThumbnailDisplay ? props.toggleThumbnailDisplay : false)\r\n const [controlsPlacement, setControlsPlacement] = useState(props.controlsPlacement ? props.controlsPlacement : \"default\")\r\n\r\n const [isSlideshowPlaying, setIsSlideshowPlaying] = useState(false)\r\n const [customIconStyle, setCustomIconStyle] = useState(props.iconStyle ? props.iconStyle : null)\r\n\r\n const [emblaReinitialized, setEmblaReinitialized] = useState(false)\r\n\r\n const [images, setImages] = useState<SlideItem[]>([]);\r\n\r\n const [previewImageElems, setPreviewImageElems] = useState<any[]>([]);\r\n\r\n const slideIndex = wrapNums(0, images.length, imgSlideIndex)\r\n\r\n const [reactSwipeOptions, setReactSwipeOptions] = useState({\r\n loop: true,\r\n startIndex: 0,\r\n active: true,\r\n duration: slideAnimDuration,\r\n dragThreshold: 10,\r\n skipSnaps: true\r\n })\r\n\r\n let initialThumbnailOptions: any = {\r\n startIndex: 0,\r\n containScroll: 'keepSnaps',\r\n dragFree: true\r\n }\r\n\r\n const [width, setWidth] = useState(0);\r\n\r\n\r\n const isMobile = width <= mobileWidth;\r\n const isTablet = width <= tabletWidth;\r\n\r\n const [thumbnailSwipeOptions, setThumbnailSwipeOptions] = useState(initialThumbnailOptions)\r\n\r\n const [carouselReady, setCarouselReady] = useState(false)\r\n const [isTabletUserAgent, setIsTabletUserAgent] = useState(false);\r\n\r\n const [zoomedIn, setZoomedIn] = useState(false)\r\n\r\n const [isDisplay, setIsDisplay] = useState(false)\r\n\r\n const [fullImg, setFullImg] = useState(false)\r\n\r\n const [isOpen, setIsOpen] = useState(false)\r\n\r\n const [prevFocusedElem, setPrevFocusedElem] = useState<HTMLElement | null>(null)\r\n const [animationEntered, setAnimationEntered] = useState(false)\r\n\r\n const [lightboxModalWidth, setLightboxModalWidth] = useState(\r\n props.lightboxWidth ? props.lightboxWidth : \"100vw\"\r\n )\r\n\r\n const [lightboxModalHeight, setLightboxModalHeight] = useState(\r\n props.lightboxHeight ? props.lightboxHeight : \"100vh\"\r\n )\r\n\r\n const [magnifyingGlassFeature, _setMagnifyingGlassFeature] = useState(\r\n props.magnifyingGlass ? props.magnifyingGlass : false\r\n )\r\n\r\n const [disableZoom, setDisableZoom] = useState(\r\n props.disableImageZoom ? props.disableImageZoom : false\r\n )\r\n\r\n const [slideshowInterval, setSlideshowInterval] = useState(\r\n props.slideshowInterval ? props.slideshowInterval : 1700\r\n )\r\n\r\n const [rightArrowStyle, setRightArrowStyle] = useState(\r\n props.rightArrowStyle ? props.rightArrowStyle : {}\r\n )\r\n\r\n const [leftArrowStyle, setLeftArrowStyle] = useState(\r\n props.leftArrowStyle ? props.leftArrowStyle : {}\r\n )\r\n\r\n const [maxScale, setMaxScale] = useState<number>(\r\n props.maxZoomScale ? getScale(props.maxZoomScale, 24) : 8\r\n )\r\n\r\n const [isRounded, setIsRounded] = useState(\r\n props.roundedImages ? props.roundedImages : false\r\n )\r\n\r\n const [showControls, setShowControls] = useState<boolean>(\r\n props.showControls ? props.showControls : true\r\n )\r\n\r\n const [displayFullScreenIcon, setDisplayFullScreenIcon] = useState<boolean>(\r\n props.showFullScreenIcon ? props.showFullScreenIcon : true\r\n )\r\n\r\n const [displayThumbnailIcon, setDisplayThumbnailIcon] = useState<boolean>(\r\n props.showThumbnailIcon ? props.showThumbnailIcon : true\r\n )\r\n\r\n const [displaySlideshowIcon, setDisplaySlideshowIcon] = useState<boolean>(\r\n props.showSlideshowIcon ? props.showSlideshowIcon : true\r\n )\r\n\r\n const [rotateImgIcon, setRotateImgIcon] = useState<boolean>(\r\n props.rotateIcon ? props.rotateIcon : false\r\n )\r\n\r\n const [displayMagnificationIcons, setDisplayMagnificationIcons] = useState<boolean>(\r\n props.showMagnificationIcons ? props.showMagnificationIcons : true\r\n )\r\n\r\n const [nextArrowElem, setNextArrowElem] = useState(\r\n props.nextArrow ? props.nextArrow : null\r\n )\r\n\r\n const [isImageComponent, setImageComponent] = useState(\r\n props.imageComponent ? props.imageComponent : null\r\n )\r\n\r\n const [prevArrowElem, setPrevArrowElem] = useState(\r\n props.prevArrow ? props.prevArrow : null\r\n )\r\n\r\n const [modalCloseOption, setModalCloseOption] = useState(\r\n props.modalClose ? props.modalClose : \"default\"\r\n )\r\n\r\n const [showDownloadBtn, setShowDownloadBtn] = useState(\r\n props.downloadImages ? props.downloadImages : false\r\n )\r\n\r\n const [navigationDots, setNavigationDots] = useState(\r\n props.showNavigationDots ? props.showNavigationDots : false\r\n )\r\n\r\n const [metadataLocale, setMetadataLocale] = useState(props.metadataTimeLocale ? props.metadataTimeLocale : \"en-US\")\r\n\r\n const [isRTL, setIsRTL] = useState(props.rtl ? props.rtl : false)\r\n\r\n const [frameworkID, setFrameworkID] = useState(\r\n props.framework ? props.framework : ''\r\n )\r\n const [lightboxIdentifier, setLightboxIdentifier] = useState(\r\n props.lightboxIdentifier ? props.lightboxIdentifier : false\r\n )\r\n const [imageFullScreen, setImageFullScreen] = useState(\r\n props.fullScreen ? props.fullScreen : false\r\n )\r\n const [licenseKey, setLicenseKey] = useState(\r\n props.licenseKey ? props.licenseKey : ''\r\n )\r\n\r\n const [displayLoader, setDisplayLoader] = useState(\r\n props.showLoader ? props.showLoader : false\r\n )\r\n\r\n const [pinch, setPinch] = useState(false);\r\n const [currentZoomScale, setCurrentZoomScale] = useState(1)\r\n\r\n const [startingIndex, setStartingIndex] = useState(\r\n props.startingSlideIndex ? props.startingSlideIndex : 0\r\n )\r\n\r\n const [showZoomCursor, setShowZoomCursor] = useState(\r\n props.zoomCursor ? props.zoomCursor : false\r\n )\r\n\r\n const [zoomCursor, setZoomCursor] = useState(\"zoom-in\")\r\n\r\n const [singleClickZoom, setSingleClickZoom] = useState(\r\n props.singleClickZoom ? props.singleClickZoom : false\r\n )\r\n\r\n // Styling/theming\r\n const [backgroundColor, setBackgroundColor] = useState(\r\n props.backgroundColor\r\n ? props.backgroundColor\r\n : themes[defaultTheme].background\r\n )\r\n const [iconColor, setIconColor] = useState(\r\n props.iconColor ? props.iconColor : null\r\n )\r\n const [textColor, setTextColor] = useState(\r\n props.textColor ? props.textColor : themes[defaultTheme].textColor\r\n )\r\n const [showControlsBar, setShowControlsBar] = useState(\r\n props.showControlsBar ? props.showControlsBar : true\r\n )\r\n\r\n const [imgCaptionPlacement, setImgCaptionPlacement] = useState(\r\n props.captionPlacement ? props.captionPlacement : \"below\"\r\n )\r\n\r\n const [coverMode, setCoverMode] = useState(\r\n props.useCoverMode ? props.useCoverMode : false\r\n )\r\n\r\n const [displayImgMetadata, setDisplayImgMetadata] = useState(\r\n props.displayMetadata ? props.displayMetadata : false\r\n )\r\n\r\n const [showImgMetadataPanel, setShowImgMetadataPanel] = useState(false)\r\n\r\n const [imgMetadata, setImgMetadata] = useState({})\r\n\r\n const [showThumbnails, setShowThumbnails] = useState(\r\n props.showThumbnails ? props.showThumbnails : false\r\n )\r\n const [animatedThumbnails, setAnimatedThumbnails] = useState(\r\n props.animateThumbnails ? props.animateThumbnails : true\r\n )\r\n const [imgAnimation, setImgAnimation] = useState(\r\n props.imgAnimation ? props.imgAnimation : 'imgDrag'\r\n )\r\n const [arrowStyle, setArrowStyle] = useState(\r\n props.arrowStyle ? props.arrowStyle : 'dark'\r\n )\r\n\r\n const div100vhHeight = use100vh();\r\n const lboxHeight = lightboxModalHeight == \"100vh\" ? div100vhHeight : lightboxModalHeight;\r\n\r\n const [YTVideoCurrentlyPlaying, setYTVideoCurrentlyPlaying] = useState(false)\r\n\r\n const [reachedMaxScale, setReachedMaxScale] = useState(false)\r\n const [isBrowserFullScreen, setIsBrowserFullScreen] = useState(false)\r\n const [enableMagnifyingGlass, setMagnifyingGlass] = useState(false)\r\n const [imagesLoaded, setImagesLoaded] = useState(false)\r\n\r\n const imageRef: React.RefObject<HTMLImageElement> = useRef(null)\r\n\r\n const [zoomIdx, setZoomIdx] = useState(0)\r\n\r\n const [imgContainHeight, setImgContainHeight] = useState(500)\r\n const [imgContainWidth, setImgContainWidth] = useState(426)\r\n const [isInit, setIsInit] = useState(false)\r\n const [currentRotation, setCurrentRotation] = useState(0)\r\n\r\n const { open } = props;\r\n const previousValues: any = usePrevious({ open });\r\n\r\n // Refs\r\n const zoomReferences = useRef<(ReactZoomPanPinchRef | null)[]>([])\r\n const videoReferences = useRef({})\r\n const imageRefs = useRef([])\r\n\r\n const btnRef = useRef(null)\r\n const [videoElements, setVideoElements] = useState({});\r\n\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [noWindow, setNoWindow] = useState(props.noWindow ? props.noWindow : false)\r\n\r\n const [touchStart, setTouchStart] = useState<any>(0)\r\n const [touchEnd, setTouchEnd] = useState<any>(0)\r\n\r\n const [mouseStartX, setMouseStartX] = useState<any>(0)\r\n const [mouseStartY, setMouseStartY] = useState<any>(0)\r\n\r\n const minimumSwipeDistance = 50\r\n\r\n const zoomImage = () => {\r\n if (imgAnimation == \"fade\") {\r\n if (currentZoomScale <= 1 && !reachedMaxScale) {\r\n zoomIntoImage()\r\n }\r\n else {\r\n zoomOutImage()\r\n }\r\n }\r\n else {\r\n if (currentZoomScale >= 1 && currentZoomScale < maxScale && !reachedMaxScale) {\r\n zoomIntoImage()\r\n }\r\n else {\r\n zoomOutImage()\r\n }\r\n }\r\n \r\n if (currentZoomScale == maxScale) {\r\n setReachedMaxScale(true)\r\n }\r\n else if (currentZoomScale == 1.08 && reachedMaxScale) {\r\n setReachedMaxScale(false)\r\n }\r\n\r\n\r\n }\r\n\r\n const zoomOutImage = () => {\r\n if (zoomReferences.current[zoomIdx] != null) {\r\n zoomReferences.current[zoomIdx]!.zoomOut()\r\n } \r\n setZoomedIn(false)\r\n }\r\n\r\n const zoomIntoImage = () => {\r\n if (zoomReferences.current[zoomIdx] != null) {\r\n zoomReferences.current[zoomIdx]!.zoomIn()\r\n }\r\n setZoomedIn(true)\r\n }\r\n\r\n const onTouchStart = (e) => {\r\n\r\n if (e.targetTouches && e.targetTouches.length == 1) {\r\n setTouchEnd(null)\r\n setTouchStart(e.targetTouches[0].clientX)\r\n }\r\n\r\n if (e.targetTouches && e.targetTouches.length == 2) {\r\n setPinch(true)\r\n }\r\n }\r\n\r\n const onTouchMove = (e) => setTouchEnd(e.targetTouches[0].clientX)\r\n\r\n const onTouchEnd = (e) => {\r\n // only move to new image if imgAnimation set to \"fade\"\r\n if (touchStart != null && touchEnd != null && imgAnimation == \"fade\" && zoomedIn == false && pinch == false\r\n ) {\r\n const distance: any = touchStart - touchEnd\r\n if (distance != null) {\r\n const isLeftSwipe = distance > minimumSwipeDistance\r\n const isRightSwipe = distance < -minimumSwipeDistance\r\n if (isLeftSwipe) {\r\n nextSlide()\r\n }\r\n else if (isRightSwipe) {\r\n prevSlide();\r\n }\r\n }\r\n\r\n }\r\n else if (touchStart != null && touchEnd != null && zoomedIn == false && pinch == false\r\n ) {\r\n // click \r\n if (toggleThumbnails) {\r\n setShowThumbnails(!showThumbnails)\r\n }\r\n }\r\n setPinch(false)\r\n setTouchStart(null)\r\n\r\n }\r\n\r\n const delta = 6;\r\n\r\n const onMouseDown = (event) => {\r\n setMouseStartX(event.pageX)\r\n setMouseStartY(event.pageY)\r\n }\r\n\r\n const onMouseUp = (event) => {\r\n const differenceX = Math.abs(event.pageX - mouseStartX);\r\n const isLeftDragMotion = (mouseStartX - event.pageX) > delta;\r\n const isRightDragMotion = (mouseStartX - event.pageX) < -delta;\r\n\r\n if (differenceX > delta) {\r\n\r\n if (isLeftDragMotion && imgAnimation == \"fade\" && zoomedIn == false) {\r\n nextSlide();\r\n }\r\n else if (isRightDragMotion && imgAnimation == \"fade\" && zoomedIn == false) {\r\n prevSlide()\r\n }\r\n\r\n }\r\n else {\r\n // click\r\n if (toggleThumbnails) {\r\n setShowThumbnails(!showThumbnails);\r\n }\r\n\r\n // if (singleClickZoom) {\r\n // event.stopPropagation()\r\n // zoomIntoImage()\r\n // }\r\n\r\n }\r\n }\r\n\r\n const [thumbnailBorder, setThumbnailBorder] = useState(\r\n props.thumbnailBorder\r\n ? createCustomThumbnailBorder(props.thumbnailBorder)\r\n : themes[defaultTheme].thumbnailBorder\r\n )\r\n\r\n const [emblaRef, emblaApi] = useEmblaCarousel(reactSwipeOptions);\r\n const [emblaThumbsRef, emblaThumbsApi] = useEmblaCarousel(thumbnailSwipeOptions)\r\n\r\n const scrollPrev = useCallback(() => {\r\n if (emblaApi) {\r\n emblaApi.scrollPrev();\r\n }\r\n\r\n }, [emblaApi])\r\n\r\n const scrollNext = useCallback(() => {\r\n if (emblaApi) {\r\n emblaApi.scrollNext()\r\n\r\n }\r\n }, [emblaApi])\r\n\r\n const variants = {\r\n active: {\r\n opacity: 1,\r\n },\r\n inactive: {\r\n opacity: 0,\r\n }\r\n }\r\n\r\n const isImageCaption = (placement) => {\r\n if (placement != imgCaptionPlacement) {\r\n return false;\r\n }\r\n if (props.images && props.images.length > 0) {\r\n if (props.images[slideIndex]?.caption) {\r\n return true\r\n }\r\n }\r\n return false\r\n }\r\n\r\n const getContainerStyles = () => {\r\n if ((props.showControlsBar == false || props.fullScreen)) {\r\n return { height: lboxHeight }\r\n }\r\n else if (isBrowserFullScreen) {\r\n\r\n // return {height: \"100vh\"}\r\n }\r\n else {\r\n return {}\r\n }\r\n }\r\n\r\n const getInnerContainerStyles = () => {\r\n\r\n if (isImageCaption(\"above\")) {\r\n return styles.innerContainerWithTopCaption\r\n }\r\n if (rotateImgIcon) {\r\n return styles.rotateImgInnerContainer;\r\n }\r\n return styles.slideshowInnerContainerThumbnails\r\n\r\n }\r\n\r\n const displayDownloadBtn = () => {\r\n if (isVideo(slideIndex)) {\r\n return false\r\n } else {\r\n return showDownloadBtn\r\n }\r\n }\r\n\r\n function handleWindowResize() {\r\n if (!noWindow) {\r\n setWidth(window.innerWidth)\r\n }\r\n }\r\n\r\n const shouldDisplayMagnifyingGlassIcon = () => {\r\n if (isVideo(slideIndex)) {\r\n return false\r\n }\r\n if (isMobile == true) {\r\n return false\r\n }\r\n if (imageFullScreen == true) {\r\n return false\r\n }\r\n\r\n if (magnifyingGlassFeature == true) {\r\n return true\r\n }\r\n return false\r\n }\r\n\r\n const getImageStyle = () => {\r\n let styleObject = {};\r\n styleObject[\"objectFit\"] = \"contain\"\r\n\r\n if (imageFullScreen) {\r\n if (props.fullScreenFillMode) {\r\n styleObject[\"objectFit\"] = props.fullScreenFillMode;\r\n if (props.fullScreenFillMode == \"cover\") {\r\n styleObject[\"maxHeight\"] = \"94vh\"\r\n styleObject[\"maxWidth\"] = \"70vw\"\r\n styleObject[\"marginTop\"] = \"auto\"\r\n styleObject[\"marginBottom\"] = \"auto\"\r\n\r\n }\r\n }\r\n else {\r\n styleObject[\"objectFit\"] = \"contain\"\r\n styleObject[\"height\"] = lboxHeight;\r\n styleObject[\"maxHeight\"] = lboxHeight;\r\n }\r\n\r\n }\r\n if (!imageFullScreen && !rotateImgIcon) {\r\n if (isImageCaption(imgCaptionPlacement) && showThumbnails == false) {\r\n // styleObject[\"height\"] = \"67vh\"\r\n }\r\n if (isImageCaption(imgCaptionPlacement) && showThumbnails) {\r\n // styleObject[\"height\"] = \"67vh\"\r\n }\r\n\r\n if (props.thumbnailImgAnim && showThumbnails == false) {\r\n styleObject[\"height\"] = \"87vh\"\r\n }\r\n else if (isImageCaption(imgCaptionPlacement) != true) {\r\n // styleObject[\"height\"] = \"77vh\"\r\n\r\n }\r\n if (props.thumbnailImgAnim && showThumbnails) {\r\n styleObject[\"height\"] = \"67vh\"\r\n }\r\n }\r\n\r\n if (rotateImgIcon && showThumbnails) {\r\n styleObject[\"width\"] = \"57vw\"\r\n styleObject[\"marginTop\"] = \"10vh\"\r\n }\r\n else if (rotateImgIcon && showThumbnails == false) {\r\n styleObject[\"width\"] = \"57vw\"\r\n styleObject[\"marginTop\"] = \"15vh\"\r\n }\r\n\r\n\r\n if (isRounded) {\r\n styleObject[\"borderRadius\"] = \"20px\";\r\n }\r\n if (modalCloseOption == \"clickOutside\") {\r\n styleObject[\"pointerEvents\"] = \"auto\"\r\n }\r\n if (isImageComponent && showThumbnails == false && !isMobile) {\r\n styleObject[\"height\"] = \"85vh\";\r\n }\r\n return styleObject;\r\n }\r\n\r\n const shouldDisplaySlideshowIcon = () => {\r\n\r\n if (props.showSlideshowIcon != undefined) {\r\n return props.showSlideshowIcon;\r\n }\r\n\r\n if (images) {\r\n if (images.length == 1) {\r\n return false;\r\n }\r\n }\r\n else if (props.images) {\r\n if (props.images.length == 1) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n const navigationClick = (index) => {\r\n initLoader(index)\r\n setCurrentSlide(index)\r\n }\r\n\r\n const checkModalClick = (e) => {\r\n const modals = document.getElementsByClassName('imageModal')\r\n let arr_modals = Array.from(modals)\r\n for (let i = 0; i < arr_modals.length; i++) {\r\n let elem = arr_modals[i]\r\n let clickInside = elem.contains(e.target);\r\n\r\n if (clickInside) {\r\n return\r\n }\r\n }\r\n\r\n closeModal()\r\n }\r\n\r\n const isZoomEnabled = () => {\r\n if (disableZoom == true) {\r\n return false;\r\n }\r\n }\r\n\r\n const getRTLIndex = (img_gallery_length, i) => {\r\n let index\r\n if (i == 0) {\r\n index = img_gallery_length - 1\r\n } else if (i == img_gallery_length - 1) {\r\n index = 0\r\n } else {\r\n index = img_gallery_length - i - 1\r\n }\r\n return index\r\n }\r\n\r\n const getMetadataTextColor = () => {\r\n if (props.theme) {\r\n if (themes[props.theme]) {\r\n return themes[props.theme].metadataTextColor;\r\n }\r\n }\r\n else {\r\n return themes[defaultTheme].metadataTextColor;\r\n }\r\n }\r\n\r\n const fullScreen = () => {\r\n let lightbox = document.getElementById('slideshowAnim')\r\n openFullScreen(lightbox)\r\n // setIsBrowserFullScreen(true)\r\n initFullScreenChangeEventListeners()\r\n }\r\n\r\n const fullScreenHandler = () => {\r\n //in full screen mode\r\n if (\r\n document['webkitIsFullScreen'] ||\r\n document['mozFullScreen'] ||\r\n document['msFullscreenElement']\r\n ) {\r\n setIsBrowserFullScreen(true)\r\n setLightboxModalHeight(\"100vh\")\r\n\r\n } else {\r\n if (isBrowserFullScreen) {\r\n closeFullScreen(document)\r\n }\r\n removeFullScreenChangeEventListeners()\r\n setIsBrowserFullScreen(false)\r\n setLightboxModalHeight(props.lightboxHeight ? props.lightboxHeight : \"100vh\")\r\n\r\n }\r\n }\r\n\r\n const exitFullScreen = () => {\r\n closeFullScreen(document)\r\n removeFullScreenChangeEventListeners()\r\n // setIsBrowserFullScreen(false)\r\n }\r\n\r\n const emblaSlideSelect = useCallback((emblaApi) => {\r\n }, [])\r\n\r\n useEffect(() => {\r\n if (emblaApi) emblaApi.on('slidesInView', emblaSlideSelect)\r\n },\r\n [emblaApi, emblaSlideSelect])\r\n\r\n\r\n const updateImageSlideshow = (newDirection) => {\r\n if (isRTL) {\r\n scrollPrev()\r\n } else {\r\n scrollNext();\r\n }\r\n\r\n setImgSlideIndex([imgSlideIndex + newDirection, newDirection])\r\n if (isRTL) {\r\n setZoomIdx(zoomIdx - 1 < 0 ? images.length - 1 : zoomIdx - 1)\r\n } else {\r\n setZoomIdx(zoomIdx + 1 >= images.length ? 0 : zoomIdx + 1)\r\n }\r\n }\r\n\r\n const displayArrows = () => {\r\n if (props.showArrows == false) {\r\n return false;\r\n }\r\n if (props.images) {\r\n if (props.images.length == 1) {\r\n return false;\r\n }\r\n }\r\n else if (images.length == 1) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n const initLoader = (newIndex) => {\r\n if (props.showLoader && props.images) {\r\n if (!isVideo(newIndex) && imagesLoadedDict && imagesLoadedDict[newIndex].loaded != true) {\r\n setDisplayLoader(true)\r\n } else if (\r\n props.showLoader &&\r\n props.images && imagesLoadedDict &&\r\n imagesLoadedDict[newIndex]['loaded']\r\n ) {\r\n setDisplayLoader(false)\r\n }\r\n }\r\n }\r\n\r\n const getImageCaption = (): string => {\r\n if (props.images && props.images.length > 0) {\r\n return props.images[slideIndex].caption;\r\n }\r\n return \"\"\r\n }\r\n\r\n const getArrowStyle = (): string | void => {\r\n if (arrowStyle == 'dark') {\r\n return styles.darkIcon\r\n } else if (arrowStyle == 'light') {\r\n return styles.lightIcon\r\n }\r\n }\r\n\r\n const getIconClasses = (): string | undefined => {\r\n if (arrowStyle == 'dark') {\r\n return styles.darkHeaderIcon\r\n }\r\n else if (arrowStyle == 'light') {\r\n return styles.lightHeaderIcon\r\n }\r\n }\r\n\r\n const setCurrentSlide = (newIndex) => {\r\n let newDirection\r\n if (newIndex > imgSlideIndex) {\r\n newDirection = 1\r\n } else {\r\n newDirection = -1\r\n }\r\n\r\n setZoomIdx(newIndex)\r\n\r\n setImgSlideIndex([newIndex, newDirection])\r\n\r\n if (emblaApi) {\r\n emblaApi.scrollTo(newIndex)\r\n }\r\n }\r\n\r\n const dispatchOpenEvent = () => {\r\n if (props.onOpen) {\r\n props.onOpen(slideIndex, images[slideIndex]);\r\n }\r\n if (props.onSelect) {\r\n props.onSelect(slideIndex, images[slideIndex])\r\n }\r\n\r\n }\r\n\r\n const dispatchCloseEvent = () => {\r\n if (props.onClose) {\r\n props.onClose(slideIndex)\r\n }\r\n }\r\n\r\n const dispatchNextImgEvent = (newIndex) => {\r\n if (props.onNext) {\r\n props.onNext(newIndex, images[newIndex])\r\n }\r\n }\r\n\r\n const dispatchPrevImgEvent = (newIndex) => {\r\n if (props.onPrev) {\r\n props.onPrev(newIndex, images[newIndex])\r\n }\r\n }\r\n\r\n const closeModal = () => {\r\n //reset zoom ref\r\n setZoomIdx(0)\r\n\r\n if (isBrowserFullScreen) {\r\n exitFullScreen()\r\n }\r\n\r\n // ensure slideshow is paused\r\n if (isSlideshowPlaying) {\r\n setIsSlideshowPlaying(false)\r\n }\r\n\r\n setShowModal(false)\r\n setIsOpen(false)\r\n setCarouselReady(false)\r\n setEmblaReinitialized(false)\r\n setCurrentRotation(0);\r\n //resetRotation()\r\n if (prevFocusedElem) prevFocusedElem?.focus();\r\n }\r\n\r\n const getCursor = () => {\r\n if (showZoomCursor) {\r\n if (zoomCursor == \"zoom-in\") {\r\n return styles.zoomInCursor\r\n }\r\n else if (zoomCursor == \"zoom-out\") {\r\n return styles.zoomOutCursor\r\n }\r\n }\r\n \r\n return \"\"\r\n }\r\n\r\n const openModal = (num) => {\r\n\r\n if (emblaApi) {\r\n emblaApi.reInit();\r\n if (emblaThumbsApi) {\r\n emblaThumbsApi?.scrollTo(emblaApi.selectedScrollSnap())\r\n }\r\n }\r\n setImgSlideIndex([num, 1])\r\n setShowModal(true)\r\n setIsOpen(true)\r\n\r\n }\r\n\r\n var imagesLoadedDict;\r\n\r\n const setItemLoaded = (index) => {\r\n setDisplayLoader(false)\r\n if (props.images) {\r\n let imgs;\r\n if (imagesLoadedDict) {\r\n imgs = imagesLoadedDict\r\n }\r\n else {\r\n imgs = images;\r\n }\r\n let newImages = imgs.map((img, i) => index === i ? {\r\n ...img,\r\n loaded: true\r\n } : img)\r\n setImages(images =>\r\n newImages\r\n )\r\n imagesLoadedDict = newImages;\r\n\r\n }\r\n }\r\n\r\n const getContainerHeight = () => {\r\n\r\n if (props.lightboxHeight && isBrowserFullScreen) {\r\n return \"100vh\";\r\n }\r\n else if (props.lightboxHeight && !isBrowserFullScreen) {\r\n return props.lightboxHeight;\r\n }\r\n return \"\"\r\n }\r\n\r\n const getContainerWidth = () => {\r\n if (props.lightboxWidth && !isBrowserFullScreen) {\r\n return props.lightboxWidth\r\n }\r\n else if (props.lightboxWidth && isBrowserFullScreen) {\r\n return \"\"\r\n }\r\n return \"\"\r\n\r\n }\r\n\r\n const setImagesItemLoaded = (index) => {\r\n setImages(images =>\r\n images.map((img, i) => index === i ? {\r\n ...img,\r\n loaded: true\r\n } : img)\r\n )\r\n }\r\n\r\n const resetMedia = (slide_index) => {\r\n resetVideo(slide_index)\r\n resetImage()\r\n }\r\n\r\n const initImgMetadataPanel = () => {\r\n if (isMobile && showImgMetadataPanel) {\r\n setShowImgMetadataPanel(false)\r\n }\r\n }\r\n\r\n const initSlide = (newSlideIndex) => {\r\n setImgSlideIndex([newSlideIndex, 1])\r\n let wrap_slide_index = wrapNums(0, images.length, newSlideIndex)\r\n setZoomIdx(wrap_slide_index)\r\n initLoader(wrap_slide_index);\r\n if (imageRefs.current[wrap_slide_index]) {\r\n imageRefs.current[wrap_slide_index].classList.add(`${styles.rotate_img}`)\r\n }\r\n\r\n if (displayImgMetadata) {\r\n initImgMetadataPanel();\r\n\r\n if (!imgMetadata[wrap_slide_index]) {\r\n setIsLoading(true)\r\n }\r\n }\r\n\r\n }\r\n\r\n const nextSlide = () => {\r\n scrollNext();\r\n initSlide(imgSlideIndex + 1);\r\n if (imgAnimation == \"fade\") {\r\n // since embla carousel not used for fade animations, dispatch next event manually\r\n dispatchNextImgEvent((imgSlideIndex + 1) % images.length)\r\n }\r\n }\r\n\r\n const prevSlide = () => {\r\n scrollPrev()\r\n initSlide(imgSlideIndex - 1);\r\n if (imgAnimation == \"fade\") {\r\n // since embla carousel not used for fade animations, dispatch next event manually\r\n dispatchPrevImgEvent((imgSlideIndex - 1) % images.length)\r\n }\r\n }\r\n\r\n const setThumbnailStartIndex = (index) => {\r\n let thumbnailSwipeOptionConfig = thumbnailSwipeOptions;\r\n thumbnailSwipeOptionConfig.startIndex = index\r\n setThumbnailSwipeOptions(thumbnailSwipeOptionConfig)\r\n }\r\n\r\n const openModalWithSlideNum = (index) => {\r\n\r\n let reactSwipeOptionConfig = reactSwipeOptions\r\n reactSwipeOptionConfig.startIndex = index\r\n setReactSwipeOptions(reactSwipeOptionConfig)\r\n setThumbnailStartIndex(index)\r\n setZoomIdx(index)\r\n openModal(index)\r\n }\r\n\r\n const saveImage = () => {\r\n let img_url;\r\n if (props.images.length > 0) {\r\n if (props.images[slideIndex].original) {\r\n img_url = props.images[slideIndex].original;\r\n\r\n } else {\r\n img_url = props.images[slideIndex]['src'];\r\n }\r\n } else {\r\n if (images[slideIndex].src) {\r\n img_url = images[slideIndex].src!\r\n }\r\n }\r\n\r\n new JsFileDownloader({\r\n url: img_url,\r\n filename: \"image.jpg\"\r\n })\r\n .then(function () {\r\n // download ended\r\n })\r\n .catch(function (error) {\r\n // an error occurred\r\n });\r\n }\r\n\r\n const playSlideshow = () => {\r\n setMagnifyingGlass(false)\r\n if (isRTL) {\r\n updateImageSlideshow(-1)\r\n } else {\r\n updateImageSlideshow(1)\r\n }\r\n setIsSlideshowPlaying(true)\r\n }\r\n\r\n const stopSlideshow = () => {\r\n setIsSlideshowPlaying(false)\r\n }\r\n\r\n const getEmbedIndex = (slide_index, elems) => {\r\n if (props.images) {\r\n let iframe_index = 0;\r\n\r\n for (let i = 0; i < props.images.length; i++) {\r\n let item = props.images[i];\r\n if ((item.type == \"customVideoEmbed\" || item.type == \"yt\")) {\r\n if (i == slide_index) {\r\n iframe_index++;\r\n break;\r\n }\r\n else {\r\n iframe_index++;\r\n }\r\n }\r\n }\r\n\r\n return iframe_index - 1;\r\n }\r\n }\r\n\r\n const getEmblaClass = (index) => {\r\n\r\n if (displayImgMetadata) {\r\n return styles.emblaSlideGrid;\r\n }\r\n\r\n if (imgAnimation == \"fade\") {\r\n let styles_str = \"\";\r\n\r\n if (props.fullScreen != true) {\r\n styles_str += `${styles.notFullScreen} `\r\n }\r\n\r\n styles_str += ` ${styles.imgfade} ${styles.emblaSlide} `\r\n if (slideIndex == index) {\r\n styles_str += `${styles.emblaSlideSelected} `\r\n }\r\n return styles_str;\r\n }\r\n\r\n else {\r\n return styles.emblaSlide;\r\n }\r\n }\r\n\r\n const resetVideo = (slide_index) => {\r\n if (props.images) {\r\n let elem = props.images[slide_index]\r\n if (elem) {\r\n if (elem.type == 'htmlVideo') {\r\n videoReferences.current[slide_index].pause()\r\n }\r\n else if (elem.type == \"yt\") {\r\n if (videoElements[slide_index]) {\r\n videoElements[slide_index].target.pauseVideo()\r\n\r\n }\r\n }\r\n else if (elem.type == \"customVideoEmbed\") {\r\n let lightboxjs_elem = document.getElementById(\"lightboxContainer\");\r\n let elems = lightboxjs_elem?.querySelectorAll(\"iframe\");\r\n if (elems) {\r\n let iframe_elem_index = getEmbedIndex(slide_index, elems);\r\n if (iframe_elem_index != undefined && iframe_elem_index >= 0) {\r\n // reset iframe\r\n let iframe = elems[iframe_elem_index];\r\n let iframe_src = iframe.src\r\n iframe.src = iframe_src;\r\n }\r\n\r\n }\r\n\r\n }\r\n }\r\n }\r\n }\r\n\r\n const getNavigationDot = (index) => {\r\n return (\r\n <button style={slideIndex === index ? { backgroundColor: \"cornflowerblue\" } : {}}\r\n className={`${styles.navigationDot} imageModal`} onClick={() => { navigationClick(index) }}></button>\r\n\r\n )\r\n }\r\n\r\n const getThumbnailsOuterContainerStyle = () => {\r\n let style = {};\r\n if (isImageCaption(\"below\")) {\r\n if (showThumbnails) {\r\n style[\"height\"] = \"21vh\"\r\n }\r\n else {\r\n style[\"height\"] = \"12vh\"\r\n }\r\n style[\"backgroundColor\"] = backgroundColor;\r\n }\r\n return style;\r\n\r\n }\r\n\r\n const getImageThumbnail = (img, index, isNextJS, props) => {\r\n return (\r\n <div key={\"thumbnail_slide_\" + index} className={`${styles.emblaThumbsSlide}`}>\r\n\r\n <img\r\n className={`${styles.thumbnail} imageModal ${props.thumbnailImgClass ? props.thumbnailImgClass : \"\"} `}\r\n src={isNextJS == true ? getThumbnailImgSrcNext(img, index) : getThumbnailImgSrc(img, index)}\r\n alt={img.alt}\r\n onLoad={() => setImagesLoaded(true)}\r\n style={\r\n slideIndex === index\r\n ? { border: thumbnailBorder }\r\n : { border: inactiveThumbnailBorder }\r\n }\r\n key={\"thumbnail_\" + index}\r\n onClick={(event) => {\r\n\r\n if (props.onThumbnailClick) {\r\n props.onThumbnailClick(index, img);\r\n }\r\n navigationClick(index);\r\n }}\r\n />\r\n </div>\r\n )\r\n }\r\n\r\n const handleError = (event, index) => {\r\n if (props.onImgError) {\r\n props.onImgError(event, images[slideIndex], index);\r\n\r\n }\r\n }\r\n\r\n const rotateImage = () => {\r\n let img_elem = imageRefs.current[zoomIdx];\r\n let transform_val = img_elem.style.transform;\r\n\r\n let current_rotation = 0;\r\n if (transform_val) {\r\n var reg = /rotate\\(([0-9.]+)deg\\)/;\r\n current_rotation = parseFloat(transform_val.match(reg)[1]);\r\n }\r\n\r\n let newRotation = current_rotation + 90;\r\n\r\n let res = newRotation / 90;\r\n\r\n img_elem.style.transform = `rotate(${newRotation}deg)`\r\n\r\n setCurrentRotation(newRotation);\r\n if (props.onRotate) {\r\n let rotationVal = newRotation;\r\n if (newRotation > 360) {\r\n rotationVal = newRotation % 360;\r\n }\r\n props.onRotate(rotationVal);\r\n }\r\n }\r\n\r\n const resetRotation = () => {\r\n imageRefs.current[zoomIdx].classList.remove(`${styles.rotate_img}`)\r\n\r\n imageRefs.current[zoomIdx].style.transform = \"\";\r\n setCurrentRotation(0)\r\n }\r\n\r\n const resetImage = () => {\r\n if (enableMagnifyingGlass) {\r\n initMagnifyingGlass()\r\n } else {\r\n if (zoomReferences.current[zoomIdx] != null) {\r\n zoomReferences.current[zoomIdx]!.resetTransform()\r\n }\r\n }\r\n // resetRotation()\r\n }\r\n\r\n const getThumbnailImgSrc = (img, index) => {\r\n\r\n if (props.images && props.images.length > 0) {\r\n if (props.images[index] && props.images[index].thumbnailSrc) {\r\n return props.images[index].thumbnailSrc\r\n }\r\n }\r\n\r\n if (isVideo(index) && img.thumbnail) {\r\n return img.thumbnail\r\n }\r\n else {\r\n return img.src\r\n }\r\n }\r\n\r\n const getImgFadeClass = () => {\r\n if (imgAnimation == \"fade\") {\r\n if (isImageCaption(\"above\")) {\r\n return ` ${styles.imgfade} ${styles.imgFadeWithTopCaption}`\r\n }\r\n else {\r\n return ` ${styles.imgfade}`\r\n }\r\n }\r\n\r\n }\r\n\r\n const getThumbnailImgSrcNext = (img, index) => {\r\n if (img.thumbnailSrc) {\r\n return img.thumbnailSrc\r\n }\r\n\r\n else if (isVideo(index)) {\r\n return img.thumbnail\r\n } else {\r\n let img_src = img.src\r\n if (\r\n typeof img_src === 'object' &&\r\n !Array.isArray(img_src) &&\r\n img_src !== null\r\n ) {\r\n return img_src.src\r\n } else {\r\n return img_src\r\n }\r\n }\r\n }\r\n\r\n const isAnimImageComponent = () => {\r\n if (images) {\r\n if (images.length == 1) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n const initWrapperClassname = () => {\r\n\r\n let classNameStr = \"\";\r\n if (props.className) {\r\n classNameStr += `${props.className} `\r\n }\r\n if (isAnimImageComponent()) {\r\n if (props.imgWrapperClassName) {\r\n classNameStr += `${props.imgWrapperClassName} `\r\n }\r\n }\r\n\r\n classNameStr += `${styles.lightboxjs}`;\r\n\r\n return classNameStr;\r\n }\r\n\r\n const initStyling = () => {\r\n if (props.theme) {\r\n if (themes[props.theme]) {\r\n setBackgroundColor(themes[props.theme].background)\r\n // setIconColor(themes[props.theme].iconColor)\r\n // setThumbnailBorder(themes[props.theme].thumbnailBorder)\r\n setTextColor(themes[props.theme].textColor)\r\n }\r\n }\r\n\r\n if (props.fullScreen) {\r\n if (props.fullScreen == true) {\r\n setImgAnimation(props.imgAnimation && props.imgAnimation == \"imgDrag\" ? props.imgAnimation : \"fade\")\r\n setIsRounded(false)\r\n }\r\n }\r\n }\r\n\r\n const getMetadataPanel = () => {\r\n\r\n let imgMetadataItem = imgMetadata[slideIndex];\r\n\r\n if (imgMetadataItem) {\r\n let element = <div className={styles.metadataPanel}>\r\n <b>Filename</b>\r\n {imgMetadataItem.name ? <p>{imgMetadataItem.name}</p> : null}\r\n\r\n {imgMetadataItem.createDate ?\r\n <div>\r\n <b>Captured Time</b>\r\n <p>{imgMetadataItem.createDate.toString()}</p>\r\n </div>\r\n\r\n : null}\r\n\r\n {\r\n imgMetadataItem.width && imgMetadataItem.height ?\r\n <div>\r\n <b>Resolution</b>\r\n <p>{imgMetadataItem.width}*{imgMetadataItem.height}</p>\r\n </div> : null\r\n }\r\n\r\n {imgMetadataItem.isoData || imgMetadataItem.fNumber || imgMetadataItem.shutterSpeed ?\r\n <div>\r\n <b>Image Details</b>\r\n {\r\n imgMetadataItem.isoData ? <span>ISO {imgMetadataItem.isoData}</span>\r\n : null\r\n }\r\n\r\n {\r\n imgMetadataItem.fNumber ? <span>f{imgMetadataItem.fNumber}</span> : null\r\n }\r\n\r\n {\r\n imgMetadataItem.shutterSpeed ? <span>Shutter speed: {imgMetadataItem.shutterSpeed}</span> : null\r\n }\r\n </div> : null\r\n\r\n }\r\n\r\n </div>\r\n return element;\r\n }\r\n\r\n }\r\n\r\n const imageSlideElement = (index) => {\r\n let imageElem;\r\n if (!props.images) {\r\n imageElem = (\r\n <LightboxImage\r\n onImgError={(e, index) => handleError(e, index)}\r\n props={props} imgStyle={getImageStyle()}\r\n imgRef={(el) => imageRefs.current[index] = el}\r\n imgSrc={\r\n images[index].original ? images[index].original : images[index].src\r\n }\r\n displayImgMetadata={displayImgMetadata}\r\n enableMagnifyingGlass={enableMagnifyingGlass}\r\n index={index}\r\n onUpdateImgMetadata={(newImgMetadata) => setImgMetadata(newImgMetadata)}\r\n />\r\n )\r\n } else if (props.images && props.render) {\r\n imageElem = props.render.imgSlide(props.images[index])\r\n } else {\r\n let img_link\r\n\r\n // check if object (Next.js local image imports are passed as objects with a src attribute)\r\n if (props.images) {\r\n if (\r\n typeof images[index].src === 'object' &&\r\n !Array.isArray(images[index].src) &&\r\n images[index].src !== null\r\n ) {\r\n img_link = images[index].src?.src\r\n } else if (props.coverImageInLightbox == true) {\r\n img_link = images[index].src\r\n } else {\r\n img_link = images[index].src\r\n }\r\n }\r\n\r\n imageElem = (\r\n <LightboxImage\r\n onImgError={(e, index) => handleError(e, index)}\r\n props={props}\r\n imgStyle={getImageStyle()}\r\n imgRef={(el) => imageRefs.current[index] = el}\r\n imgSrc={\r\n images[index].original\r\n ? images[index].original\r\n : img_link\r\n }\r\n displayImgMetadata={displayImgMetadata}\r\n enableMagnifyingGlass={enableMagnifyingGlass}\r\n index={index}\r\n onUpdateImgMetadata={(newImgMetadata) => setImgMetadata(newImgMetadata)}\r\n\r\n />\r\n )\r\n }\r\n\r\n return imageElem\r\n }\r\n\r\n const getCloseIconBtnStyle = () => {\r\n let style_object = {}\r\n if (iconColor) {\r\n style_object = { color: iconColor }\r\n }\r\n if (props.closeIconBtnStyle) {\r\n let closeIconBtnStyleKeys = Object.keys(props.closeIconBtnStyle)\r\n for (let i = 0; i < closeIconBtnStyleKeys.length; i++) {\r\n let keyName = closeIconBtnStyleKeys[i];\r\n let style_obj = props.closeIconBtnStyle[keyName]\r\n style_object[keyName] = style_obj;\r\n }\r\n }\r\n if (customIconStyle) {\r\n style_object = customIconStyle\r\n }\r\n return style_object;\r\n\r\n }\r\n\r\n const isPanningDisabled = () => {\r\n if ((isMobile || isTablet || isTabletUserAgent) && zoomedIn == false) {\r\n return true;\r\n }\r\n if ((isMobile || isTablet || isTabletUserAgent) && zoomedIn) {\r\n return false;\r\n }\r\n return false;\r\n }\r\n\r\n\r\n const getLightboxElem = (index) => {\r\n if (isCustomEmbed(index)) {\r\n return customEmbedElement(index)\r\n }\r\n else if (isVideo(index)) {\r\n return videoSlideElement(index)\r\n }\r\n else if (isPictureElement(index)) {\r\n let elem_metadata = props.images[index][\"picture\"];\r\n return <picture className={`imageModal \r\n ${styles.lightboxImg} \r\n ${enableMagnifyingGlass\r\n ? styles.maxWidthFull\r\n : styles.maxWidthWithoutMagnifier\r\n } `}>\r\n {Object.keys(elem_metadata).map((format) => (\r\n <source\r\n type={format}\r\n key={format}\r\n srcSet={elem_metadata[format].srcSet}\r\n />\r\n ))}\r\n <img src={elem_metadata['fallback']}\r\n onError={(error) => {\r\n handleError(error, index)\r\n }}\r\n />\r\n </picture>\r\n }\r\n else {\r\n\r\n if ((images && props.render) ||\r\n frameworkID == 'next') {\r\n return imageSlideElement(index);\r\n }\r\n else {\r\n return <LightboxImage\r\n onImgError={(e, index) => handleError(e, index)}\r\n props={props} imgStyle={getImageStyle()}\r\n imgRef={(el) => imageRefs.current[index] = el}\r\n imgSrc={\r\n images && images[index].original\r\n ? images[index].original\r\n : images[index].src}\r\n displayImgMetadata={displayImgMetadata}\r\n enableMagnifyingGlass={enableMagnifyingGlass}\r\n index={index}\r\n onUpdateImgMetadata={(newImgMetadata) => setImgMetadata(newImgMetadata)}\r\n\r\n />\r\n\r\n }\r\n }\r\n }\r\n\r\n const isCustomEmbed = (index) => {\r\n\r\n if (props.images) {\r\n let elem = props.images[index]\r\n if (elem) {\r\n if (elem.type == 'customEmbed') {\r\n return true\r\n }\r\n }\r\n }\r\n return false\r\n }\r\n\r\n const isVideo = (index) => {\r\n\r\n if (props.images) {\r\n let elem = props.images[index]\r\n if (elem) {\r\n if (elem.type == 'yt' || elem.type == 'htmlVideo' || elem.type == 'customVideoEmbed') {\r\n return true\r\n }\r\n }\r\n }\r\n\r\n return false\r\n }\r\n\r\n const shouldDisplayMetadataPanel = () => {\r\n if (isMobile) {\r\n if (showImgMetadataPanel) {\r\n return true;\r\n }\r\n else {\r\n return false;\r\n }\r\n }\r\n else {\r\n return displayImgMetadata;\r\n }\r\n }\r\n\r\n const isPictureElement = (index) => {\r\n if (props.images) {\r\n let elem = props.images[index]\r\n if (elem) {\r\n if (elem.picture) {\r\n return true\r\n }\r\n }\r\n }\r\n\r\n return false\r\n }\r\n\r\n useEffect(() => {\r\n if (!emblaApi) return\r\n\r\n if (imgAnimation == \"fade\") {\r\n emblaApi.internalEngine().translate.toggleActive(false);\r\n }\r\n\r\n }, [\r\n carouselReady, emblaApi\r\n ])\r\n\r\n const getIconStyle = () => {\r\n if (iconColor) {\r\n return { color: iconColor }\r\n }