Files
NapCatQQ/.pnpm-store/v3/files/c7/33f7e754720988ea72f48067e804ccdf16564b1b5519e4d02a3174bba1c7018c80b60892dde817cd00814728ad92002f740e67bcbe31bbdac856bb07c823e2
TanTan e311ca3275
Build NapCat Artifacts / Type Check & Test (push) Waiting to run
docs: 仓库链接指向本镜像仓库
2026-11-13 09:25:58 +08:00

1 line
91 KiB
Plaintext

{"version":3,"file":"react-photo-view.modern.js","sources":["../src/hooks/useMethods.ts","../src/hooks/useSetState.ts","../src/photo-context.ts","../src/variables.ts","../src/utils/isTouchDevice.ts","../src/utils/limitTarget.ts","../src/hooks/useIsomorphicLayoutEffect.ts","../src/hooks/useEventListener.ts","../src/components/SlidePortal.tsx","../src/components/CloseIcon.tsx","../src/components/ArrowLeft.tsx","../src/components/ArrowRight.tsx","../src/components/PreventScroll.tsx","../src/utils/getMultipleTouchPosition.ts","../src/utils/edgeHandle.ts","../src/utils/getPositionOnMoveOrScale.ts","../src/utils/getRotateSize.ts","../src/utils/getSuitableImageSize.ts","../src/hooks/useDebounceCallback.ts","../src/hooks/useScrollPosition.ts","../src/hooks/useAnimationOrigin.tsx","../src/hooks/useMountedRef.ts","../src/components/Spinner.tsx","../src/Photo.tsx","../src/PhotoBox.tsx","../src/hooks/useContinuousTap.ts","../src/hooks/useAnimationPosition.ts","../src/hooks/useTargetScale.ts","../src/PhotoSlider.tsx","../src/hooks/useAnimationVisible.tsx","../src/hooks/useForkedVariable.ts","../src/hooks/useAdjacentImages.ts","../src/PhotoProvider.tsx","../src/PhotoView.tsx","../src/hooks/useInitial.ts"],"sourcesContent":["import { useRef } from 'react';\n\n/**\n * Hook of persistent methods\n */\nexport default function useMethods<T extends Record<string, (...args: any[]) => any>>(fn: T) {\n const { current } = useRef({\n fn,\n curr: undefined as T | undefined,\n });\n current.fn = fn;\n\n if (!current.curr) {\n const curr = Object.create(null);\n Object.keys(fn).forEach((key) => {\n curr[key] = (...args: unknown[]) => current.fn[key].call(current.fn, ...args);\n });\n current.curr = curr;\n }\n\n return current.curr as T;\n}\n","import { useReducer } from 'react';\n\nexport default function useSetState<S extends Record<string, any>>(initialState: S) {\n return useReducer(\n (state: S, action: Partial<S> | ((state: S) => Partial<S>)) => ({\n ...state,\n ...(typeof action === 'function' ? action(state) : action),\n }),\n initialState,\n );\n}\n","import { createContext } from 'react';\nimport type { DataType } from './types';\n\nexport type UpdateItemType = (dataType: DataType) => void;\n\nexport interface PhotoContextType {\n show: (key: number) => void;\n update: UpdateItemType;\n remove: (key: number) => void;\n nextId: () => number;\n}\n\nexport default createContext<PhotoContextType>(undefined as unknown as PhotoContextType);\n","/**\n * 最大触摸时间\n */\nexport const maxTouchTime = 200;\n\n/**\n * 默认动画速度\n */\nexport const defaultSpeed = 400;\n\n/**\n * 默认动画函数\n */\nexport const defaultEasing = 'cubic-bezier(0.25, 0.8, 0.25, 1)';\n\n/**\n * 最大滑动切换图片距离\n */\nexport const maxMoveOffset = 40;\n\n/**\n * 图片的间隔\n */\nexport const horizontalOffset = 20;\n\n/**\n * 最小初始响应距离\n */\nexport const minStartTouchOffset = 20;\n\n/**\n * 默认背景透明度\n */\nexport const defaultOpacity = 1;\n\n/**\n * 最小缩放度\n */\nexport const minScale = 1;\n\n/**\n * 最大缩放度(若图片足够大,则会超出)\n */\nexport const maxScale = 6;\n\n/**\n * 最小长图模式比例\n */\nexport const longModeRatio = 3;\n\n/**\n * 缩放弹性缓冲\n */\nexport const scaleBuffer = 0.2;\n\n/**\n * 最大等待动画时间\n */\nexport const maxWaitAnimationTime = 250;\n","/**\n * 是否支持触摸设备\n */\nconst isTouchDevice = typeof window !== 'undefined' && 'ontouchstart' in window;\n\nexport default isTouchDevice;\n","import { maxScale, minScale } from '../variables';\n\nexport const limitNumber = (value: number, min: number, max: number) => {\n return Math.max(Math.min(value, max), min);\n};\n\n/**\n * 限制最大/最小缩放\n */\nexport const limitScale = (scale: number, max: number = 0, buffer: number = 0) => {\n return limitNumber(scale, minScale * (1 - buffer), Math.max(maxScale, max) * (1 + buffer));\n};\n","import { useEffect, useLayoutEffect } from 'react';\n\nconst isSSR = typeof window === 'undefined' || /ServerSideRendering/.test(navigator && navigator.userAgent);\n\nexport default isSSR ? useEffect : useLayoutEffect;\n","import { useEffect, useRef } from 'react';\n\nexport default function useEventListener<K extends keyof WindowEventMap>(\n type: K | undefined,\n fn: (evt: WindowEventMap[K]) => void,\n options?: AddEventListenerOptions,\n) {\n const latest = useRef(fn);\n latest.current = fn;\n\n useEffect(() => {\n function wrapper(evt: WindowEventMap[K]) {\n latest.current(evt);\n }\n if (type) {\n window.addEventListener(type, wrapper, options);\n }\n return () => {\n if (type) {\n window.removeEventListener(type, wrapper);\n }\n };\n }, [type]);\n}\n","import React from 'react';\nimport { createPortal } from 'react-dom';\nimport './SlidePortal.less';\n\nexport interface ISliderPortalProps extends React.HTMLAttributes<HTMLDivElement> {\n container?: HTMLElement;\n}\n\nfunction SlidePortal({ container = document.body, ...rest }: ISliderPortalProps) {\n return createPortal(<div {...rest} />, container);\n}\n\nexport default SlidePortal;\n","import React from 'react';\n\nfunction CloseIcon(props: React.HTMLAttributes<SVGElement>) {\n return (\n <svg width=\"44\" height=\"44\" viewBox=\"0 0 768 768\" {...props}>\n <path d=\"M607.5 205.5l-178.5 178.5 178.5 178.5-45 45-178.5-178.5-178.5 178.5-45-45 178.5-178.5-178.5-178.5 45-45 178.5 178.5 178.5-178.5z\" />\n </svg>\n );\n}\n\nexport default CloseIcon;\n","import React from 'react';\n\nfunction ArrowLeft(props: React.HTMLAttributes<SVGElement>) {\n return (\n <svg width=\"44\" height=\"44\" viewBox=\"0 0 768 768\" {...props}>\n <path d=\"M640.5 352.5v63h-390l178.5 180-45 45-256.5-256.5 256.5-256.5 45 45-178.5 180h390z\" />\n </svg>\n );\n}\n\nexport default ArrowLeft;\n","import React from 'react';\n\nfunction ArrowRight(props: React.HTMLAttributes<SVGElement>) {\n return (\n <svg width=\"44\" height=\"44\" viewBox=\"0 0 768 768\" {...props}>\n <path d=\"M384 127.5l256.5 256.5-256.5 256.5-45-45 178.5-180h-390v-63h390l-178.5-180z\" />\n </svg>\n );\n}\n\nexport default ArrowRight;\n","import { useEffect } from 'react';\n\nexport default function PreventScroll() {\n useEffect(() => {\n const { style } = document.body;\n const lastOverflow = style.overflow;\n style.overflow = 'hidden';\n\n return () => {\n style.overflow = lastOverflow;\n };\n }, []);\n\n return null;\n}\n","import type React from 'react';\n\n/**\n * 从 Touch 事件中获取两个触控中心位置\n */\nexport default function getMultipleTouchPosition(\n evt: TouchEvent | React.TouchEvent,\n): [clientX: number, clientY: number, touchLength: number] {\n const { clientX, clientY } = evt.touches[0];\n if (evt.touches.length >= 2) {\n const { clientX: nextClientX, clientY: nextClientY } = evt.touches[1];\n return [\n (clientX + nextClientX) / 2,\n (clientY + nextClientY) / 2,\n Math.sqrt((nextClientX - clientX) ** 2 + (nextClientY - clientY) ** 2),\n ];\n }\n return [clientX, clientY, 0];\n}\n","import type { CloseEdgeType, ReachType, TouchStartType } from '../types';\n\n/**\n * 获取接触边缘类型\n */\nexport const getReachType = (\n initialTouchState: TouchStartType,\n horizontalCloseEdge: CloseEdgeType,\n verticalCloseEdge: CloseEdgeType,\n reachPosition: ReachType,\n): ReachType => {\n if ((horizontalCloseEdge && initialTouchState === 1) || reachPosition === 'x') {\n return 'x';\n }\n if ((verticalCloseEdge && initialTouchState > 1) || reachPosition === 'y') {\n return 'y';\n }\n return undefined;\n};\n\n/**\n * 计算接触边缘位置\n * @param position - x/y\n * @param scale\n * @param size - width/height\n * @param innerSize - innerWidth/innerHeight\n * @return [CloseEdgeType, position]\n */\nexport const computePositionEdge = (position: number, scale: number, size: number, innerSize: number) => {\n const currentWidth = size * scale;\n // 图片超出的宽度\n const outOffset = (currentWidth - innerSize) / 2;\n let closedEdge: CloseEdgeType;\n\n let current = position;\n if (currentWidth <= innerSize) {\n closedEdge = 1;\n current = 0;\n } else if (position > 0 && outOffset - position <= 0) {\n closedEdge = 2;\n current = outOffset;\n } else if (position < 0 && outOffset + position <= 0) {\n closedEdge = 3;\n current = -outOffset;\n }\n\n return [closedEdge, current] as const;\n};\n","import { longModeRatio } from '../variables';\nimport { computePositionEdge } from './edgeHandle';\n\n/**\n * 获取移动或缩放之后的中心点\n */\nexport default function getPositionOnMoveOrScale(\n x: number,\n y: number,\n width: number,\n height: number,\n scale: number,\n toScale: number,\n clientX: number = innerWidth / 2,\n clientY: number = innerHeight / 2,\n offsetX: number = 0,\n offsetY: number = 0,\n) {\n // 是否接触边缘\n const [closedEdgeX] = computePositionEdge(x, toScale, width, innerWidth);\n const [closedEdgeY] = computePositionEdge(y, toScale, height, innerHeight);\n\n const centerClientX = innerWidth / 2;\n const centerClientY = innerHeight / 2;\n\n // 坐标偏移\n const lastPositionX = centerClientX + x;\n const lastPositionY = centerClientY + y;\n\n // 偏移位置\n const originX = clientX - (clientX - lastPositionX) * (toScale / scale) - centerClientX;\n const originY = clientY - (clientY - lastPositionY) * (toScale / scale) - centerClientY;\n // 长图模式无左右反馈\n const longModeEdge = height / width >= longModeRatio && width * toScale === innerWidth;\n // 超出边缘距离减半\n return {\n x: originX + (longModeEdge ? 0 : closedEdgeX ? offsetX / 2 : offsetX),\n y: originY + (closedEdgeY ? offsetY / 2 : offsetY),\n lastCX: clientX,\n lastCY: clientY,\n };\n}\n","/**\n * 获取旋转后的宽高\n */\nexport default function getRotateSize(rotate: number, width: number, height: number) {\n const isVertical = rotate % 180 !== 0;\n\n // 若图片不是水平则调换属性\n if (isVertical) {\n return [height, width, isVertical] as const;\n }\n\n return [width, height, isVertical] as const;\n}\n","import { longModeRatio } from '../variables';\nimport getRotateSize from './getRotateSize';\n\n/**\n * 获取图片合适的大小\n */\nexport default function getSuitableImageSize(naturalWidth: number, naturalHeight: number, rotate: number) {\n const [currentWidth, currentHeight, isVertical] = getRotateSize(rotate, innerWidth, innerHeight);\n\n let y = 0;\n let width = currentWidth;\n let height = currentHeight;\n\n // 自适应宽高\n const autoWidth = (naturalWidth / naturalHeight) * currentHeight;\n const autoHeight = (naturalHeight / naturalWidth) * currentWidth;\n\n if (naturalWidth < currentWidth && naturalHeight < currentHeight) {\n width = naturalWidth;\n height = naturalHeight;\n } else if (naturalWidth < currentWidth && naturalHeight >= currentHeight) {\n width = autoWidth;\n } else if (naturalWidth >= currentWidth && naturalHeight < currentHeight) {\n height = autoHeight;\n } else if (naturalWidth / naturalHeight > currentWidth / currentHeight) {\n height = autoHeight;\n }\n // 长图模式\n else if (naturalHeight / naturalWidth >= longModeRatio && !isVertical) {\n height = autoHeight;\n y = (height - currentHeight) / 2;\n } else {\n width = autoWidth;\n }\n return {\n width,\n height,\n x: 0,\n y,\n pause: true,\n };\n}\n","import { useCallback, useRef } from 'react';\n\ninterface DebounceCallback<CallbackArguments extends any[]> {\n (...args: CallbackArguments): void;\n cancel: () => void;\n}\n\nexport default function useDebounceCallback<CallbackArguments extends any[]>(\n callback: (...args: CallbackArguments) => void,\n {\n leading = false,\n maxWait,\n wait = maxWait || 0,\n }: {\n leading?: boolean;\n maxWait?: number;\n wait?: number;\n },\n): DebounceCallback<CallbackArguments> {\n const callbackRef = useRef(callback);\n callbackRef.current = callback;\n\n const prev = useRef(0);\n const trailingTimeout = useRef<ReturnType<typeof setTimeout>>();\n const clearTrailing = () => trailingTimeout.current && clearTimeout(trailingTimeout.current);\n\n const fn = useCallback(\n (...args: CallbackArguments) => {\n const now = Date.now();\n\n function call() {\n prev.current = now;\n clearTrailing();\n callbackRef.current.apply(null, args);\n }\n const last = prev.current;\n const offset = now - last;\n // leading\n if (last === 0) {\n if (leading) {\n call();\n }\n prev.current = now;\n }\n\n // body\n if (maxWait !== undefined) {\n if (offset > maxWait) {\n call();\n return;\n }\n } else if (offset < wait) {\n prev.current = now;\n }\n\n // trailing\n clearTrailing();\n trailingTimeout.current = setTimeout(() => {\n call();\n prev.current = 0;\n }, wait);\n },\n [wait, maxWait, leading],\n );\n (fn as DebounceCallback<CallbackArguments>).cancel = clearTrailing;\n\n return fn as DebounceCallback<CallbackArguments>;\n}\n","import { computePositionEdge } from '../utils/edgeHandle';\nimport getPositionOnMoveOrScale from '../utils/getPositionOnMoveOrScale';\nimport getRotateSize from '../utils/getRotateSize';\nimport { defaultSpeed, maxTouchTime } from '../variables';\nimport useMethods from './useMethods';\n\n// 触边运动反馈\nconst rebound = (start: number, bound: number, callback: (spatial: number) => boolean) =>\n easeOutMove(\n start,\n bound,\n callback,\n defaultSpeed / 4,\n (t) => t,\n () => easeOutMove(bound, start, callback),\n );\n\n/**\n * 物理滚动到具体位置\n */\nexport default function useScrollPosition<C extends (spatial: number) => boolean>(\n callbackX: C,\n callbackY: C,\n callbackS: C,\n) {\n const callback = useMethods({\n X: (spatial: number) => callbackX(spatial),\n Y: (spatial: number) => callbackY(spatial),\n S: (spatial: number) => callbackS(spatial),\n });\n\n return (\n x: number,\n y: number,\n lastX: number,\n lastY: number,\n width: number,\n height: number,\n scale: number,\n safeScale: number,\n lastScale: number,\n rotate: number,\n touchedTime: number,\n ) => {\n const [currentWidth, currentHeight] = getRotateSize(rotate, width, height);\n // 开始状态下边缘触发状态\n const [beginEdgeX, beginX] = computePositionEdge(x, safeScale, currentWidth, innerWidth);\n const [beginEdgeY, beginY] = computePositionEdge(y, safeScale, currentHeight, innerHeight);\n const moveTime = Date.now() - touchedTime;\n\n // 时间过长、超出安全范围的情况下不执行滚动逻辑,恢复安全范围\n if (moveTime >= maxTouchTime || safeScale !== scale || Math.abs(lastScale - scale) > 1) {\n // 计算中心缩放点\n const { x: nextX, y: nextY } = getPositionOnMoveOrScale(x, y, width, height, scale, safeScale);\n const targetX = beginEdgeX ? beginX : nextX !== x ? nextX : null;\n const targetY = beginEdgeY ? beginY : nextY !== y ? nextY : null;\n\n if (targetX !== null) {\n easeOutMove(x, targetX, callback.X);\n }\n if (targetY !== null) {\n easeOutMove(y, targetY, callback.Y);\n }\n if (safeScale !== scale) {\n easeOutMove(scale, safeScale, callback.S);\n }\n return;\n }\n\n // 初始速度\n const speedX = (x - lastX) / moveTime;\n const speedY = (y - lastY) / moveTime;\n const speedT = Math.sqrt(speedX ** 2 + speedY ** 2);\n // 是否接触到边缘\n let edgeX = false;\n let edgeY = false;\n\n scrollMove(speedT, (spatial) => {\n const nextX = x + spatial * (speedX / speedT);\n const nextY = y + spatial * (speedY / speedT);\n\n const [isEdgeX, currentX] = computePositionEdge(nextX, scale, currentWidth, innerWidth);\n const [isEdgeY, currentY] = computePositionEdge(nextY, scale, currentHeight, innerHeight);\n\n if (isEdgeX && !edgeX) {\n edgeX = true;\n if (beginEdgeX) {\n easeOutMove(nextX, currentX, callback.X);\n } else {\n rebound(currentX, nextX + (nextX - currentX), callback.X);\n }\n }\n\n if (isEdgeY && !edgeY) {\n edgeY = true;\n if (beginEdgeY) {\n easeOutMove(nextY, currentY, callback.Y);\n } else {\n rebound(currentY, nextY + (nextY - currentY), callback.Y);\n }\n }\n // 同时接触边缘的情况下停止滚动\n if (edgeX && edgeY) {\n return false;\n }\n\n const resultX = edgeX || callback.X(currentX);\n const resultY = edgeY || callback.Y(currentY);\n return resultX && resultY;\n });\n };\n}\n\n// 加速度\nconst acceleration = -0.001;\n// 阻力\nconst resistance = 0.0002;\n\n/**\n * 通过速度滚动到停止\n */\nfunction scrollMove(initialSpeed: number, callback: (spatial: number) => boolean) {\n let v = initialSpeed;\n let s = 0;\n let lastTime: number | undefined;\n let frameId = 0;\n\n const calcMove = (now: number) => {\n if (!lastTime) {\n lastTime = now;\n }\n const dt = now - lastTime;\n const direction = Math.sign(initialSpeed);\n const a = direction * acceleration;\n const f = Math.sign(-v) * v ** 2 * resistance;\n const ds = v * dt + ((a + f) * dt ** 2) / 2;\n v += (a + f) * dt;\n\n s += ds;\n // move to s\n lastTime = now;\n\n if (direction * v <= 0) {\n caf();\n return;\n }\n\n if (callback(s)) {\n raf();\n return;\n }\n caf();\n };\n raf();\n\n function raf() {\n frameId = requestAnimationFrame(calcMove);\n }\n function caf() {\n cancelAnimationFrame(frameId);\n }\n}\n\n/**\n * 缓动函数\n */\nconst easeOutQuart = (x: number) => 1 - (1 - x) ** 4;\n\n/**\n * 缓动回调\n */\nfunction easeOutMove(\n start: number,\n end: number,\n callback: (spatial: number) => boolean,\n speed = defaultSpeed,\n easing = easeOutQuart,\n complete?: () => void,\n) {\n const distance = end - start;\n if (distance === 0) {\n return;\n }\n\n const startTime = Date.now();\n let frameId = 0;\n\n const calcMove = () => {\n const time = Math.min(1, (Date.now() - startTime) / speed);\n const result = callback(start + easing(time) * distance);\n\n if (result && time < 1) {\n raf();\n return;\n }\n cancelAnimationFrame(frameId);\n if (time >= 1 && complete) {\n complete();\n }\n };\n raf();\n\n function raf() {\n frameId = requestAnimationFrame(calcMove);\n }\n}\n","import type { Dispatch, MutableRefObject, SetStateAction } from 'react';\nimport { useState, useEffect, useRef } from 'react';\nimport type { EasingMode, OriginRectType } from '../types';\nimport useMethods from './useMethods';\nimport { maxWaitAnimationTime } from '../variables';\n\nconst initialRect: OriginRectType = {\n T: 0,\n L: 0,\n W: 0,\n H: 0,\n // 图像填充方式\n FIT: undefined,\n};\n\nexport default function useAnimationOrigin(\n visible: boolean | undefined,\n originRef: MutableRefObject<HTMLElement | null> | undefined,\n loaded: boolean,\n speed: number,\n updateEasing: (pause: boolean) => void,\n): [\n // 动画状态\n easingMode: EasingMode,\n originRect: OriginRectType,\n] {\n const [originRect, updateOriginRect] = useState(initialRect);\n // 动画状态\n const [easingMode, updateEasingMode] = useState<EasingMode>(0);\n const initialTime = useRef<number>();\n\n const fn = useMethods({\n OK: () => visible && updateEasingMode(4),\n });\n\n useEffect(() => {\n // 记录初始打开的时间\n if (!initialTime.current) {\n initialTime.current = Date.now();\n }\n if (!loaded) {\n return;\n }\n handleUpdateOrigin(originRef, updateOriginRect);\n // 打开动画处理\n if (visible) {\n // 小于最大允许动画时间,则执行缩放动画\n if (Date.now() - initialTime.current < maxWaitAnimationTime) {\n updateEasingMode(1);\n // 延时执行动画,保持 transition 生效\n requestAnimationFrame(() => {\n updateEasingMode(2);\n requestAnimationFrame(() => handleToShape(3));\n });\n setTimeout(fn.OK, speed);\n return;\n }\n // 超出则不执行\n updateEasingMode(4);\n return;\n }\n // 关闭动画处理\n handleToShape(5);\n }, [visible, loaded]);\n\n function handleToShape(currentShape: EasingMode) {\n updateEasing(false);\n updateEasingMode(currentShape);\n }\n\n return [easingMode, originRect];\n}\n\n/**\n * 更新缩略图位置信息\n */\nfunction handleUpdateOrigin(\n originRef: MutableRefObject<HTMLElement | null> | undefined,\n updateOriginRect: Dispatch<SetStateAction<typeof initialRect>>,\n) {\n const element = originRef && originRef.current;\n\n if (element && element.nodeType === 1) {\n // 获取触发时节点位置\n const { top, left, width, height } = element.getBoundingClientRect();\n const isImage = element.tagName === 'IMG';\n updateOriginRect({\n T: top,\n L: left,\n W: width,\n H: height,\n FIT: isImage ? (getComputedStyle(element).objectFit as 'contain' | 'cover' | 'fill' | undefined) : undefined,\n });\n }\n}\n","import { useEffect, useRef } from 'react';\n\nconst useMountedRef = () => {\n const mountedRef = useRef(false);\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n return mountedRef;\n};\n\nexport default useMountedRef;\n","import React from 'react';\nimport './Spinner.less';\n\n// eslint-disable-next-line react/prop-types\nfunction Spinner({ className = '', ...props }: React.HTMLAttributes<HTMLElement>) {\n return (\n <div className={`PhotoView__Spinner ${className}`} {...props}>\n <svg viewBox=\"0 0 32 32\" width=\"36\" height=\"36\" fill=\"white\">\n <path opacity=\".25\" d=\"M16 0 A16 16 0 0 0 16 32 A16 16 0 0 0 16 0 M16 4 A12 12 0 0 1 16 28 A12 12 0 0 1 16 4\" />\n <path d=\"M16 0 A16 16 0 0 1 32 16 L28 16 A12 12 0 0 0 16 4z\" />\n </svg>\n </div>\n );\n}\n\nexport default Spinner;\n","import React from 'react';\nimport Spinner from './components/Spinner';\nimport useMountedRef from './hooks/useMountedRef';\nimport type { BrokenElementParams } from './types';\nimport './Photo.less';\n\nexport interface IPhotoLoadedParams {\n loaded?: boolean;\n naturalWidth?: number;\n naturalHeight?: number;\n broken?: boolean;\n}\n\nexport interface IPhotoProps extends React.HTMLAttributes<HTMLElement> {\n src: string;\n loaded: boolean;\n broken: boolean;\n onPhotoLoad: (params: IPhotoLoadedParams) => void;\n loadingElement?: JSX.Element;\n brokenElement?: JSX.Element | ((photoProps: BrokenElementParams) => JSX.Element);\n}\n\nexport default function Photo({\n src,\n loaded,\n broken,\n className,\n onPhotoLoad,\n loadingElement,\n brokenElement,\n ...restProps\n}: IPhotoProps) {\n const mountedRef = useMountedRef();\n\n function handleImageLoaded(e: React.SyntheticEvent<HTMLImageElement>) {\n const { naturalWidth, naturalHeight } = e.target as HTMLImageElement;\n if (mountedRef.current) {\n onPhotoLoad({\n loaded: true,\n naturalWidth,\n naturalHeight,\n });\n }\n }\n\n function handleImageBroken() {\n if (mountedRef.current) {\n onPhotoLoad({\n broken: true,\n });\n }\n }\n\n if (src && !broken) {\n return (\n <>\n <img\n className={`PhotoView__Photo${className ? ` ${className}` : ''}`}\n src={src}\n onLoad={handleImageLoaded}\n onError={handleImageBroken}\n draggable={false}\n alt=\"\"\n {...restProps}\n />\n {!loaded &&\n (loadingElement ? (\n <span className=\"PhotoView__icon\">{loadingElement}</span>\n ) : (\n <Spinner className=\"PhotoView__icon\" />\n ))}\n </>\n );\n }\n\n if (brokenElement) {\n return (\n <span className=\"PhotoView__icon\">\n {typeof brokenElement === 'function' ? brokenElement({ src }) : brokenElement}\n </span>\n );\n }\n\n return null;\n}\n","import React, { useRef } from 'react';\nimport isTouchDevice from './utils/isTouchDevice';\nimport getMultipleTouchPosition from './utils/getMultipleTouchPosition';\nimport getPositionOnMoveOrScale from './utils/getPositionOnMoveOrScale';\nimport { getReachType, computePositionEdge } from './utils/edgeHandle';\nimport getRotateSize from './utils/getRotateSize';\nimport { limitScale } from './utils/limitTarget';\nimport getSuitableImageSize from './utils/getSuitableImageSize';\nimport useIsomorphicLayoutEffect from './hooks/useIsomorphicLayoutEffect';\nimport { minStartTouchOffset, scaleBuffer } from './variables';\nimport type {\n DataType,\n ReachMoveFunction,\n ReachFunction,\n PhotoTapFunction,\n BrokenElementParams,\n ExposedProperties,\n ReachType,\n TouchStartType,\n} from './types';\nimport useSetState from './hooks/useSetState';\nimport useMethods from './hooks/useMethods';\nimport useDebounceCallback from './hooks/useDebounceCallback';\nimport useEventListener from './hooks/useEventListener';\nimport useContinuousTap from './hooks/useContinuousTap';\nimport useScrollPosition from './hooks/useScrollPosition';\nimport useAnimationPosition from './hooks/useAnimationPosition';\nimport useMountedRef from './hooks/useMountedRef';\nimport type { IPhotoLoadedParams } from './Photo';\nimport Photo from './Photo';\nimport './PhotoBox.less';\n\nexport interface PhotoBoxProps {\n // 图片信息\n item: DataType;\n // 是否可见\n visible: boolean;\n // 动画时间\n speed: number;\n // 动画函数\n easing: string;\n // 容器类名\n wrapClassName?: string;\n // 图片类名\n className?: string;\n // style\n style?: object;\n // 自定义 loading\n loadingElement?: JSX.Element;\n // 加载失败 Element\n brokenElement?: JSX.Element | ((photoProps: BrokenElementParams) => JSX.Element);\n\n // Photo 点击事件\n onPhotoTap: PhotoTapFunction;\n // Mask 点击事件\n onMaskTap: PhotoTapFunction;\n // 到达边缘滑动事件\n onReachMove: ReachMoveFunction;\n // 触摸解除事件\n onReachUp: ReachFunction;\n // Resize 事件\n onPhotoResize: () => void;\n // 向父组件导出属性\n expose: (state: ExposedProperties) => void;\n // 是否在当前操作中\n isActive: boolean;\n}\n\nconst initialState = {\n // 真实宽度\n naturalWidth: undefined as number | undefined,\n // 真实高度\n naturalHeight: undefined as number | undefined,\n // 宽度\n width: undefined as number | undefined,\n // 高度\n height: undefined as number | undefined,\n // 加载成功状态\n loaded: undefined as boolean | undefined,\n // 破碎状态\n broken: false,\n\n // 图片 X 偏移量\n x: 0,\n // 图片 y 偏移量\n y: 0,\n // 图片处于触摸的状态\n touched: false,\n // 背景处于触摸状态\n maskTouched: false,\n // 旋转状态\n rotate: 0,\n // 放大缩小\n scale: 1,\n\n // 触摸开始时 x 原始坐标\n CX: 0,\n // 触摸开始时 y 原始坐标\n CY: 0,\n\n // 触摸开始时图片 x 偏移量\n lastX: 0,\n // 触摸开始时图片 y 偏移量\n lastY: 0,\n // 上一个触摸状态 x 原始坐标\n lastCX: 0,\n // 上一个触摸状态 y 原始坐标\n lastCY: 0,\n // 上一个触摸状态的 scale\n lastScale: 1,\n\n // 触摸开始时时间\n touchTime: 0,\n // 多指触控间距\n touchLength: 0,\n // 是否暂停 transition\n pause: true,\n // 停止 Raf\n stopRaf: true,\n // 当前边缘触发状态\n reach: undefined as ReachType,\n};\n\nexport default function PhotoBox({\n item: { src, render, width: customWidth = 0, height: customHeight = 0, originRef },\n visible,\n speed,\n easing,\n wrapClassName,\n className,\n style,\n loadingElement,\n brokenElement,\n\n onPhotoTap,\n onMaskTap,\n onReachMove,\n onReachUp,\n onPhotoResize,\n isActive,\n expose,\n}: PhotoBoxProps) {\n const [state, updateState] = useSetState(initialState);\n const initialTouchRef = useRef<TouchStartType>(0);\n const mounted = useMountedRef();\n\n const {\n naturalWidth = customWidth,\n naturalHeight = customHeight,\n width = customWidth,\n height = customHeight,\n loaded = !src,\n broken,\n x,\n y,\n touched,\n stopRaf,\n maskTouched,\n rotate,\n scale,\n CX,\n CY,\n lastX,\n lastY,\n lastCX,\n lastCY,\n lastScale,\n touchTime,\n touchLength,\n pause,\n reach,\n } = state;\n\n const fn = useMethods({\n onScale: (current: number) => onScale(limitScale(current)),\n onRotate(current: number) {\n if (rotate !== current) {\n expose({ rotate: current });\n updateState({ rotate: current, ...getSuitableImageSize(naturalWidth, naturalHeight, current) });\n }\n },\n });\n\n // 默认为屏幕中心缩放\n function onScale(current: number, clientX?: number, clientY?: number) {\n if (scale !== current) {\n expose({ scale: current });\n updateState({\n scale: current,\n ...getPositionOnMoveOrScale(x, y, width, height, scale, current, clientX, clientY),\n ...(current <= 1 && { x: 0, y: 0 }),\n });\n }\n }\n\n const handleMove = useDebounceCallback(\n (nextClientX: number, nextClientY: number, currentTouchLength: number = 0) => {\n if ((touched || maskTouched) && isActive) {\n // 通过旋转调换宽高\n const [currentWidth, currentHeight] = getRotateSize(rotate, width, height);\n // 单指最小缩放下,以初始移动距离来判断意图\n if (currentTouchLength === 0 && initialTouchRef.current === 0) {\n const isStillX = Math.abs(nextClientX - CX) <= minStartTouchOffset;\n const isStillY = Math.abs(nextClientY - CY) <= minStartTouchOffset;\n // 初始移动距离不足\n if (isStillX && isStillY) {\n // 方向记录上次移动距离,以便平滑过渡\n updateState({ lastCX: nextClientX, lastCY: nextClientY });\n return;\n }\n // 设置响应状态\n initialTouchRef.current = !isStillX ? 1 : nextClientY > CY ? 3 : 2;\n }\n\n const offsetX = nextClientX - lastCX;\n const offsetY = nextClientY - lastCY;\n // 边缘触发状态\n let currentReach: ReachType;\n if (currentTouchLength === 0) {\n // 边缘超出状态\n const [horizontalCloseEdge] = computePositionEdge(offsetX + lastX, scale, currentWidth, innerWidth);\n const [verticalCloseEdge] = computePositionEdge(offsetY + lastY, scale, currentHeight, innerHeight);\n // 边缘触发检测\n currentReach = getReachType(initialTouchRef.current, horizontalCloseEdge, verticalCloseEdge, reach);\n\n // 接触边缘\n if (currentReach !== undefined) {\n onReachMove(currentReach, nextClientX, nextClientY, scale);\n }\n }\n // 横向边缘触发、背景触发禁用当前滑动\n if (currentReach === 'x' || maskTouched) {\n updateState({ reach: 'x' });\n return;\n }\n // 目标倍数\n const toScale = limitScale(\n scale + ((currentTouchLength - touchLength) / 100 / 2) * scale,\n naturalWidth / width,\n scaleBuffer,\n );\n // 导出变量\n expose({ scale: toScale });\n updateState({\n touchLength: currentTouchLength,\n reach: currentReach,\n scale: toScale,\n ...getPositionOnMoveOrScale(x, y, width, height, scale, toScale, nextClientX, nextClientY, offsetX, offsetY),\n });\n }\n },\n {\n maxWait: 8,\n },\n );\n\n function updateRaf(position: { x?: number; y?: number }) {\n if (stopRaf || touched) {\n return false;\n }\n if (mounted.current) {\n // 下拉关闭时可以有动画\n updateState({ ...position, pause: visible });\n }\n return mounted.current;\n }\n\n const slideToPosition = useScrollPosition(\n (nextX) => updateRaf({ x: nextX }),\n (nextY) => updateRaf({ y: nextY }),\n (nextScale) => {\n if (mounted.current) {\n expose({ scale: nextScale });\n updateState({ scale: nextScale });\n }\n return !touched && mounted.current;\n },\n );\n\n const handlePhotoTap = useContinuousTap(onPhotoTap, (currentClientX: number, currentClientY: number) => {\n if (!reach) {\n // 若图片足够大,则放大适应的倍数\n const endScale = scale !== 1 ? 1 : Math.max(2, naturalWidth / width);\n onScale(endScale, currentClientX, currentClientY);\n }\n });\n\n function handleUp(nextClientX: number, nextClientY: number) {\n // 重置响应状态\n initialTouchRef.current = 0;\n if ((touched || maskTouched) && isActive) {\n updateState({\n touched: false,\n maskTouched: false,\n pause: false,\n stopRaf: false,\n reach: undefined,\n });\n const safeScale = limitScale(scale, naturalWidth / width);\n // Go\n slideToPosition(x, y, lastX, lastY, width, height, scale, safeScale, lastScale, rotate, touchTime);\n\n onReachUp(nextClientX, nextClientY);\n // 触发 Tap 事件\n if (CX === nextClientX && CY === nextClientY) {\n if (touched) {\n handlePhotoTap(nextClientX, nextClientY);\n return;\n }\n if (maskTouched) {\n onMaskTap(nextClientX, nextClientY);\n }\n }\n }\n }\n\n useEventListener(isTouchDevice ? undefined : 'mousemove', (e) => {\n e.preventDefault();\n handleMove(e.clientX, e.clientY);\n });\n useEventListener(isTouchDevice ? undefined : 'mouseup', (e) => {\n handleUp(e.clientX, e.clientY);\n });\n useEventListener(\n isTouchDevice ? 'touchmove' : undefined,\n (e) => {\n e.preventDefault();\n const position = getMultipleTouchPosition(e);\n handleMove(...position);\n },\n { passive: false },\n );\n useEventListener(\n isTouchDevice ? 'touchend' : undefined,\n ({ changedTouches }) => {\n const touch = changedTouches[0];\n handleUp(touch.clientX, touch.clientY);\n },\n { passive: false },\n );\n useEventListener(\n 'resize',\n useDebounceCallback(\n () => {\n if (loaded && !touched) {\n updateState(getSuitableImageSize(naturalWidth, naturalHeight, rotate));\n onPhotoResize();\n }\n },\n { maxWait: 8 },\n ),\n );\n\n useIsomorphicLayoutEffect(() => {\n if (isActive) {\n expose({ scale, rotate, ...fn });\n }\n }, [isActive]);\n\n function handlePhotoLoad(params: IPhotoLoadedParams) {\n updateState({\n ...params,\n ...(params.loaded && getSuitableImageSize(params.naturalWidth || 0, params.naturalHeight || 0, rotate)),\n });\n }\n\n function handleStart(currentClientX: number, currentClientY: number, currentTouchLength: number = 0) {\n updateState({\n touched: true,\n CX: currentClientX,\n CY: currentClientY,\n lastCX: currentClientX,\n lastCY: currentClientY,\n lastX: x,\n lastY: y,\n lastScale: scale,\n touchLength: currentTouchLength,\n touchTime: Date.now(),\n });\n }\n\n function handleWheel(e: React.WheelEvent) {\n if (!reach) {\n // 限制最大倍数和最小倍数\n const toScale = limitScale(scale - e.deltaY / 100 / 2, naturalWidth / width);\n updateState({ stopRaf: true });\n onScale(toScale, e.clientX, e.clientY);\n }\n }\n\n function handleMaskStart(e: { clientX: number; clientY: number }) {\n updateState({\n maskTouched: true,\n CX: e.clientX,\n CY: e.clientY,\n lastX: x,\n lastY: y,\n });\n }\n\n function handleTouchStart(e: React.TouchEvent) {\n e.stopPropagation();\n handleStart(...getMultipleTouchPosition(e));\n }\n\n function handleMouseDown(e: React.MouseEvent) {\n e.stopPropagation();\n if (e.button === 0) {\n handleStart(e.clientX, e.clientY, 0);\n }\n }\n\n // 计算位置\n const [translateX, translateY, currentWidth, currentHeight, currentScale, opacity, easingMode, FIT] =\n useAnimationPosition(visible, originRef, loaded, x, y, width, height, scale, speed, (isPause: boolean) =>\n updateState({ pause: isPause }),\n );\n // 图片 objectFit 渐变时间\n const transitionLayoutTime = easingMode < 4 ? speed / 2 : easingMode > 4 ? speed : 0;\n const transitionCSS = `transform ${speed}ms ${easing}`;\n\n const attrs = {\n className,\n onMouseDown: isTouchDevice ? undefined : handleMouseDown,\n onTouchStart: isTouchDevice ? handleTouchStart : undefined,\n onWheel: handleWheel,\n style: {\n width: `${currentWidth}px`,\n height: `${currentHeight}px`,\n opacity,\n objectFit: easingMode === 4 ? undefined : FIT,\n transform: rotate ? `rotate(${rotate}deg)` : undefined,\n transition:\n // 初始状态无渐变\n easingMode > 2\n ? `${transitionCSS}, opacity ${speed}ms ease, height ${transitionLayoutTime}ms ${easing}`\n : undefined,\n },\n };\n\n return (\n <div\n className={`PhotoView__PhotoWrap${wrapClassName ? ` ${wrapClassName}` : ''}`}\n style={style}\n onMouseDown={!isTouchDevice && isActive ? handleMaskStart : undefined}\n onTouchStart={isTouchDevice && isActive ? (e) => handleMaskStart(e.touches[0]) : undefined}\n >\n <div\n className=\"PhotoView__PhotoBox\"\n style={{\n transform: `matrix(${currentScale}, 0, 0, ${currentScale}, ${translateX}, ${translateY})`,\n transition: touched || pause ? undefined : transitionCSS,\n willChange: isActive ? 'transform' : undefined,\n }}\n >\n {src ? (\n <Photo\n src={src}\n loaded={loaded}\n broken={broken}\n {...attrs}\n onPhotoLoad={handlePhotoLoad}\n loadingElement={loadingElement}\n brokenElement={brokenElement}\n />\n ) : (\n render && render({ attrs, scale: currentScale, rotate })\n )}\n </div>\n </div>\n );\n}\n","import { useRef } from 'react';\nimport useDebounceCallback from './useDebounceCallback';\n\nexport type TapFuncType<T> = (...args: T[]) => void;\n\n/**\n * 单击和双击事件处理\n * @param singleTap - 单击事件\n * @param doubleTap - 双击事件\n * @return invokeTap\n */\nexport default function useContinuousTap<T>(singleTap: TapFuncType<T>, doubleTap: TapFuncType<T>): TapFuncType<T> {\n // 当前连续点击次数\n const continuousClick = useRef(0);\n\n const debounceTap = useDebounceCallback(\n (...args) => {\n continuousClick.current = 0;\n singleTap(...args);\n },\n {\n wait: 300,\n },\n );\n\n return function invokeTap(...args) {\n continuousClick.current += 1;\n debounceTap(...args);\n // 双击\n if (continuousClick.current >= 2) {\n debounceTap.cancel();\n continuousClick.current = 0;\n doubleTap(...args);\n }\n };\n}\n","import type { MutableRefObject } from 'react';\nimport useAnimationOrigin from './useAnimationOrigin';\nimport useTargetScale from './useTargetScale';\n\nexport default function useAnimationPosition(\n visible: boolean | undefined,\n originRef: MutableRefObject<HTMLElement | null> | undefined,\n loaded: boolean,\n x: number,\n y: number,\n width: number,\n height: number,\n scale: number,\n speed: number,\n updateEasing: (pause: boolean) => void,\n) {\n // 延迟更新 width/height\n const [autoWidth, autoHeight, autoScale] = useTargetScale(width, height, scale, speed, updateEasing);\n // 动画源处理\n const [easingMode, originRect] = useAnimationOrigin(visible, originRef, loaded, speed, updateEasing);\n\n // 计算动画位置\n const { T, L, W, H, FIT } = originRect;\n // 偏移量,x: 0, y: 0 居中为初始\n const centerWidth = innerWidth / 2;\n const centerHeight = innerHeight / 2;\n const offsetX = centerWidth - (width * scale) / 2;\n const offsetY = centerHeight - (height * scale) / 2;\n // 缩略图状态\n const miniMode = easingMode < 3 || easingMode > 4;\n // 有缩略图时,则为缩略图的位置,否则居中\n const translateX = miniMode ? (W ? L : centerWidth) : x + offsetX;\n const translateY = miniMode ? (W ? T : centerHeight) : y + offsetY;\n\n // 最小值缩放\n const minScale = W / (width * scale) || 0.01;\n\n // 适应 objectFit 保持缩略图宽高比\n const currentHeight = miniMode && FIT ? autoWidth * (H / W) : autoHeight;\n // 初始加载情况无缩放\n const currentScale = easingMode === 0 ? autoScale : miniMode ? minScale : autoScale;\n const opacity = miniMode ? (FIT ? 1 : 0) : 1;\n\n return [translateX, translateY, autoWidth, currentHeight, currentScale, opacity, easingMode, FIT] as const;\n}\n","import { useRef } from 'react';\nimport useSetState from './useSetState';\nimport useIsomorphicLayoutEffect from './useIsomorphicLayoutEffect';\nimport useDebounceCallback from './useDebounceCallback';\n\n/**\n * 目标缩放延迟处理\n */\nexport default function useTargetScale(\n realWidth: number,\n realHeight: number,\n realScale: number,\n speed: number,\n updateEasing: (pause: boolean) => void,\n) {\n const execRef = useRef(false);\n\n const [{ lead, scale }, updateState] = useSetState({ lead: true, scale: realScale });\n\n const moveScale = useDebounceCallback(\n async (current: number) => {\n updateEasing(true);\n updateState({ lead: false, scale: current });\n },\n { wait: speed },\n );\n\n useIsomorphicLayoutEffect(() => {\n if (!execRef.current) {\n execRef.current = true;\n return;\n }\n updateEasing(false);\n updateState({ lead: true });\n\n moveScale(realScale);\n }, [realScale]);\n\n // 运动开始\n if (lead) {\n return [realWidth * scale, realHeight * scale, realScale / scale] as const;\n }\n\n // 运动结束\n return [realWidth * realScale, realHeight * realScale, 1] as const;\n}\n","import React, { useRef, useState } from 'react';\nimport type { DataType, PhotoProviderBase, OverlayRenderProps, ReachType } from './types';\nimport { defaultEasing, defaultSpeed, defaultOpacity, horizontalOffset, maxMoveOffset } from './variables';\nimport isTouchDevice from './utils/isTouchDevice';\nimport { limitNumber } from './utils/limitTarget';\nimport useIsomorphicLayoutEffect from './hooks/useIsomorphicLayoutEffect';\nimport useAdjacentImages from './hooks/useAdjacentImages';\nimport useSetState from './hooks/useSetState';\nimport useEventListener from './hooks/useEventListener';\nimport useAnimationVisible from './hooks/useAnimationVisible';\nimport useMethods from './hooks/useMethods';\nimport SlidePortal from './components/SlidePortal';\nimport CloseIcon from './components/CloseIcon';\nimport ArrowLeft from './components/ArrowLeft';\nimport ArrowRight from './components/ArrowRight';\nimport PreventScroll from './components/PreventScroll';\nimport PhotoBox from './PhotoBox';\nimport './PhotoSlider.less';\n\nexport interface IPhotoSliderProps extends PhotoProviderBase {\n // 图片列表\n images: DataType[];\n // 图片当前索引\n index?: number;\n // 索引改变回调\n onIndexChange?: (index: number) => void;\n // 可见\n visible: boolean;\n // 关闭回调\n onClose: (evt?: React.MouseEvent | React.TouchEvent) => void;\n // 关闭动画结束后回调\n afterClose?: () => void;\n\n direction?: 'ltr' | 'rtl';\n}\n\ntype PhotoSliderState = {\n // 偏移量\n x: number;\n // 图片处于触摸的状态\n touched: boolean;\n // 是否暂停 transition\n pause: boolean;\n // Reach 开始时 x 坐标\n lastCX: number | undefined;\n // Reach 开始时 y 坐标\n lastCY: number | undefined;\n // 背景透明度\n bg: number | null | undefined;\n // 上次关闭的背景透明度\n lastBg: number | null | undefined;\n // 是否显示 overlay\n overlay: boolean;\n // 是否为最小状态,可下拉关闭\n minimal: boolean;\n // 缩放\n scale: number;\n // 旋转\n rotate: number;\n // 缩放回调\n onScale?: (scale: number) => void;\n // 旋转回调\n onRotate?: (rotate: number) => void;\n};\n\nconst initialState: PhotoSliderState = {\n x: 0,\n touched: false,\n pause: false,\n lastCX: undefined,\n lastCY: undefined,\n bg: undefined,\n lastBg: undefined,\n overlay: true,\n minimal: true,\n scale: 1,\n rotate: 0,\n};\n\nexport default function PhotoSlider(props: IPhotoSliderProps) {\n const {\n loop = 3,\n speed: speedFn,\n easing: easingFn,\n photoClosable,\n maskClosable = true,\n maskOpacity = defaultOpacity,\n pullClosable = true,\n bannerVisible = true,\n overlayRender,\n toolbarRender,\n className,\n maskClassName,\n photoClassName,\n photoWrapClassName,\n loadingElement,\n brokenElement,\n images,\n index: controlledIndex = 0,\n onIndexChange: controlledIndexChange,\n visible,\n onClose,\n afterClose,\n portalContainer,\n } = props;\n\n const [state, updateState] = useSetState(initialState);\n const [innerIndex, updateInnerIndex] = useState(0);\n\n const {\n x,\n touched,\n pause,\n\n lastCX,\n lastCY,\n\n bg = maskOpacity,\n lastBg,\n overlay,\n minimal,\n\n scale,\n rotate,\n onScale,\n onRotate,\n } = state;\n\n // 受控 index\n const isControlled = props.hasOwnProperty('index');\n const index = isControlled ? controlledIndex : innerIndex;\n const onIndexChange = isControlled ? controlledIndexChange : updateInnerIndex;\n // 内部虚拟 index\n const virtualIndexRef = useRef(index);\n\n // 当前图片\n const imageLength = images.length;\n const currentImage: DataType | undefined = images[index];\n\n // 是否开启\n // noinspection SuspiciousTypeOfGuard\n const enableLoop = typeof loop === 'boolean' ? loop : imageLength > loop;\n\n // 显示动画处理\n const [realVisible, activeAnimation, onAnimationEnd] = useAnimationVisible(visible, afterClose);\n\n useIsomorphicLayoutEffect(() => {\n // 显示弹出层,修正正确的指向\n if (realVisible) {\n updateState({\n pause: true,\n x: index * -(innerWidth + horizontalOffset),\n });\n virtualIndexRef.current = index;\n return;\n }\n // 关闭后清空状态\n updateState(initialState);\n }, [realVisible]);\n\n const { close, changeIndex } = useMethods({\n close(evt?: React.MouseEvent | React.TouchEvent) {\n if (onRotate) {\n onRotate(0);\n }\n updateState({\n overlay: true,\n // 记录当前关闭时的透明度\n lastBg: bg,\n });\n onClose(evt);\n },\n changeIndex(nextIndex: number, isPause: boolean = false) {\n // 当前索引\n const currentIndex = enableLoop ? virtualIndexRef.current + (nextIndex - index) : nextIndex;\n const max = imageLength - 1;\n // 虚拟 index\n // 非循环模式,限制区间\n const limitIndex = limitNumber(currentIndex, 0, max);\n const nextVirtualIndex = enableLoop ? currentIndex : limitIndex;\n // 单个屏幕宽度\n const singlePageWidth = innerWidth + horizontalOffset;\n\n updateState({\n touched: false,\n lastCX: undefined,\n lastCY: undefined,\n x: -singlePageWidth * nextVirtualIndex,\n pause: isPause,\n });\n\n virtualIndexRef.current = nextVirtualIndex;\n // 更新真实的 index\n const realLoopIndex = nextIndex < 0 ? max : nextIndex > max ? 0 : nextIndex;\n if (onIndexChange) {\n onIndexChange(enableLoop ? realLoopIndex : limitIndex);\n }\n },\n });\n\n useEventListener('keydown', (evt: KeyboardEvent) => {\n if (visible) {\n switch (evt.key) {\n case 'ArrowLeft':\n changeIndex(index - 1, true);\n break;\n case 'ArrowRight':\n changeIndex(index + 1, true);\n break;\n case 'Escape':\n close();\n break;\n default:\n }\n }\n });\n\n function handlePhotoTap(closeable: boolean | undefined) {\n return closeable ? close() : updateState({ overlay: !overlay });\n }\n\n function handleResize() {\n updateState({\n x: -(innerWidth + horizontalOffset) * index,\n lastCX: undefined,\n lastCY: undefined,\n pause: true,\n });\n virtualIndexRef.current = index;\n }\n\n function handleReachVerticalMove(clientY: number, nextScale?: number) {\n if (lastCY === undefined) {\n updateState({\n touched: true,\n lastCY: clientY,\n bg,\n minimal: true,\n });\n return;\n }\n const opacity =\n maskOpacity === null ? null : limitNumber(maskOpacity, 0.01, maskOpacity - Math.abs(clientY - lastCY) / 100 / 4);\n\n updateState({\n touched: true,\n lastCY,\n bg: nextScale === 1 ? opacity : maskOpacity,\n minimal: nextScale === 1,\n });\n }\n\n function handleReachHorizontalMove(clientX: number) {\n if (lastCX === undefined) {\n updateState({\n touched: true,\n lastCX: clientX,\n x,\n pause: false,\n });\n return;\n }\n const originOffsetClientX = clientX - lastCX;\n let offsetClientX = originOffsetClientX;\n\n // 第一张和最后一张超出距离减半\n if (\n !enableLoop &&\n ((index === 0 && originOffsetClientX > 0) || (index === imageLength - 1 && originOffsetClientX < 0))\n ) {\n offsetClientX = originOffsetClientX / 2;\n }\n\n updateState({\n touched: true,\n lastCX,\n x: -(innerWidth + horizontalOffset) * virtualIndexRef.current + offsetClientX,\n pause: false,\n });\n }\n\n function handleReachMove(reachPosition: ReachType, clientX: number, clientY: number, nextScale?: number) {\n if (reachPosition === 'x') {\n handleReachHorizontalMove(clientX);\n } else if (reachPosition === 'y') {\n handleReachVerticalMove(clientY, nextScale);\n }\n }\n\n function handleReachUp(clientX: number, clientY: number) {\n const offsetClientX = clientX - (lastCX ?? clientX);\n const offsetClientY = clientY - (lastCY ?? clientY);\n let willClose = false;\n // 下一张\n if (offsetClientX < -maxMoveOffset) {\n changeIndex(index + 1);\n return;\n }\n // 上一张\n if (offsetClientX > maxMoveOffset) {\n changeIndex(index - 1);\n return;\n }\n const singlePageWidth = innerWidth + horizontalOffset;\n // 当前偏移\n const currentTranslateX = -singlePageWidth * virtualIndexRef.current;\n\n if (Math.abs(offsetClientY) > 100 && minimal && pullClosable) {\n willClose = true;\n close();\n }\n updateState({\n touched: false,\n x: currentTranslateX,\n lastCX: undefined,\n lastCY: undefined,\n bg: maskOpacity,\n overlay: willClose ? true : overlay,\n });\n }\n // 截取相邻的图片\n const adjacentImages = useAdjacentImages(images, index, enableLoop);\n\n if (!realVisible) {\n return null;\n }\n\n const currentOverlayVisible = overlay && !activeAnimation;\n // 关闭过程中使用下拉保存的透明度\n const currentOpacity = visible ? bg : lastBg;\n // 覆盖物参数\n const overlayParams: OverlayRenderProps | undefined = onScale &&\n onRotate && {\n images,\n index,\n visible,\n onClose: close,\n onIndexChange: changeIndex,\n overlayVisible: currentOverlayVisible,\n overlay: currentImage && currentImage.overlay,\n scale,\n rotate,\n onScale,\n onRotate,\n };\n // 动画时间\n const currentSpeed = speedFn ? speedFn(activeAnimation) : defaultSpeed;\n const currentEasing = easingFn ? easingFn(activeAnimation) : defaultEasing;\n const slideSpeed = speedFn ? speedFn(3) : defaultSpeed + 200;\n const slideEasing = easingFn ? easingFn(3) : defaultEasing;\n\n return (\n <SlidePortal\n className={`PhotoView-Portal${!currentOverlayVisible ? ' PhotoView-Slider__clean' : ''}${\n !visible ? ' PhotoView-Slider__willClose' : ''\n }${className ? ` ${className}` : ''}`}\n role=\"dialog\"\n onClick={(e) => e.stopPropagation()}\n container={portalContainer}\n >\n {visible && <PreventScroll />}\n <div\n className={`PhotoView-Slider__Backdrop${maskClassName ? ` ${maskClassName}` : ''}${\n activeAnimation === 1\n ? ' PhotoView-Slider__fadeIn'\n : activeAnimation === 2\n ? ' PhotoView-Slider__fadeOut'\n : ''\n }`}\n style={{\n background: currentOpacity ? `rgba(0, 0, 0, ${currentOpacity})` : undefined,\n transitionTimingFunction: currentEasing,\n transitionDuration: `${touched ? 0 : currentSpeed}ms`,\n animationDuration: `${currentSpeed}ms`,\n }}\n onAnimationEnd={onAnimationEnd}\n />\n {bannerVisible && (\n <div className=\"PhotoView-Slider__BannerWrap\">\n <div className=\"PhotoView-Slider__Counter\">\n {index + 1} / {imageLength}\n </div>\n <div className=\"PhotoView-Slider__BannerRight\">\n {toolbarRender && overlayParams && toolbarRender(overlayParams)}\n <CloseIcon className=\"PhotoView-Slider__toolbarIcon\" onClick={close} />\n </div>\n </div>\n )}\n {adjacentImages.map((item: DataType, currentIndex) => {\n // 截取之前的索引位置\n const nextIndex =\n !enableLoop && index === 0 ? index + currentIndex : virtualIndexRef.current - 1 + currentIndex;\n\n return (\n <PhotoBox\n key={enableLoop ? `${item.key}/${item.src}/${nextIndex}` : item.key}\n item={item}\n speed={currentSpeed}\n easing={currentEasing}\n visible={visible}\n onReachMove={handleReachMove}\n onReachUp={handleReachUp}\n onPhotoTap={() => handlePhotoTap(photoClosable)}\n onMaskTap={() => handlePhotoTap(maskClosable)}\n wrapClassName={photoWrapClassName}\n className={photoClassName}\n style={{\n left: `${(innerWidth + horizontalOffset) * nextIndex}px`,\n transform: `translate3d(${x}px, 0px, 0)`,\n transition: touched || pause ? undefined : `transform ${slideSpeed}ms ${slideEasing}`,\n }}\n loadingElement={loadingElement}\n brokenElement={brokenElement}\n onPhotoResize={handleResize}\n isActive={virtualIndexRef.current === nextIndex}\n expose={updateState}\n />\n );\n })}\n {!isTouchDevice && bannerVisible && (\n <>\n {(enableLoop || index !== 0) && (\n <div className=\"PhotoView-Slider__ArrowLeft\" onClick={() => changeIndex(index - 1, true)}>\n <ArrowLeft />\n </div>\n )}\n {(enableLoop || index + 1 < imageLength) && (\n <div className=\"PhotoView-Slider__ArrowRight\" onClick={() => changeIndex(index + 1, true)}>\n <ArrowRight />\n </div>\n )}\n </>\n )}\n {overlayRender && overlayParams && (\n <div className=\"PhotoView-Slider__Overlay\">{overlayRender(overlayParams)}</div>\n )}\n </SlidePortal>\n );\n}\n","import { useReducer, useRef } from 'react';\nimport type { ActiveAnimationType } from '../types';\nimport useForkedVariable from './useForkedVariable';\n\n/**\n * 动画关闭处理真实关闭状态\n * 通过 onAnimationEnd 回调实现 leaveCallback\n */\nexport default function useAnimationVisible(\n visible: boolean | undefined,\n afterClose?: () => void,\n): [realVisible: boolean | undefined, activeAnimation: ActiveAnimationType, onAnimationEnd: () => void] {\n const [, handleRender] = useReducer((c) => !c, false);\n\n const activeAnimation = useRef<ActiveAnimationType>(0);\n\n // 可见状态分支\n const [realVisible, modifyRealVisible] = useForkedVariable(visible, (modify) => {\n // 可见状态:设置进入动画\n if (visible) {\n modify(visible);\n activeAnimation.current = 1;\n } else {\n activeAnimation.current = 2;\n }\n });\n\n function onAnimationEnd() {\n // 动画结束后触发渲染\n handleRender();\n // 结束动画:设置隐藏状态\n if (activeAnimation.current === 2) {\n modifyRealVisible(false);\n // 触发隐藏回调\n if (afterClose) {\n afterClose();\n }\n }\n // 重置状态\n activeAnimation.current = 0;\n }\n\n return [\n /**\n * 真实可见状态\n */\n realVisible,\n /**\n * 正在进行的动画\n */\n activeAnimation.current,\n /**\n * 动画结束后回调\n */\n onAnimationEnd,\n ];\n}\n","import { useRef, useMemo } from 'react';\n\n/**\n * 逻辑分叉变量处理\n * 此 hook 不触发额外渲染\n */\nexport default function useForkedVariable<T>(initial: T, updater: (modify: (variable: T) => void) => void) {\n // 初始分叉变量\n const forkedRef = useRef(initial);\n\n function modify(next: T) {\n forkedRef.current = next;\n }\n\n useMemo(() => {\n // 参数变化之后同步内部分叉变量\n updater(modify);\n }, [initial]);\n\n return [forkedRef.current, modify] as const;\n}\n","import { useMemo } from 'react';\nimport type { DataType } from '../types';\n\n/**\n * 截取相邻三张图片\n */\nexport default function useAdjacentImages(images: DataType[], index: number, loop: boolean) {\n return useMemo(() => {\n const imageLength = images.length;\n if (loop) {\n const connected = images.concat(images).concat(images);\n return connected.slice(imageLength + index - 1, imageLength + index + 2);\n }\n return images.slice(Math.max(index - 1, 0), Math.min(index + 2, imageLength + 1));\n }, [images, index, loop]);\n}\n","import React, { useMemo, useRef } from 'react';\nimport type { DataType, PhotoProviderBase } from './types';\nimport useMethods from './hooks/useMethods';\nimport useSetState from './hooks/useSetState';\nimport PhotoContext from './photo-context';\nimport PhotoSlider from './PhotoSlider';\n\nexport interface PhotoProviderProps extends PhotoProviderBase {\n children: React.ReactNode;\n onIndexChange?: (index: number, state: PhotoProviderState) => void;\n onVisibleChange?: (visible: boolean, index: number, state: PhotoProviderState) => void;\n}\n\ntype PhotoProviderState = {\n images: DataType[];\n visible: boolean;\n index: number;\n};\n\nconst initialState: PhotoProviderState = {\n images: [],\n visible: false,\n index: 0,\n};\n\nexport default function PhotoProvider({ children, onIndexChange, onVisibleChange, ...restProps }: PhotoProviderProps) {\n const [state, updateState] = useSetState(initialState);\n const uniqueIdRef = useRef(0);\n const { images, visible, index } = state;\n\n const methods = useMethods({\n nextId() {\n return (uniqueIdRef.current += 1);\n },\n update(imageItem: DataType) {\n const currentIndex = images.findIndex((n) => n.key === imageItem.key);\n if (currentIndex > -1) {\n const nextImages = images.slice();\n nextImages.splice(currentIndex, 1, imageItem);\n updateState({\n images: nextImages,\n });\n return;\n }\n updateState((prev) => ({\n images: prev.images.concat(imageItem),\n }));\n },\n remove(key: number) {\n updateState((prev) => {\n const nextImages = prev.images.filter((item) => item.key !== key);\n const nextEndIndex = nextImages.length - 1;\n return {\n images: nextImages,\n index: Math.min(nextEndIndex, index),\n };\n });\n },\n show(key: number) {\n const currentIndex = images.findIndex((item) => item.key === key);\n updateState({\n visible: true,\n index: currentIndex,\n });\n if (onVisibleChange) {\n onVisibleChange(true, currentIndex, state);\n }\n },\n });\n\n const fn = useMethods({\n close() {\n updateState({\n visible: false,\n });\n\n if (onVisibleChange) {\n onVisibleChange(false, index, state);\n }\n },\n changeIndex(nextIndex: number) {\n updateState({\n index: nextIndex,\n });\n\n if (onIndexChange) {\n onIndexChange(nextIndex, state);\n }\n },\n });\n\n const value = useMemo(() => ({ ...state, ...methods }), [state, methods]);\n\n return (\n <PhotoContext.Provider value={value}>\n {children}\n <PhotoSlider\n images={images}\n visible={visible}\n index={index}\n onIndexChange={fn.changeIndex}\n onClose={fn.close}\n {...restProps}\n />\n </PhotoContext.Provider>\n );\n}\n","import type React from 'react';\nimport { useImperativeHandle, Children, cloneElement, useContext, useEffect, useMemo, useRef } from 'react';\nimport useInitial from './hooks/useInitial';\nimport useMethods from './hooks/useMethods';\nimport type { PhotoContextType } from './photo-context';\nimport PhotoContext from './photo-context';\nimport type { PhotoRenderParams } from './types';\n\nexport interface PhotoViewProps {\n /**\n * 图片地址\n */\n src?: string;\n /**\n * 自定义渲染,优先级比 src 低\n */\n render?: (props: PhotoRenderParams) => React.ReactNode;\n /**\n * 自定义覆盖节点\n */\n overlay?: React.ReactNode;\n /**\n * 自定义渲染节点宽度\n */\n width?: number;\n /**\n * 自定义渲染节点高度\n */\n height?: number;\n /**\n * 子节点,一般为缩略图\n */\n children?: React.ReactElement;\n /**\n * 触发的事件\n */\n triggers?: ('onClick' | 'onDoubleClick')[];\n}\n\nconst PhotoView: React.FC<PhotoViewProps> = ({\n src,\n render,\n overlay,\n width,\n height,\n triggers = ['onClick'],\n children,\n}) => {\n const photoContext = useContext<PhotoContextType>(PhotoContext);\n const key = useInitial(() => photoContext.nextId());\n const originRef = useRef<HTMLElement>(null);\n\n useImperativeHandle((children as React.FunctionComponentElement<HTMLElement>)?.ref, () => originRef.current);\n\n useEffect(() => {\n return () => {\n photoContext.remove(key);\n };\n }, []);\n\n function invokeChildrenFn(eventName: string, e: React.SyntheticEvent) {\n if (children) {\n const eventFn = children.props[eventName];\n if (eventFn) {\n eventFn(e);\n }\n }\n }\n\n const fn = useMethods({\n render(props: PhotoRenderParams) {\n return render && render(props);\n },\n show(eventName: string, e: React.MouseEvent) {\n photoContext.show(key);\n invokeChildrenFn(eventName, e);\n },\n });\n\n const eventListeners = useMemo(() => {\n const listener = {};\n triggers.forEach((eventName) => {\n listener[eventName] = fn.show.bind(null, eventName);\n });\n return listener;\n }, []);\n\n useEffect(() => {\n photoContext.update({\n key,\n src,\n originRef,\n render: fn.render,\n overlay,\n width,\n height,\n });\n }, [src]);\n\n if (children) {\n return Children.only(cloneElement(children, { ...eventListeners, ref: originRef }));\n }\n return null;\n};\n\nexport default PhotoView;\n","import { useRef } from 'react';\n\nexport default function useInitial<T extends (...args: any) => any>(callback: T) {\n const { current } = useRef({ sign: false, fn: undefined as ReturnType<T> });\n if (!current.sign) {\n current.sign = true;\n current.fn = callback();\n }\n return current.fn;\n}\n"],"names":["useMethods","fn","current","useRef","curr","undefined","Object","create","keys","forEach","key","args","call","useSetState","initialState","useReducer","state","action","_extends","createContext","defaultEasing","horizontalOffset","defaultOpacity","isTouchDevice","window","limitNumber","value","min","max","Math","limitScale","scale","buffer","test","navigator","userAgent","useEffect","useLayoutEffect","useEventListener","type","options","latest","wrapper","evt","addEventListener","removeEventListener","SlidePortal","_ref","container","document","body","rest","_objectWithoutPropertiesLoose","_excluded","createPortal","React","createElement","CloseIcon","props","width","height","viewBox","d","ArrowLeft","ArrowRight","PreventScroll","style","lastOverflow","overflow","getMultipleTouchPosition","clientX","clientY","touches","length","nextClientX","nextClientY","sqrt","computePositionEdge","position","size","innerSize","currentWidth","outOffset","closedEdge","getPositionOnMoveOrScale","x","y","toScale","innerWidth","innerHeight","offsetX","offsetY","closedEdgeX","closedEdgeY","centerClientX","centerClientY","lastCX","lastCY","getRotateSize","rotate","isVertical","getSuitableImageSize","naturalWidth","naturalHeight","currentHeight","autoWidth","autoHeight","pause","useDebounceCallback","callback","leading","maxWait","wait","callbackRef","prev","trailingTimeout","clearTrailing","clearTimeout","useCallback","now","Date","apply","last","offset","setTimeout","cancel","rebound","start","bound","easeOutMove","defaultSpeed","t","easeOutQuart","end","speed","easing","complete","distance","startTime","frameId","calcMove","time","raf","cancelAnimationFrame","requestAnimationFrame","initialRect","T","L","W","H","FIT","useMountedRef","mountedRef","Spinner","className","fill","opacity","Photo","src","loaded","broken","onPhotoLoad","loadingElement","brokenElement","restProps","Fragment","onLoad","e","target","onError","draggable","alt","touched","maskTouched","CX","CY","lastX","lastY","lastScale","touchTime","touchLength","stopRaf","reach","PhotoBox","item","render","customWidth","customHeight","originRef","visible","wrapClassName","onPhotoTap","onMaskTap","onReachMove","onReachUp","onPhotoResize","isActive","expose","updateState","initialTouchRef","mounted","onScale","onRotate","handleMove","currentTouchLength","isStillX","abs","isStillY","currentReach","horizontalCloseEdge","verticalCloseEdge","getReachType","initialTouchState","reachPosition","updateRaf","slideToPosition","X","spatial","Y","S","callbackS","nextScale","safeScale","touchedTime","beginEdgeX","beginX","beginEdgeY","beginY","moveTime","nextX","nextY","targetX","targetY","speedX","speedY","speedT","edgeX","edgeY","initialSpeed","lastTime","v","s","dt","direction","sign","a","f","ds","caf","scrollMove","isEdgeX","currentX","isEdgeY","currentY","resultX","resultY","useScrollPosition","handlePhotoTap","singleTap","continuousClick","debounceTap","currentClientX","currentClientY","doubleTap","useContinuousTap","handleUp","handleStart","handleMaskStart","preventDefault","passive","changedTouches","touch","useIsomorphicLayoutEffect","translateX","translateY","currentScale","easingMode","updateEasing","autoScale","realWidth","realHeight","realScale","execRef","lead","moveScale","async","useTargetScale","originRect","updateOriginRect","useState","updateEasingMode","initialTime","OK","handleToShape","currentShape","element","nodeType","top","left","getBoundingClientRect","tagName","getComputedStyle","objectFit","handleUpdateOrigin","useAnimationOrigin","centerWidth","centerHeight","miniMode","useAnimationPosition","isPause","transitionCSS","attrs","onMouseDown","stopPropagation","button","onTouchStart","onWheel","deltaY","transform","transition","willChange","params","bg","lastBg","overlay","minimal","PhotoSlider","loop","speedFn","easingFn","photoClosable","maskClosable","maskOpacity","pullClosable","bannerVisible","overlayRender","toolbarRender","maskClassName","photoClassName","photoWrapClassName","images","index","controlledIndex","onIndexChange","controlledIndexChange","onClose","afterClose","portalContainer","innerIndex","updateInnerIndex","isControlled","hasOwnProperty","virtualIndexRef","imageLength","currentImage","enableLoop","realVisible","activeAnimation","onAnimationEnd","handleRender","c","modifyRealVisible","initial","forkedRef","modify","next","useMemo","updater","useForkedVariable","useAnimationVisible","close","changeIndex","nextIndex","currentIndex","limitIndex","nextVirtualIndex","singlePageWidth","closeable","handleResize","handleReachMove","originOffsetClientX","offsetClientX","handleReachHorizontalMove","handleReachVerticalMove","handleReachUp","offsetClientY","willClose","currentTranslateX","adjacentImages","concat","slice","useAdjacentImages","currentOverlayVisible","currentOpacity","overlayParams","overlayVisible","currentSpeed","currentEasing","slideSpeed","slideEasing","role","onClick","background","transitionTimingFunction","transitionDuration","animationDuration","map","PhotoProvider","children","onVisibleChange","uniqueIdRef","methods","nextId","update","imageItem","findIndex","n","nextImages","splice","remove","filter","show","PhotoContext","Provider","PhotoView","triggers","photoContext","useContext","useInitial","useImperativeHandle","ref","eventName","eventFn","invokeChildrenFn","eventListeners","listener","bind","Children","only","cloneElement"],"mappings":"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"}