UNPKG

easy-magnify

Version:

Everything you need for magnifying images

1 lines 52.1 kB
{"version":3,"sources":["../src/EasyZoomOnHover.tsx","../src/utils/useZoomImageHover.ts","../src/hooks/useMouse/use-mouse.tsx","../src/hooks/useSkeleton/Skeleton.tsx","../src/hooks/useStore/use-store.ts","../src/core/imageLoader.tsx","../src/core/clamp.ts","../src/core/createZoomImageHover.tsx","../src/utils/useZoomImageMove.ts","../src/core/cropImage.tsx","../src/core/createZoomImageMove.tsx","../src/EasyZoomOnMove.tsx"],"names":["React","useCallback","useEffect","useRef","useState","controller","EasyZoomOnHover","createZoomImageHover","createZoomImageMove"],"mappings":"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","sourcesContent":["\"use client\";\r\nimport React from 'react';\r\nimport { useZoomImageHover } from './utils';\r\nimport { EasySkeleton } from './hooks/useSkeleton';\r\n\r\n\r\nexport type EasyZoomOnHoverProps = {\r\n\r\n /**\r\n * Delay timer in ms for knowingly applying delay on loader and enhancing user experience\r\n * @default 1600\r\n */\r\n delayTimer?: number;\r\n\r\n /**\r\n * The distance between main image and zoomed Image in pixels. \r\n * @default 10\r\n */\r\n distance?: number;\r\n\r\n /**\r\n * The loading indicator to show when the image is loading. Provides extra user experience.\r\n * default: EasySkeleton with height={500} and width={500}\r\n */\r\n loadingIndicator?: React.ReactNode;\r\n mainImage: {\r\n width?: number;\r\n height?: number;\r\n src: string;\r\n alt?: string;\r\n }\r\n zoomImage: {\r\n src: string;\r\n alt?: string;\r\n }\r\n zoomContainerWidth?: number;\r\n zoomContainerHeight?: number;\r\n zoomLensScale?: number;\r\n}\r\n\r\nexport type ImageDimensionType = {\r\n height: number;\r\n width: number;\r\n}\r\n\r\n\r\nconst EasyZoomOnHover = React.forwardRef(function EasyZoomOnHover(props: EasyZoomOnHoverProps, ref: React.Ref<HTMLDivElement>) {\r\n\r\n const { mainImage, zoomImage, loadingIndicator, delayTimer, distance = 10, zoomContainerWidth } = props;\r\n const { createZoomImage: createZoomImageHover } = useZoomImageHover();\r\n\r\n const imageHoverContainerRef = React.useRef<HTMLDivElement>(null);\r\n const zoomTargetRef = React.useRef<HTMLDivElement>(null);\r\n const imgRef = React.useRef<HTMLImageElement>(null);\r\n\r\n const [imageDimension, setImageDimensions] = React.useState<ImageDimensionType>({ height: 0, width: 0 });\r\n const [isImageLoaded, setIsImageLoaded] = React.useState(false);\r\n\r\n const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));\r\n\r\n const handleImageLoad = async () => {\r\n if (imgRef.current) {\r\n setImageDimensions({\r\n width: imgRef.current.naturalWidth,\r\n height: imgRef.current.naturalHeight,\r\n });\r\n await delay(delayTimer ?? 1600); //delay for better user experience\r\n setIsImageLoaded(true);\r\n }\r\n };\r\n\r\n React.useEffect(() => {\r\n if (imageDimension.width > 0 && imageDimension.height > 0) {\r\n const imageContainer = imageHoverContainerRef.current as HTMLDivElement;\r\n const zoomTarget = zoomTargetRef.current as HTMLDivElement;\r\n createZoomImageHover(\r\n imageContainer, {\r\n zoomImageSource: zoomImage.src ?? mainImage.src,\r\n customZoom: {\r\n width: props.zoomContainerWidth ?? imageDimension.width ?? 450,\r\n height: props.zoomContainerHeight ?? imageDimension.height ?? 470\r\n },\r\n zoomTarget,\r\n scale: props.zoomLensScale ?? 3,\r\n });\r\n }\r\n }, [isImageLoaded, imageDimension]);\r\n\r\n return (\r\n <>\r\n {!isImageLoaded && (loadingIndicator ??\r\n <EasySkeleton\r\n height={props.mainImage.height ?? 450}\r\n width={props.mainImage.width ?? 450}\r\n />\r\n )}\r\n <div\r\n ref={imageHoverContainerRef}\r\n className=\"EasyZoomImageHoverMainContainer\"\r\n style={{\r\n position: \"relative\",\r\n width: props.mainImage.width ?? imageDimension.width,\r\n height: props.mainImage.height ?? imageDimension.height,\r\n display: isImageLoaded ? \"flex\" : \"none\",\r\n justifyItems: \"start\",\r\n }}\r\n >\r\n <img\r\n className=\"EasyZoomHoverSmallImage\"\r\n onLoad={handleImageLoad}\r\n ref={imgRef}\r\n style={{ height: \"auto\", width: \"auto\" }}\r\n alt={mainImage.alt ?? \"Small Pic\"}\r\n src={mainImage.src}\r\n />\r\n\r\n <div\r\n ref={zoomTargetRef}\r\n className=\"EasyZoomImageZoomHoverContainer\"\r\n id=\"zoomTargeted\"\r\n style={{\r\n position: \"absolute\",\r\n maxWidth: zoomContainerWidth ?? \"450px\",\r\n left: `${mainImage.width ? mainImage.width + distance : imageDimension.width + distance}px`,\r\n }}\r\n ></div>\r\n </div>\r\n </>\r\n )\r\n})\r\n\r\nexport default EasyZoomOnHover;\r\n","\"use client\"\r\nimport { useCallback, useEffect, useRef, useState } from \"react\"\r\nimport { ZoomImageHoverState, createZoomImageHover as _createZoomImageHover } from \"../core/createZoomImageHover\"\r\n\r\n\r\nexport default function useZoomImageHover() {\r\n const result = useRef<ReturnType<typeof _createZoomImageHover>>()\r\n const [zoomImageState, updateZoomImageState] = useState<ZoomImageHoverState>({\r\n enabled: false,\r\n zoomedImgStatus: \"idle\",\r\n })\r\n\r\n const createZoomImage = useCallback((...arg: Parameters<typeof _createZoomImageHover>) => {\r\n result.current?.cleanup()\r\n result.current = _createZoomImageHover(...arg)\r\n updateZoomImageState(result.current.getState())\r\n\r\n result.current.subscribe(({ state }: any) => {\r\n updateZoomImageState(state)\r\n })\r\n }, [])\r\n\r\n useEffect(() => {\r\n return () => {\r\n result.current?.cleanup()\r\n }\r\n }, [])\r\n\r\n return {\r\n createZoomImage,\r\n zoomImageState,\r\n setZoomImageState: result.current?.setState ?? (() => { }),\r\n }\r\n}","\"use client\";\r\nimport { useEffect, useRef, useState, useCallback } from 'react';\r\nimport type { MouseEvent } from 'react';\r\n\r\n/**\r\n * This hook is used for tracking mouse position. Note: this is to be tested and not recommended as of 1.1.0\r\n * for use as it re-renders whole component on change of cursor position. It is to be optimized.\r\n */\r\nfunction useMouse<T extends HTMLElement = any>(\r\n options: { resetOnExit?: boolean } = { resetOnExit: false }\r\n) {\r\n const [position, setPosition] = useState({ x: 0, y: 0 });\r\n const ref = useRef<T>(null);\r\n const requestRef = useRef<number | null>(null);\r\n const positionRef = useRef(position);\r\n\r\n const setMousePosition = useCallback((event: MouseEvent<HTMLElement>) => {\r\n if (ref.current) {\r\n const rect = event.currentTarget.getBoundingClientRect();\r\n const x = Math.max(\r\n 0,\r\n Math.round(event.pageX - rect.left - (window.pageXOffset || window.scrollX))\r\n );\r\n const y = Math.max(\r\n 0,\r\n Math.round(event.pageY - rect.top - (window.pageYOffset || window.scrollY))\r\n );\r\n positionRef.current = { x, y };\r\n } else {\r\n positionRef.current = { x: event.clientX, y: event.clientY };\r\n }\r\n if (requestRef.current === null) {\r\n requestRef.current = requestAnimationFrame(() => {\r\n setPosition(positionRef.current);\r\n requestRef.current = null;\r\n });\r\n }\r\n }, []);\r\n\r\n const resetMousePosition = useCallback(() => {\r\n positionRef.current = { x: 0, y: 0 };\r\n setPosition({ x: 0, y: 0 });\r\n }, []);\r\n\r\n useEffect(() => {\r\n const element = ref.current || document;\r\n element.addEventListener('mousemove', setMousePosition as any);\r\n if (options.resetOnExit) element.addEventListener('mouseleave', resetMousePosition as any);\r\n\r\n return () => {\r\n element.removeEventListener('mousemove', setMousePosition as any);\r\n if (options.resetOnExit) element.removeEventListener('mouseleave', resetMousePosition as any);\r\n if (requestRef.current !== null) {\r\n cancelAnimationFrame(requestRef.current);\r\n }\r\n };\r\n }, [setMousePosition, resetMousePosition, options.resetOnExit]);\r\n\r\n return { ref, ...position };\r\n}\r\n\r\nexport default useMouse;\r\n","import React from \"react\";\r\nimport { HTMLAttributes } from 'react';\r\n\r\n\r\nexport interface SkeletonPropsType extends HTMLAttributes<HTMLDivElement> {\r\n height: number;\r\n width: number;\r\n\r\n /**\r\n * Animation of the skeleton. Default is \"pulse 2s ease-in-out 0.5s infinite\"\r\n */\r\n animation?: string;\r\n\r\n /**\r\n * Background color of the skeleton. Default is #0000001c\r\n */\r\n backgroundColor?: string;\r\n}\r\n\r\nconst EasySkeleton = (props: SkeletonPropsType) => {\r\n\r\n const { height, width, backgroundColor, animation, ...other } = props;\r\n\r\n return (\r\n <div className=\"easyPulseSkeleton\" style={{\r\n backgroundColor: backgroundColor ?? \"#0000001c\",\r\n height: `${height}px`,\r\n width: `${width}px`,\r\n animation: animation ?? \"pulse 2s ease-in-out 0.5s infinite\"\r\n }}\r\n {...other}\r\n />\r\n );\r\n};\r\n\r\nexport default EasySkeleton;","export type StoreListener<TState> = (arg: { state: TState; updatedProperties: Partial<TState> }) => void\r\n\r\nexport default function createStore<TState>(initialState: TState) {\r\n const listeners = new Set<StoreListener<TState>>()\r\n let batching = false\r\n let state: TState = initialState\r\n let updatedProperties: Partial<TState> | undefined\r\n\r\n const setState = (extraState: Partial<TState> = {}) => {\r\n updatedProperties = { ...updatedProperties, ...extraState }\r\n flush()\r\n }\r\n\r\n const flush = () => {\r\n if (batching) return\r\n\r\n let hasChanged = false\r\n\r\n if (updatedProperties) {\r\n for (const key in updatedProperties) {\r\n if (state[key] !== updatedProperties[key]) {\r\n hasChanged = true\r\n break\r\n }\r\n }\r\n }\r\n\r\n if (!hasChanged) {\r\n return\r\n }\r\n\r\n state = { ...state, ...updatedProperties }\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n listeners.forEach((listener) => listener({ state, updatedProperties } as any))\r\n updatedProperties = undefined\r\n }\r\n\r\n const batch = (cb: () => void) => {\r\n batching = true\r\n cb()\r\n batching = false\r\n flush()\r\n }\r\n\r\n const subscribe = (listener: StoreListener<TState>) => {\r\n listeners.add(listener)\r\n return () => {\r\n listeners.delete(listener)\r\n }\r\n }\r\n\r\n const cleanup = () => listeners.clear()\r\n\r\n const getState = () => state\r\n\r\n return {\r\n subscribe,\r\n cleanup,\r\n getState,\r\n setState,\r\n batch,\r\n }\r\n}","import { createStore } from \"../hooks\"\r\n\r\n// There is a scenario where the image is already in the cache,\r\n// we don't want to trigger the loading state too quickly in that case\r\n// 50ms should be enough to wait before triggering the loading state\r\n\r\nconst THRESHOLD = 50;\r\ntype ZoomedImgStatus = \"idle\" | \"loading\" | \"loaded\" | \"error\";\r\n\r\n\r\nexport const makeImageLoader = () => {\r\n const createZoomImage = (\r\n img: HTMLImageElement,\r\n src: string,\r\n store: ReturnType<\r\n typeof createStore<{\r\n zoomedImgStatus: ZoomedImgStatus\r\n }>\r\n >,\r\n ) => {\r\n if (img.src === src) return\r\n img.src = src\r\n let complete = false\r\n\r\n img.onload = () => {\r\n complete = true\r\n store.setState({ zoomedImgStatus: \"loaded\" })\r\n }\r\n\r\n img.onerror = () => {\r\n complete = true\r\n store.setState({ zoomedImgStatus: \"error\" })\r\n }\r\n\r\n setTimeout(() => {\r\n if (!complete) store.setState({ zoomedImgStatus: \"loading\" })\r\n }, THRESHOLD)\r\n }\r\n\r\n return {\r\n createZoomImage,\r\n }\r\n}\r\n\r\nexport const imageLoader = makeImageLoader()","export function clamp(value: number, min: number, max: number) {\r\n return Math.max(min, Math.min(max, value))\r\n}\r\n\r\nexport function noop() { }\r\n\r\nfunction preventDefault(event: Event) {\r\n event.preventDefault()\r\n}\r\n\r\nconst keySet = new Set([\"ArrowUp\", \"ArrowRight\", \"ArrowDown\", \"ArrowLeft\"])\r\nfunction preventDefaultForScrollKeys(event: KeyboardEvent) {\r\n if (keySet.has(event.key)) {\r\n preventDefault(event)\r\n return false\r\n }\r\n}\r\n\r\nlet controller: AbortController | undefined\r\n\r\nexport function disableScroll() {\r\n controller = new AbortController()\r\n const { signal } = controller\r\n window.addEventListener(\"DOMMouseScroll\", preventDefault, { signal })\r\n window.addEventListener(\"wheel\", preventDefault, { passive: false, signal })\r\n window.addEventListener(\"touchmove\", preventDefault, { passive: false, signal })\r\n window.addEventListener(\"keydown\", preventDefaultForScrollKeys, { signal })\r\n}\r\n\r\nexport function enableScroll() {\r\n controller?.abort()\r\n}\r\n\r\nexport function getSourceImage(container: HTMLElement) {\r\n if (!container) {\r\n throw new Error(\"Please specify a container for the zoom image\")\r\n }\r\n\r\n const sourceImgElement = container.querySelector(\"img\")\r\n if (!sourceImgElement) {\r\n throw new Error(\"Please place an image inside the container\")\r\n }\r\n\r\n return sourceImgElement\r\n}\r\n\r\nexport type PointerPosition = {\r\n x: number\r\n y: number\r\n}\r\n\r\nexport function getPointersCenter(first: PointerPosition, second: PointerPosition) {\r\n return {\r\n x: (first.x + second.x) / 2,\r\n y: (first.y + second.y) / 2,\r\n }\r\n}\r\n\r\n// Given the previous and current positions of two touch inputs, compute the zoom\r\n// factor and the origin of the zoom gesture.\r\nexport function computeZoomGesture(prev: [PointerPosition, PointerPosition], curr: [PointerPosition, PointerPosition]) {\r\n const prevCenter = getPointersCenter(prev[0], prev[1])\r\n const currCenter = getPointersCenter(curr[0], curr[1])\r\n const centerDist = { x: currCenter.x - prevCenter.x, y: currCenter.y - prevCenter.y }\r\n\r\n const prevDistance = Math.hypot(prev[0].x - prev[1].x, prev[0].y - prev[1].y)\r\n const currDistance = Math.hypot(curr[0].x - curr[1].x, curr[0].y - curr[1].y)\r\n let scale = currDistance / prevDistance\r\n\r\n // avoid division by zero\r\n const eps = 0.00001\r\n if (Math.abs(scale - 1) < eps) {\r\n scale = 1 + eps\r\n }\r\n\r\n return {\r\n scale,\r\n center: {\r\n // We shift the zoom center away such that the translation part of the gesture\r\n // is also captured by the zoom operation.\r\n x: prevCenter.x + centerDist.x / (1 - scale),\r\n y: prevCenter.y + centerDist.y / (1 - scale),\r\n },\r\n }\r\n}\r\n\r\nexport function makeMaybeCallFunction<T>(predicateFn: () => boolean, fn: (arg: T) => void) {\r\n return (arg: T) => {\r\n if (predicateFn()) {\r\n fn(arg)\r\n }\r\n }\r\n}\r\n\r\nexport const scaleLinear =\r\n ({\r\n domainStart,\r\n domainStop,\r\n rangeStart,\r\n rangeStop,\r\n }: {\r\n domainStart: number\r\n domainStop: number\r\n rangeStart: number\r\n rangeStop: number\r\n }) =>\r\n (value: number) =>\r\n rangeStart + (rangeStop - rangeStart) * ((value - domainStart) / (domainStop - domainStart))","import { createStore } from \"../hooks\"\r\nimport { imageLoader } from \"./imageLoader\"\r\nimport { clamp, disableScroll, enableScroll, getSourceImage } from \"../core/clamp\";\r\n\r\ntype ZoomedImgStatus = \"idle\" | \"loading\" | \"loaded\" | \"error\"\r\n\r\n\r\nexport type ZoomImageHoverOptions = {\r\n customZoom: { width: number; height: number }\r\n zoomImageSource?: string\r\n zoomLensClass?: string\r\n zoomLensScale?: number\r\n zoomTarget: HTMLElement\r\n zoomTargetClass?: string\r\n scale?: number\r\n disableScrollLock?: boolean\r\n zoomImageProps?: {\r\n alt?: string\r\n }\r\n}\r\n\r\nexport type ZoomImageHoverState = {\r\n zoomedImgStatus: ZoomedImgStatus\r\n enabled: boolean\r\n}\r\n\r\nexport type ZoomImageHoverStateUpdate = { enabled: boolean }\r\n\r\nexport function createZoomImageHover(container: HTMLElement, options: ZoomImageHoverOptions) {\r\n const controller = new AbortController()\r\n const { signal } = controller\r\n const sourceImgElement = getSourceImage(container)\r\n const zoomedImgWrapper = document.createElement(\"div\")\r\n zoomedImgWrapper.style.overflow = \"hidden\"\r\n const zoomedImg = zoomedImgWrapper.appendChild(document.createElement(\"img\"))\r\n zoomedImg.alt = options.zoomImageProps?.alt || \"\"\r\n zoomedImg.style.maxWidth = \"none\"\r\n zoomedImg.style.display = \"none\"\r\n const zoomLens = container.appendChild(document.createElement(\"div\"))\r\n zoomLens.style.display = \"none\"\r\n zoomedImg.id = \"meroZoomedImg\"\r\n\r\n // Sometimes, source image element's width and height are not available until the image is loaded\r\n // and container size is set. These values are expected to be same as the container's width and height\r\n let sourceImageElementWidth = 0\r\n let sourceImageElementHeight = 0\r\n\r\n const finalOptions: Omit<Required<ZoomImageHoverOptions>, \"zoomImageProps\"> = {\r\n zoomImageSource: options.zoomImageSource || sourceImgElement.src,\r\n zoomLensClass: options.zoomLensClass || \"\",\r\n zoomTargetClass: options.zoomTargetClass || \"\",\r\n customZoom: options.customZoom,\r\n scale: options.scale || 2,\r\n zoomTarget: options.zoomTarget,\r\n zoomLensScale: options.zoomLensScale || 1,\r\n disableScrollLock: options.disableScrollLock || false,\r\n }\r\n\r\n const {\r\n scale,\r\n zoomImageSource,\r\n customZoom,\r\n zoomLensClass,\r\n zoomTarget,\r\n zoomLensScale,\r\n zoomTargetClass,\r\n disableScrollLock,\r\n } = finalOptions\r\n\r\n const store = createStore<ZoomImageHoverState>({\r\n zoomedImgStatus: \"idle\",\r\n enabled: true,\r\n })\r\n\r\n let offset: { left: number; top: number } = getOffset(sourceImgElement)\r\n\r\n function getOffset(element: HTMLElement) {\r\n const elRect = element.getBoundingClientRect()\r\n return { left: elRect.left, top: elRect.top }\r\n }\r\n\r\n function getLimitX(value: number) {\r\n return sourceImageElementWidth - value\r\n }\r\n\r\n function getLimitY(value: number) {\r\n return sourceImageElementHeight - value\r\n }\r\n\r\n function zoomLensLeft(left: number) {\r\n const minX = zoomLens.clientWidth / 2\r\n return clamp(left, minX, getLimitX(minX)) - minX\r\n }\r\n\r\n function zoomLensTop(top: number) {\r\n const minY = zoomLens.clientHeight / 2\r\n return clamp(top, minY, getLimitY(minY)) - minY\r\n }\r\n\r\n function processZoom(event: PointerEvent) {\r\n let offsetX: number\r\n let offsetY: number\r\n let backgroundX: number\r\n let backgroundY: number\r\n if (offset) {\r\n offsetX = zoomLensLeft(event.clientX - offset.left)\r\n offsetY = zoomLensTop(event.clientY - offset.top)\r\n backgroundX = (offsetX * scale) / zoomLensScale\r\n backgroundY = (offsetY * scale) / zoomLensScale\r\n zoomedImg.style.transform = \"translate(\" + -backgroundX + \"px,\" + -backgroundY + \"px)\"\r\n zoomLens.style.cssText += \"transform:\" + \"translate(\" + offsetX + \"px,\" + offsetY + \"px);\"\r\n }\r\n }\r\n\r\n async function handlePointerEnter() {\r\n imageLoader.createZoomImage(zoomedImg, zoomImageSource, store)\r\n zoomedImg.style.display = \"block\"\r\n zoomLens.style.display = \"block\"\r\n\r\n if (zoomTargetClass) {\r\n const classes = zoomTargetClass.split(\" \")\r\n classes.forEach((className) => zoomTarget.classList.add(className))\r\n }\r\n\r\n if (!disableScrollLock) disableScroll()\r\n }\r\n\r\n function handlePointerLeave() {\r\n zoomedImg.style.display = \"none\"\r\n zoomLens.style.display = \"none\"\r\n\r\n if (zoomTargetClass) {\r\n const classes = zoomTargetClass.split(\" \")\r\n classes.forEach((className) => zoomTarget.classList.remove(className))\r\n }\r\n\r\n if (!disableScrollLock) enableScroll()\r\n }\r\n\r\n function handleScroll() {\r\n offset = getOffset(sourceImgElement)\r\n }\r\n\r\n async function setup() {\r\n if (zoomLensClass) {\r\n zoomLens.className = zoomLensClass\r\n } else {\r\n zoomLens.style.backgroundImage = \"url(data:image/gif;base64,R0lGODlhZABkAPABAHOf4fj48yH5BAEAAAEALAAAAABkAGQAAAL+jI+py+0PowOB2oqvznz7Dn5iSI7SiabqWrbj68bwTLL2jUv0Lvf8X8sJhzmg0Yc8mojM5kmZjEKPzqp1MZVqs7Cr98rdisOXr7lJHquz57YwDV8j3XRb/C7v1vcovD8PwicY8VcISDGY2GDIKKf4mNAoKQZZeXg5aQk5yRml+dgZ2vOpKGraQpp4uhqYKsgKi+H6iln7N8sXG4u7p2s7ykvnyxos/DuMWtyGfKq8fAwd5nzGHN067VUtiv2lbV3GDfY9DhQu7p1pXoU+rr5ODk/j7sSePk9Ub33PlN+4jx8v4JJ/RQQa3EDwzcGFiBLi6AfN4UOGCyXegGjIoh0fisQ0rsD4y+NHjgZFqgB5y2Qfks1UPmEZ0OVLlIcKAAA7)\"\r\n zoomLens.style.cursor = \"pointer\"\r\n }\r\n\r\n // setup event listeners\r\n container.addEventListener(\"pointerdown\", processZoom, { signal })\r\n container.addEventListener(\"pointermove\", processZoom, { signal })\r\n container.addEventListener(\"pointerenter\", handlePointerEnter, { signal })\r\n container.addEventListener(\"pointerleave\", handlePointerLeave, { signal })\r\n window.addEventListener(\"scroll\", handleScroll, { signal })\r\n\r\n // Append zoomed image wrapper to zoom target\r\n zoomTarget.appendChild(zoomedImgWrapper)\r\n\r\n // Wait for next tick to get container size\r\n await new Promise((resolve) => setTimeout(resolve, 1))\r\n const containerRect = container.getBoundingClientRect()\r\n sourceImageElementWidth = containerRect.width\r\n sourceImageElementHeight = containerRect.height\r\n\r\n // Set up styles if custom zoom available\r\n if (customZoom) {\r\n zoomedImgWrapper.style.maxWidth = customZoom.width + \"px\"\r\n zoomedImgWrapper.style.height = customZoom.height + \"px\"\r\n } else {\r\n // Else default zoom to source image size\r\n zoomedImgWrapper.style.width = sourceImageElementWidth + \"px\"\r\n zoomedImgWrapper.style.height = sourceImageElementHeight + \"px\"\r\n }\r\n\r\n zoomedImg.width = (sourceImageElementWidth * scale) / zoomLensScale\r\n zoomedImg.height = (sourceImageElementHeight * scale) / zoomLensScale\r\n\r\n // Setup default zoom lens style\r\n const sourceImageRect = sourceImgElement.getBoundingClientRect()\r\n const fromLeft = sourceImageRect.left - containerRect.left\r\n const fromTop = sourceImageRect.top - containerRect.top\r\n zoomTarget.style.pointerEvents = \"none\"\r\n zoomLens.style.position = \"absolute\"\r\n zoomLens.style.left = fromLeft + \"px\"\r\n zoomLens.style.top = fromTop + \"px\"\r\n zoomLens.style.width = (customZoom.width / scale) * zoomLensScale + \"px\"\r\n zoomLens.style.height = (customZoom.height / scale) * zoomLensScale + \"px\"\r\n }\r\n\r\n setup()\r\n\r\n return {\r\n cleanup: () => {\r\n controller.abort()\r\n container.contains(zoomLens) && container.removeChild(zoomLens)\r\n\r\n if (zoomTarget && zoomTarget.contains(zoomedImgWrapper)) {\r\n zoomTarget.removeChild(zoomedImgWrapper)\r\n return\r\n }\r\n\r\n container.contains(zoomedImgWrapper) && container.removeChild(zoomedImgWrapper)\r\n },\r\n subscribe: store.subscribe,\r\n getState: store.getState,\r\n setState: (newState: ZoomImageHoverStateUpdate) => {\r\n store.setState(newState)\r\n },\r\n }\r\n}","\"use client\"\r\nimport { useCallback, useEffect, useRef, useState } from \"react\"\r\nimport { createZoomImageMove as _createZoomImageMove } from \"../core/createZoomImageMove\"\r\nimport type { ZoomImageMoveState } from \"../core/createZoomImageMove\"\r\n\r\nexport default function useZoomImageMove() {\r\n const result = useRef<ReturnType<typeof _createZoomImageMove>>()\r\n const [zoomImageState, updateZoomImageState] = useState<ZoomImageMoveState>({\r\n zoomedImgStatus: \"idle\",\r\n })\r\n\r\n const createZoomImage = useCallback((...arg: Parameters<typeof _createZoomImageMove>) => {\r\n result.current?.cleanup()\r\n result.current = _createZoomImageMove(...arg)\r\n updateZoomImageState(result.current.getState())\r\n\r\n result.current.subscribe(({ state }) => {\r\n updateZoomImageState(state)\r\n })\r\n }, [])\r\n\r\n useEffect(() => {\r\n return () => {\r\n result.current?.cleanup()\r\n }\r\n }, [])\r\n\r\n return {\r\n createZoomImage,\r\n zoomImageState,\r\n }\r\n}","export type CropImageArg = {\r\n currentZoom: number\r\n image: HTMLImageElement\r\n positionX: number\r\n positionY: number\r\n rotation?: number\r\n}\r\n\r\nconst cropImage = async ({ image, positionX, positionY, currentZoom, rotation = 0 }: CropImageArg) => {\r\n const canvas = document.createElement(\"canvas\")\r\n const scale = image.naturalWidth / (image.clientWidth * currentZoom)\r\n const normalizedRotation = rotation % 360\r\n const croppedImageWidth = image.clientWidth * scale\r\n const croppedImageHeight = image.clientHeight * scale\r\n canvas.width = croppedImageWidth\r\n canvas.height = croppedImageHeight\r\n const canvasContext = canvas.getContext(\"2d\") as CanvasRenderingContext2D\r\n\r\n const sx = Math.max(0, Math.abs(positionX) * scale)\r\n const sy = Math.max(0, Math.abs(positionY) * scale)\r\n\r\n canvasContext.drawImage(\r\n image,\r\n sx,\r\n sy,\r\n croppedImageWidth,\r\n croppedImageHeight,\r\n 0,\r\n 0,\r\n croppedImageWidth,\r\n croppedImageHeight,\r\n )\r\n\r\n const originalImage = new Image()\r\n originalImage.src = canvas.toDataURL()\r\n\r\n await new Promise((resolve) => setTimeout(resolve, 0))\r\n\r\n const rotatedCanvas = document.createElement(\"canvas\") as HTMLCanvasElement\r\n const rotatedCanvasContext = rotatedCanvas.getContext(\"2d\") as CanvasRenderingContext2D\r\n\r\n if (normalizedRotation === 90 || normalizedRotation === 270) {\r\n rotatedCanvas.width = originalImage.naturalHeight\r\n rotatedCanvas.height = originalImage.naturalWidth\r\n } else {\r\n rotatedCanvas.width = originalImage.naturalWidth\r\n rotatedCanvas.height = originalImage.naturalHeight\r\n }\r\n\r\n rotatedCanvasContext.clearRect(0, 0, canvas.width, canvas.height)\r\n if (normalizedRotation === 90 || normalizedRotation === 270) {\r\n rotatedCanvasContext.translate(originalImage.height / 2, originalImage.width / 2)\r\n } else {\r\n rotatedCanvasContext.translate(originalImage.width / 2, originalImage.height / 2)\r\n }\r\n rotatedCanvasContext.rotate((normalizedRotation * Math.PI) / 180)\r\n rotatedCanvasContext.drawImage(originalImage, -originalImage.width / 2, -originalImage.height / 2)\r\n\r\n return rotatedCanvas.toDataURL()\r\n}\r\nexport default cropImage;","import { createStore } from \"../hooks\"\r\nimport { imageLoader } from \"./imageLoader\"\r\nimport { disableScroll, enableScroll, getSourceImage } from \"../core\"\r\n\r\nexport type ZoomedImgStatus = \"idle\" | \"loading\" | \"loaded\" | \"error\"\r\n\r\nexport type ZoomImageMoveOptions = {\r\n zoomFactor?: number\r\n zoomImageSource?: string\r\n disableScrollLock?: boolean\r\n zoomImageProps?: {\r\n alt?: string\r\n }\r\n}\r\n\r\nexport type ZoomImageMoveState = {\r\n zoomedImgStatus: ZoomedImgStatus\r\n}\r\n\r\nexport function createZoomImageMove(container: HTMLElement, options: ZoomImageMoveOptions = {}) {\r\n const sourceImgElement = getSourceImage(container)\r\n const finalOptions: Omit<Required<ZoomImageMoveOptions>, \"zoomImageProps\"> = {\r\n zoomFactor: options.zoomFactor ?? 4,\r\n zoomImageSource: options.zoomImageSource ?? sourceImgElement.src,\r\n disableScrollLock: options.disableScrollLock ?? false,\r\n }\r\n\r\n const { disableScrollLock, zoomFactor, zoomImageSource } = finalOptions\r\n\r\n const store = createStore<ZoomImageMoveState>({\r\n zoomedImgStatus: \"idle\",\r\n })\r\n\r\n const zoomedImg = container.appendChild(document.createElement(\"img\"))\r\n zoomedImg.alt = options.zoomImageProps?.alt || \"\"\r\n zoomedImg.style.maxWidth = \"none\"\r\n zoomedImg.style.position = \"absolute\"\r\n zoomedImg.style.top = \"0\"\r\n zoomedImg.style.left = \"0\"\r\n\r\n function handlePointerEnter(event: PointerEvent) {\r\n zoomedImg.style.display = \"block\"\r\n const zoomedImgWidth = sourceImgElement.clientWidth * zoomFactor\r\n const zoomedImgHeight = sourceImgElement.clientHeight * zoomFactor\r\n zoomedImg.style.width = `${zoomedImgWidth}px`\r\n zoomedImg.style.height = `${zoomedImgHeight}px`\r\n imageLoader.createZoomImage(zoomedImg, zoomImageSource, store)\r\n\r\n processZoom(event)\r\n\r\n if (!disableScrollLock) disableScroll()\r\n }\r\n\r\n function handlePointerMove(event: PointerEvent) {\r\n processZoom(event)\r\n }\r\n\r\n function handlePointerLeave() {\r\n zoomedImg.style.display = \"none\"\r\n zoomedImg.style.transform = \"none\"\r\n if (!disableScrollLock) enableScroll()\r\n }\r\n\r\n const calculatePositionX = (newPositionX: number) => {\r\n const width = container.clientWidth\r\n if (newPositionX > 0) return 0\r\n if (newPositionX + width * zoomFactor < width) return -width * (zoomFactor - 1)\r\n return newPositionX\r\n }\r\n\r\n const calculatePositionY = (newPositionY: number) => {\r\n const height = container.clientHeight\r\n if (newPositionY > 0) return 0\r\n if (newPositionY + height * zoomFactor < height) return -height * (zoomFactor - 1)\r\n return newPositionY\r\n }\r\n\r\n function processZoom(event: PointerEvent) {\r\n zoomedImg.style.display = \"block\"\r\n\r\n const containerRect = container.getBoundingClientRect()\r\n const zoomPointX = event.clientX - containerRect.left\r\n const zoomPointY = event.clientY - containerRect.top\r\n\r\n const currentPositionX = calculatePositionX(-zoomPointX * zoomFactor + zoomPointX)\r\n const currentPositionY = calculatePositionY(-zoomPointY * zoomFactor + zoomPointY)\r\n zoomedImg.style.transform = `translate(${currentPositionX}px, ${currentPositionY}px)`\r\n }\r\n\r\n const controller = new AbortController()\r\n const { signal } = controller\r\n container.addEventListener(\"pointerenter\", handlePointerEnter, { signal })\r\n container.addEventListener(\"pointermove\", handlePointerMove, { signal })\r\n container.addEventListener(\"pointerleave\", handlePointerLeave, { signal })\r\n\r\n return {\r\n cleanup: () => {\r\n controller.abort()\r\n container.contains(zoomedImg) && container.removeChild(zoomedImg)\r\n container.style.width = \"100%\"\r\n container.style.height = \"100%\"\r\n store.cleanup()\r\n },\r\n subscribe: store.subscribe,\r\n getState: store.getState,\r\n }\r\n}","\"use client\"\r\nimport React from 'react'\r\nimport { useZoomImageMove } from './utils';\r\nimport { EasySkeleton } from './hooks/useSkeleton';\r\n\r\ntype EasyZoomOnMovePropsType = {\r\n /**\r\n * Delay timer in ms for knowingly applying delay on loader and enhancing user experience\r\n * @default 1600\r\n */\r\n delayTimer?: number;\r\n\r\n loadingIndicator?: React.ReactNode;\r\n mainImage: {\r\n width?: number;\r\n height?: number;\r\n src: string;\r\n alt?: string;\r\n };\r\n zoomImage: {\r\n src: string;\r\n alt?: string;\r\n };\r\n\r\n}\r\n\r\ntype ImageDimensionType = {\r\n width: number;\r\n height: number\r\n}\r\n\r\n\r\nconst EasyZoomOnMove = (props: EasyZoomOnMovePropsType) => {\r\n\r\n const { mainImage, zoomImage, loadingIndicator, delayTimer } = props;\r\n const [isImageLoaded, setIsImageLoaded] = React.useState(false);\r\n const { createZoomImage: createZoomImageMove } = useZoomImageMove();\r\n const imageMoveContainerRef = React.useRef<HTMLDivElement>(null)\r\n const imgRef = React.useRef<HTMLImageElement>(null)\r\n const [imageDimension, setImageDimensions] = React.useState<ImageDimensionType>({ height: 0, width: 0 });\r\n\r\n const delay = (ms: nu