From 72dd485dfde3ad1cc1ba2a64c634aaa563efb748 Mon Sep 17 00:00:00 2001 From: thomasvo Date: Fri, 10 Jan 2025 13:44:35 -0800 Subject: [PATCH 1/4] fix --- lib/commonjs/ReactNativeZoomableView.js | 42 ++++++++------- lib/commonjs/ReactNativeZoomableView.js.map | 2 +- lib/module/ReactNativeZoomableView.js | 42 ++++++++------- lib/module/ReactNativeZoomableView.js.map | 2 +- lib/typescript/ReactNativeZoomableView.d.ts | 7 +-- src/ReactNativeZoomableView.tsx | 60 +++++++++++---------- 6 files changed, 83 insertions(+), 72 deletions(-) diff --git a/lib/commonjs/ReactNativeZoomableView.js b/lib/commonjs/ReactNativeZoomableView.js index fbff7d3..4ce481f 100644 --- a/lib/commonjs/ReactNativeZoomableView.js +++ b/lib/commonjs/ReactNativeZoomableView.js @@ -971,37 +971,41 @@ class ReactNativeZoomableView extends _react.Component { * { x: 0, y: 0 } is the very center of the zoom subject. * * @param newZoomLevel - * @param zoomCenter relative coords compared to the zoom subject. Default to the center. + * @param zoomCenter */ - zoomTo(newZoomLevel, zoomCenter = { - x: 0, - y: 0 - }) { + zoomTo(newZoomLevel, zoomCenter) { var _this$props$onZoomBef, _this$props17, _this$props$onZoomAft2, _this$props18; if (!this.props.zoomEnabled) return false; if (this.props.maxZoom && newZoomLevel > this.props.maxZoom) return false; if (this.props.minZoom && newZoomLevel < this.props.minZoom) return false; - (_this$props$onZoomBef = (_this$props17 = this.props).onZoomBefore) === null || _this$props$onZoomBef === void 0 ? void 0 : _this$props$onZoomBef.call(_this$props17, null, null, this._getZoomableViewEventObject()); // == Perform Zoom Animation == - // Calculates panAnim values based on changes in zoomAnim. + (_this$props$onZoomBef = (_this$props17 = this.props).onZoomBefore) === null || _this$props$onZoomBef === void 0 ? void 0 : _this$props$onZoomBef.call(_this$props17, null, null, this._getZoomableViewEventObject()); // == Perform Pan Animation to preserve the zoom center while zooming == - let prevScale = this.zoomLevel; // Since zoomAnim is calculated in native driver, - // it will jitter panAnim once in a while, - // because here panAnim is being calculated in js. - // However the jittering should mostly occur in simulator. + let listenerId; - const listenerId = this.zoomAnim.addListener(({ - value: newScale - }) => { - this.panAnim.setValue({ - x: (0, _helper.calcNewScaledOffsetForZoomCentering)(this.offsetX, this.state.originalWidth, prevScale, newScale, zoomCenter.x), - y: (0, _helper.calcNewScaledOffsetForZoomCentering)(this.offsetY, this.state.originalHeight, prevScale, newScale, zoomCenter.y) + if (zoomCenter) { + // Calculates panAnim values based on changes in zoomAnim. + let prevScale = this.zoomLevel; // Since zoomAnim is calculated in native driver, + // it will jitter panAnim once in a while, + // because here panAnim is being calculated in js. + // However the jittering should mostly occur in simulator. + + listenerId = this.zoomAnim.addListener(({ + value: newScale + }) => { + this.panAnim.setValue({ + x: (0, _helper.calcNewScaledOffsetForZoomCentering)(this.offsetX, this.state.originalWidth, prevScale, newScale, zoomCenter.x), + y: (0, _helper.calcNewScaledOffsetForZoomCentering)(this.offsetY, this.state.originalHeight, prevScale, newScale, zoomCenter.y) + }); + prevScale = newScale; }); - prevScale = newScale; - }); + } // == Perform Zoom Animation == + + (0, _animations.getZoomToAnimation)(this.zoomAnim, newZoomLevel).start(() => { + if (!listenerId) return; this.zoomAnim.removeListener(listenerId); }); // == Zoom Animation Ends == diff --git a/lib/commonjs/ReactNativeZoomableView.js.map b/lib/commonjs/ReactNativeZoomableView.js.map index 4d4796a..f9547bd 100644 --- a/lib/commonjs/ReactNativeZoomableView.js.map +++ b/lib/commonjs/ReactNativeZoomableView.js.map @@ -1 +1 @@ -{"version":3,"sources":["ReactNativeZoomableView.tsx"],"names":["initialState","originalWidth","originalHeight","originalPageX","originalPageY","pinSize","width","height","ReactNativeZoomableView","Component","gestureStarted","v","_gestureStarted","constructor","props","Animated","ValueXY","x","y","Value","value","boundaryCrossedAnimInEffect","position","onStaticPinPositionChange","requestAnimationFrame","setTimeout","zoomSubjectWrapperRef","current","measureInWindow","state","setState","e","gestureState","onStartShouldSetPanResponder","_getZoomableViewEventObject","onLongPress","longPressTimeout","longPressDuration","onPanResponderGrant","panAnim","stopAnimation","zoomAnim","raisePin","gestureType","_resolveAndHandleTap","debugPoints","lastGestureCenterPosition","disableMomentum","panEnabled","disablePanOnInitialZoom","zoomLevel","initialZoom","vx","vy","start","clearTimeout","onPanResponderEnd","onZoomEnd","onShiftingEnd","staticPinPosition","_updateStaticPin","dropPin","onPanResponderMove","numberActiveTouches","_handlePanResponderGrant","_handlePanResponderEnd","lastGestureTouchDistance","_handlePinching","Math","abs","dx","dy","isShiftGesture","_handleShifting","now","Date","doubleTapFirstTapReleaseTimestamp","doubleTapDelay","doubleTapFirstTap","_addTouch","id","toString","isSecondTap","singleTapTimeoutId","_handleDoubleTap","nativeEvent","pageX","pageY","persist","tapX","tapY","timing","toValue","offsetX","offsetY","useNativeDriver","duration","onSingleTap","contentWidth","contentHeight","pinX","pinY","setValue","viewportPosition","imageSize","zoomableEvent","_staticPinPosition","gestureHandlers","PanResponder","create","_handleStartShouldSetPanResponder","_handlePanResponderMove","onPanResponderRelease","onPanResponderTerminate","evt","onPanResponderTerminationRequest","onShouldBlockNativeResponder","onStartShouldSetPanResponderCapture","onMoveShouldSetPanResponderCapture","zoomAnimatedValue","panAnimatedValueXY","initialOffsetX","initialOffsetY","addListener","animatePin","pinAnim","easing","Easing","out","ease","__setOffset","__getOffset","axis","offset","offsetState","__offsets","bindToBorders","containerSize","contentSize","boundOffset","panBoundaryPadding","boundariesApplied","toFixed","componentDidUpdate","prevProps","prevState","zoomEnabled","onTransformInvocationInitialized","_invokeOnTransform","successful","currState","originalMeasurementsChanged","staticPinPositionChanged","componentDidMount","grabZoomSubjectOriginalMeasurements","measureZoomSubjectInterval","setInterval","componentWillUnmount","clearInterval","zoomableViewEvent","onTransform","onStaticPinPositionMove","debouncedOnStaticPinPositionChange","overwriteObj","maxZoom","minZoom","pinchToZoomInSensitivity","pinchToZoomOutSensitivity","distance","onZoomBefore","zoomGrowthFromLastGestureState","pinchToZoomSensitivity","deltaGrowth","deltaGrowthAdjustedBySensitivity","newZoomLevel","gestureCenterPoint","zoomCenter","debug","_setPinchDebugPoints","oldOffsetX","oldOffsetY","oldScale","newScale","offsetShift","_calcOffsetShiftSinceLastGestureState","onZoomAfter","gestureResponderEvent","points","touches","movementSensibility","shift","shiftX","shiftY","moveX","moveY","_setNewOffsetPosition","newOffsetX","newOffsetY","onShiftingBefore","onShiftingAfter","touch","push","_removeTouch","splice","indexOf","onDoubleTapBefore","onDoubleTapAfter","doubleTapZoomToCenter","nextZoomStep","_getNextZoomStep","zoomPositionCoordinates","zoomTo","zoomStep","prevScale","listenerId","removeListener","zoomBy","zoomLevelChange","moveTo","moveBy","offsetChangeX","offsetChangeY","render","staticPinIcon","children","visualTouchFeedbackEnabled","onStaticPinLongPress","onStaticPinPress","pinProps","styles","container","panHandlers","event","onLayout","zoomSubject","style","transform","scale","getTranslateTransform","map","index","size","undefined","StyleSheet","alignItems","flex","justifyContent","overflow"],"mappings":"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","sourcesContent":["import React, { Component, createRef, RefObject } from 'react';\nimport {\n Animated,\n Easing,\n GestureResponderEvent,\n PanResponder,\n PanResponderCallbacks,\n PanResponderGestureState,\n PanResponderInstance,\n StyleSheet,\n View,\n} from 'react-native';\n\nimport {\n Vec2D,\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState,\n TouchPoint,\n ZoomableViewEvent,\n Size2D,\n} from './typings';\n\nimport { AnimatedTouchFeedback } from './components';\nimport { DebugTouchPoint } from './debugHelper';\nimport {\n calcGestureCenterPoint,\n calcGestureTouchDistance,\n calcNewScaledOffsetForZoomCentering,\n} from './helper';\nimport { applyPanBoundariesToOffset } from './helper/applyPanBoundariesToOffset';\nimport { viewportPositionToImagePosition } from './helper/coordinateConversion';\nimport { StaticPin } from './components/StaticPin';\nimport { debounce } from 'lodash';\nimport {\n getBoundaryCrossedAnim,\n getPanMomentumDecayAnim,\n getZoomToAnimation,\n} from './animations';\n\nconst initialState: ReactNativeZoomableViewState = {\n originalWidth: 0,\n originalHeight: 0,\n originalPageX: 0,\n originalPageY: 0,\n pinSize: { width: 0, height: 0 },\n};\n\nclass ReactNativeZoomableView extends Component<\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState\n> {\n zoomSubjectWrapperRef: RefObject;\n gestureHandlers: PanResponderInstance;\n doubleTapFirstTapReleaseTimestamp: number | undefined;\n\n static defaultProps = {\n zoomEnabled: true,\n panEnabled: true,\n initialZoom: 1,\n initialOffsetX: 0,\n initialOffsetY: 0,\n maxZoom: 1.5,\n minZoom: 0.5,\n pinchToZoomInSensitivity: 1,\n pinchToZoomOutSensitivity: 1,\n movementSensibility: 1,\n doubleTapDelay: 300,\n bindToBorders: true,\n zoomStep: 0.5,\n onLongPress: null,\n longPressDuration: 700,\n contentWidth: undefined,\n contentHeight: undefined,\n panBoundaryPadding: 0,\n visualTouchFeedbackEnabled: true,\n staticPinPosition: undefined,\n staticPinIcon: undefined,\n onStaticPinPositionChange: undefined,\n onStaticPinPositionMove: undefined,\n animatePin: true,\n disablePanOnInitialZoom: false,\n };\n\n private panAnim = new Animated.ValueXY({ x: 0, y: 0 });\n private zoomAnim = new Animated.Value(1);\n private pinAnim = new Animated.ValueXY({ x: 0, y: 0 });\n\n private __offsets = {\n x: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n y: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n };\n\n private zoomLevel = 1;\n private lastGestureCenterPosition: { x: number; y: number } | null = null;\n private lastGestureTouchDistance: number | null = null;\n private gestureType: 'pinch' | 'shift' | null;\n\n private _gestureStarted = false;\n private set gestureStarted(v: boolean) {\n this._gestureStarted = v;\n }\n\n public get gestureStarted() {\n return this._gestureStarted;\n }\n\n /**\n * Last press time (used to evaluate whether user double tapped)\n * @type {number}\n */\n private longPressTimeout: NodeJS.Timeout | null = null;\n private onTransformInvocationInitialized: boolean | undefined;\n private singleTapTimeoutId: NodeJS.Timeout | undefined;\n private touches: TouchPoint[] = [];\n private doubleTapFirstTap: TouchPoint | undefined;\n private measureZoomSubjectInterval: NodeJS.Timer | undefined;\n\n constructor(props: ReactNativeZoomableViewProps) {\n super(props);\n // This needs to be done before anything else to initialize the state.\n // Otherwise, the logic below may reference the state when it's undefined,\n // causing runtime errors.\n this.state = { ...initialState };\n\n this.gestureHandlers = PanResponder.create({\n onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,\n onPanResponderGrant: this._handlePanResponderGrant,\n onPanResponderMove: this._handlePanResponderMove,\n onPanResponderRelease: this._handlePanResponderEnd,\n onPanResponderTerminate: (evt, gestureState) => {\n // We should also call _handlePanResponderEnd\n // to properly perform cleanups when the gesture is terminated\n // (aka gesture handling responsibility is taken over by another component).\n // This also fixes a weird issue where\n // on real device, sometimes onPanResponderRelease is not called when you lift 2 fingers up,\n // but onPanResponderTerminate is called instead for no apparent reason.\n this._handlePanResponderEnd(evt, gestureState);\n this.props.onPanResponderTerminate?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n );\n },\n onPanResponderTerminationRequest: (evt, gestureState) =>\n !!this.props.onPanResponderTerminationRequest?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ),\n // Defaults to true to prevent parent components, such as React Navigation's tab view, from taking over as responder.\n onShouldBlockNativeResponder: (evt, gestureState) =>\n this.props.onShouldBlockNativeResponder?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ) ?? true,\n onStartShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onStartShouldSetPanResponderCapture?.(evt, gestureState),\n onMoveShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onMoveShouldSetPanResponderCapture?.(evt, gestureState),\n });\n\n this.zoomSubjectWrapperRef = createRef();\n\n if (this.props.zoomAnimatedValue)\n this.zoomAnim = this.props.zoomAnimatedValue;\n if (this.props.panAnimatedValueXY)\n this.panAnim = this.props.panAnimatedValueXY;\n\n if (this.props.initialZoom) this.zoomLevel = this.props.initialZoom;\n if (this.props.initialOffsetX != null)\n this.offsetX = this.props.initialOffsetX;\n if (this.props.initialOffsetY != null)\n this.offsetY = this.props.initialOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n this.panAnim.addListener(({ x, y }) => {\n this.offsetX = x;\n this.offsetY = y;\n });\n this.zoomAnim.addListener(({ value }) => {\n this.zoomLevel = value;\n });\n\n this.lastGestureTouchDistance = 150;\n\n this.gestureType = null;\n }\n\n private raisePin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: -10 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private dropPin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: 0 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private set offsetX(x: number) {\n this.__setOffset('x', x);\n }\n\n private set offsetY(y: number) {\n this.__setOffset('y', y);\n }\n\n private get offsetX() {\n return this.__getOffset('x');\n }\n\n private get offsetY() {\n return this.__getOffset('y');\n }\n\n private __setOffset(axis: 'x' | 'y', offset: number) {\n const offsetState = this.__offsets[axis];\n\n if (this.props.bindToBorders) {\n const containerSize =\n axis === 'x' ? this.state.originalWidth : this.state.originalHeight;\n const contentSize =\n axis === 'x'\n ? this.props.contentWidth || this.state.originalWidth\n : this.props.contentHeight || this.state.originalHeight;\n\n const boundOffset =\n contentSize && containerSize && this.props.panBoundaryPadding != null\n ? applyPanBoundariesToOffset(\n offset,\n containerSize,\n contentSize,\n this.zoomLevel,\n this.props.panBoundaryPadding\n )\n : offset;\n\n if (!this.gestureType && !offsetState.boundaryCrossedAnimInEffect) {\n const boundariesApplied =\n boundOffset !== offset &&\n boundOffset.toFixed(3) !== offset.toFixed(3);\n if (boundariesApplied) {\n offsetState.boundaryCrossedAnimInEffect = true;\n getBoundaryCrossedAnim(this.panAnim[axis], boundOffset).start(() => {\n offsetState.boundaryCrossedAnimInEffect = false;\n });\n return;\n }\n }\n }\n\n offsetState.value = offset;\n }\n\n private __getOffset(axis: 'x' | 'y') {\n return this.__offsets[axis].value;\n }\n\n componentDidUpdate(\n prevProps: ReactNativeZoomableViewProps,\n prevState: ReactNativeZoomableViewState\n ) {\n const { zoomEnabled, initialZoom } = this.props;\n if (prevProps.zoomEnabled && !zoomEnabled && initialZoom) {\n this.zoomLevel = initialZoom;\n this.zoomAnim.setValue(this.zoomLevel);\n }\n if (\n !this.onTransformInvocationInitialized &&\n this._invokeOnTransform().successful\n ) {\n this.panAnim.addListener(() => this._invokeOnTransform());\n this.zoomAnim.addListener(() => this._invokeOnTransform());\n this.onTransformInvocationInitialized = true;\n }\n\n const currState = this.state;\n const originalMeasurementsChanged =\n currState.originalHeight !== prevState.originalHeight ||\n currState.originalWidth !== prevState.originalWidth ||\n currState.originalPageX !== prevState.originalPageX ||\n currState.originalPageY !== prevState.originalPageY;\n\n const staticPinPositionChanged =\n prevProps.staticPinPosition?.x !== this.props.staticPinPosition?.x ||\n prevProps.staticPinPosition?.y !== this.props.staticPinPosition?.y;\n\n if (\n this.onTransformInvocationInitialized &&\n (originalMeasurementsChanged || staticPinPositionChanged)\n ) {\n this._invokeOnTransform();\n }\n }\n\n componentDidMount() {\n this.grabZoomSubjectOriginalMeasurements();\n // We've already run `grabZoomSubjectOriginalMeasurements` at various events\n // to make sure the measurements are promptly updated.\n // However, there might be cases we haven't accounted for, especially when\n // native processes are involved. To account for those cases,\n // we'll use an interval here to ensure we're always up-to-date.\n // The `setState` in `grabZoomSubjectOriginalMeasurements` won't trigger a rerender\n // if the values given haven't changed, so we're not running performance risk here.\n this.measureZoomSubjectInterval = setInterval(\n this.grabZoomSubjectOriginalMeasurements,\n 1e3\n );\n }\n\n componentWillUnmount() {\n this.measureZoomSubjectInterval &&\n clearInterval(this.measureZoomSubjectInterval);\n }\n\n debouncedOnStaticPinPositionChange = debounce(\n (position: Vec2D) => this.props.onStaticPinPositionChange?.(position),\n 100\n );\n\n /**\n * try to invoke onTransform\n * @private\n */\n _invokeOnTransform() {\n const zoomableViewEvent = this._getZoomableViewEventObject();\n const position = this._staticPinPosition();\n\n if (!zoomableViewEvent.originalWidth || !zoomableViewEvent.originalHeight)\n return { successful: false };\n\n this.props.onTransform?.(zoomableViewEvent);\n\n if (position) {\n this.props.onStaticPinPositionMove?.(position);\n this.debouncedOnStaticPinPositionChange(position);\n }\n\n return { successful: true };\n }\n\n /**\n * Returns additional information about components current state for external event hooks\n *\n * @returns {{}}\n * @private\n */\n _getZoomableViewEventObject(overwriteObj = {}): ZoomableViewEvent {\n return {\n zoomLevel: this.zoomLevel,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n originalHeight: this.state.originalHeight,\n originalWidth: this.state.originalWidth,\n originalPageX: this.state.originalPageX,\n originalPageY: this.state.originalPageY,\n ...overwriteObj,\n } as ZoomableViewEvent;\n }\n\n /**\n * Get the original box dimensions and save them for later use.\n * (They will be used to calculate boxBorders)\n *\n * @private\n */\n private grabZoomSubjectOriginalMeasurements = () => {\n // make sure we measure after animations are complete\n requestAnimationFrame(() => {\n // this setTimeout is here to fix a weird issue on iOS where the measurements are all `0`\n // when navigating back (react-navigation stack) from another view\n // while closing the keyboard at the same time\n setTimeout(() => {\n // In normal conditions, we're supposed to measure zoomSubject instead of its wrapper.\n // However, our zoomSubject may have been transformed by an initial zoomLevel or offset,\n // in which case these measurements will not represent the true \"original\" measurements.\n // We just need to make sure the zoomSubjectWrapper perfectly aligns with the zoomSubject\n // (no border, space, or anything between them)\n const zoomSubjectWrapperRef = this.zoomSubjectWrapperRef;\n // we don't wanna measure when zoomSubjectWrapperRef is not yet available or has been unmounted\n zoomSubjectWrapperRef.current?.measureInWindow(\n (x, y, width, height) => {\n // When the component is off-screen, these become all 0s, so we don't set them\n // to avoid messing up calculations, especially ones that are done right after\n // the component transitions from hidden to visible.\n if (!x && !y && !width && !height) return;\n\n // If these values are all the same, don't re-set them in state\n // this way we don't re-render\n if (\n this.state.originalWidth === width &&\n this.state.originalHeight === height &&\n this.state.originalPageX === x &&\n this.state.originalPageY === y\n ) {\n return;\n }\n\n this.setState({\n originalWidth: width,\n originalHeight: height,\n originalPageX: x,\n originalPageY: y,\n });\n }\n );\n });\n });\n };\n\n /**\n * Handles the start of touch events and checks for taps\n *\n * @param e\n * @param gestureState\n * @returns {boolean}\n *\n * @private\n */\n _handleStartShouldSetPanResponder = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onStartShouldSetPanResponder) {\n this.props.onStartShouldSetPanResponder(\n e,\n gestureState,\n this._getZoomableViewEventObject(),\n false\n );\n }\n\n // Always set pan responder on start\n // of gesture so we can handle tap.\n // \"Pan threshold validation\" will be handled\n // in `onPanResponderMove` instead of in `onMoveShouldSetPanResponder`\n return true;\n };\n\n /**\n * Calculates pinch distance\n *\n * @param e\n * @param gestureState\n * @private\n */\n _handlePanResponderGrant: NonNullable<\n PanResponderCallbacks['onPanResponderGrant']\n > = (e, gestureState) => {\n if (this.props.onLongPress) {\n this.longPressTimeout = setTimeout(() => {\n this.props.onLongPress?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n this.longPressTimeout = null;\n }, this.props.longPressDuration);\n }\n\n this.props.onPanResponderGrant?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n this.panAnim.stopAnimation();\n this.zoomAnim.stopAnimation();\n this.gestureStarted = true;\n\n this.raisePin();\n };\n\n /**\n * Handles the end of touch events\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderEnd: NonNullable<\n PanResponderCallbacks['onPanResponderEnd']\n > = (e, gestureState) => {\n if (!this.gestureType) {\n this._resolveAndHandleTap(e);\n }\n\n this.setState({ debugPoints: [] });\n\n this.lastGestureCenterPosition = null;\n\n const disableMomentum =\n this.props.disableMomentum ||\n (this.props.panEnabled &&\n this.gestureType === 'shift' &&\n this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom);\n\n // Trigger final shift animation unless disablePanOnInitialZoom is set and we're on the initial zoom level\n // or disableMomentum\n if (!disableMomentum) {\n getPanMomentumDecayAnim(this.panAnim, {\n x: gestureState.vx / this.zoomLevel,\n y: gestureState.vy / this.zoomLevel,\n }).start();\n }\n\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n this.props.onPanResponderEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n if (this.gestureType === 'pinch') {\n this.props.onZoomEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n } else if (this.gestureType === 'shift') {\n this.props.onShiftingEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n if (this.props.staticPinPosition) {\n this._updateStaticPin();\n }\n\n this.dropPin();\n\n this.gestureType = null;\n this.gestureStarted = false;\n };\n\n /**\n * Handles the actual movement of our pan responder\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderMove = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onPanResponderMove) {\n if (\n this.props.onPanResponderMove(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return false;\n }\n }\n\n // Only supports 2 touches and below,\n // any invalid number will cause the gesture to end.\n if (gestureState.numberActiveTouches <= 2) {\n if (!this.gestureStarted) {\n this._handlePanResponderGrant(e, gestureState);\n }\n } else {\n if (this.gestureStarted) {\n this._handlePanResponderEnd(e, gestureState);\n }\n return true;\n }\n\n if (gestureState.numberActiveTouches === 2) {\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'pinch') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n this.lastGestureTouchDistance = calcGestureTouchDistance(\n e,\n gestureState\n );\n }\n this.gestureType = 'pinch';\n this._handlePinching(e, gestureState);\n } else if (gestureState.numberActiveTouches === 1) {\n if (\n this.longPressTimeout &&\n (Math.abs(gestureState.dx) > 5 || Math.abs(gestureState.dy) > 5)\n ) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'shift') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n }\n\n const { dx, dy } = gestureState;\n const isShiftGesture = Math.abs(dx) > 2 || Math.abs(dy) > 2;\n if (isShiftGesture) {\n this.gestureType = 'shift';\n this._handleShifting(gestureState);\n }\n }\n };\n\n /**\n * Handles the pinch movement and zooming\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePinching(\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) {\n if (!this.props.zoomEnabled) return;\n\n const {\n maxZoom,\n minZoom,\n pinchToZoomInSensitivity,\n pinchToZoomOutSensitivity,\n } = this.props;\n\n const distance = calcGestureTouchDistance(e, gestureState);\n\n if (\n this.props.onZoomBefore &&\n this.props.onZoomBefore(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return;\n }\n\n if (!distance) return;\n if (!this.lastGestureTouchDistance) return;\n\n // define the new zoom level and take zoom level sensitivity into consideration\n const zoomGrowthFromLastGestureState =\n distance / this.lastGestureTouchDistance;\n this.lastGestureTouchDistance = distance;\n\n const pinchToZoomSensitivity =\n zoomGrowthFromLastGestureState < 1\n ? pinchToZoomOutSensitivity\n : pinchToZoomInSensitivity;\n\n if (pinchToZoomSensitivity == null) return;\n const deltaGrowth = zoomGrowthFromLastGestureState - 1;\n // 0 - no resistance\n // 10 - 90% resistance\n const deltaGrowthAdjustedBySensitivity =\n deltaGrowth * (1 - (pinchToZoomSensitivity * 9) / 100);\n\n let newZoomLevel = this.zoomLevel * (1 + deltaGrowthAdjustedBySensitivity);\n\n // make sure max and min zoom levels are respected\n if (maxZoom != null && newZoomLevel > maxZoom) {\n newZoomLevel = maxZoom;\n }\n\n if (minZoom != null && newZoomLevel < minZoom) {\n newZoomLevel = minZoom;\n }\n\n const gestureCenterPoint = calcGestureCenterPoint(e, gestureState);\n\n if (!gestureCenterPoint) return;\n\n let zoomCenter = {\n x: gestureCenterPoint.x - this.state.originalPageX,\n y: gestureCenterPoint.y - this.state.originalPageY,\n };\n\n if (this.props.staticPinPosition) {\n // When we use a static pin position, the zoom centre is the same as that position,\n // otherwise the pin moves around way too much while zooming.\n zoomCenter = {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n };\n }\n\n // Uncomment to debug\n this.props.debug && this._setPinchDebugPoints(e, zoomCenter);\n\n const { originalHeight, originalWidth } = this.state;\n\n const oldOffsetX = this.offsetX;\n const oldOffsetY = this.offsetY;\n const oldScale = this.zoomLevel;\n const newScale = newZoomLevel;\n\n if (!originalHeight || !originalWidth) return;\n\n let offsetY = calcNewScaledOffsetForZoomCentering(\n oldOffsetY,\n originalHeight,\n oldScale,\n newScale,\n zoomCenter.y\n );\n let offsetX = calcNewScaledOffsetForZoomCentering(\n oldOffsetX,\n originalWidth,\n oldScale,\n newScale,\n zoomCenter.x\n );\n\n const offsetShift =\n this._calcOffsetShiftSinceLastGestureState(gestureCenterPoint);\n if (offsetShift) {\n offsetX += offsetShift.x;\n offsetY += offsetShift.y;\n }\n\n this.offsetX = offsetX;\n this.offsetY = offsetY;\n this.zoomLevel = newScale;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n this.props.onZoomAfter?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n /**\n * Used to debug pinch events\n * @param gestureResponderEvent\n * @param zoomCenter\n * @param points\n */\n _setPinchDebugPoints(\n gestureResponderEvent: GestureResponderEvent,\n zoomCenter: Vec2D,\n ...points: Vec2D[]\n ) {\n const { touches } = gestureResponderEvent.nativeEvent;\n const { originalPageY, originalPageX } = this.state;\n\n this.setState({\n debugPoints: [\n {\n x: touches[0].pageX - originalPageX,\n y: touches[0].pageY - originalPageY,\n },\n {\n x: touches[1].pageX - originalPageX,\n y: touches[1].pageY - originalPageY,\n },\n zoomCenter,\n ...points,\n ],\n });\n }\n\n /**\n * Calculates the amount the offset should shift since the last position during panning\n *\n * @param {Vec2D} gestureCenterPoint\n *\n * @private\n */\n _calcOffsetShiftSinceLastGestureState(gestureCenterPoint: Vec2D) {\n const { movementSensibility } = this.props;\n\n let shift = null;\n\n if (this.lastGestureCenterPosition && movementSensibility) {\n const dx = gestureCenterPoint.x - this.lastGestureCenterPosition.x;\n const dy = gestureCenterPoint.y - this.lastGestureCenterPosition.y;\n\n const shiftX = dx / this.zoomLevel / movementSensibility;\n const shiftY = dy / this.zoomLevel / movementSensibility;\n\n shift = {\n x: shiftX,\n y: shiftY,\n };\n }\n\n this.lastGestureCenterPosition = gestureCenterPoint;\n\n return shift;\n }\n\n /**\n * Handles movement by tap and move\n *\n * @param gestureState\n *\n * @private\n */\n _handleShifting(gestureState: PanResponderGestureState) {\n // Skips shifting if panEnabled is false or disablePanOnInitialZoom is true and we're on the initial zoom level\n if (\n !this.props.panEnabled ||\n (this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom)\n ) {\n return;\n }\n const shift = this._calcOffsetShiftSinceLastGestureState({\n x: gestureState.moveX,\n y: gestureState.moveY,\n });\n if (!shift) return;\n\n const offsetX = this.offsetX + shift.x;\n const offsetY = this.offsetY + shift.y;\n\n if (\n this.props.debug &&\n this.state.originalPageX &&\n this.state.originalPageY\n ) {\n const x = gestureState.moveX - this.state.originalPageX;\n const y = gestureState.moveY - this.state.originalPageY;\n this.setState({ debugPoints: [{ x, y }] });\n }\n\n this._setNewOffsetPosition(offsetX, offsetY);\n\n this.raisePin();\n }\n\n /**\n * Set the state to offset moved\n *\n * @param {number} newOffsetX\n * @param {number} newOffsetY\n * @returns\n */\n _setNewOffsetPosition(newOffsetX: number, newOffsetY: number) {\n const { onShiftingBefore, onShiftingAfter } = this.props;\n\n if (onShiftingBefore?.(null, null, this._getZoomableViewEventObject())) {\n return;\n }\n\n this.offsetX = newOffsetX;\n this.offsetY = newOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n onShiftingAfter?.(null, null, this._getZoomableViewEventObject());\n }\n\n /**\n * Check whether the press event is double tap\n * or single tap and handle the event accordingly\n *\n * @param e\n *\n * @private\n */\n private _resolveAndHandleTap = (e: GestureResponderEvent) => {\n const now = Date.now();\n if (\n this.doubleTapFirstTapReleaseTimestamp &&\n this.props.doubleTapDelay &&\n now - this.doubleTapFirstTapReleaseTimestamp < this.props.doubleTapDelay\n ) {\n this.doubleTapFirstTap &&\n this._addTouch({\n ...this.doubleTapFirstTap,\n id: now.toString(),\n isSecondTap: true,\n });\n this.singleTapTimeoutId && clearTimeout(this.singleTapTimeoutId);\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n delete this.doubleTapFirstTap;\n this._handleDoubleTap(e);\n } else {\n this.doubleTapFirstTapReleaseTimestamp = now;\n this.doubleTapFirstTap = {\n id: now.toString(),\n x: e.nativeEvent.pageX - this.state.originalPageX,\n y: e.nativeEvent.pageY - this.state.originalPageY,\n };\n this._addTouch(this.doubleTapFirstTap);\n\n // persist event so e.nativeEvent is preserved after a timeout delay\n e.persist();\n this.singleTapTimeoutId = setTimeout(() => {\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n\n // Pan to the tapped location\n if (this.props.staticPinPosition && this.doubleTapFirstTap) {\n const tapX =\n this.props.staticPinPosition.x - this.doubleTapFirstTap.x;\n const tapY =\n this.props.staticPinPosition.y - this.doubleTapFirstTap.y;\n\n Animated.timing(this.panAnim, {\n toValue: {\n x: this.offsetX + tapX / this.zoomLevel,\n y: this.offsetY + tapY / this.zoomLevel,\n },\n useNativeDriver: true,\n duration: 200,\n }).start(() => {\n this._updateStaticPin();\n });\n }\n\n this.props.onSingleTap?.(e, this._getZoomableViewEventObject());\n }, this.props.doubleTapDelay);\n }\n };\n\n moveStaticPinTo = (position: Vec2D, duration?: number) => {\n const { originalWidth, originalHeight } = this.state;\n const { staticPinPosition, contentWidth, contentHeight } = this.props;\n\n if (!staticPinPosition) return;\n if (!originalWidth || !originalHeight) return;\n if (!contentWidth || !contentHeight) return;\n\n // Offset for the static pin\n const pinX = staticPinPosition.x - originalWidth / 2;\n const pinY = staticPinPosition.y - originalHeight / 2;\n\n this.offsetX = contentWidth / 2 - position.x + pinX / this.zoomLevel;\n this.offsetY = contentHeight / 2 - position.y + pinY / this.zoomLevel;\n\n if (duration) {\n Animated.timing(this.panAnim, {\n toValue: { x: this.offsetX, y: this.offsetY },\n useNativeDriver: true,\n duration,\n }).start();\n } else {\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n }\n };\n\n private _staticPinPosition = () => {\n if (!this.props.staticPinPosition) return;\n if (!this.props.contentWidth || !this.props.contentHeight) return;\n\n return viewportPositionToImagePosition({\n viewportPosition: {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n },\n imageSize: {\n height: this.props.contentHeight,\n width: this.props.contentWidth,\n },\n zoomableEvent: {\n ...this._getZoomableViewEventObject(),\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n zoomLevel: this.zoomLevel,\n },\n });\n };\n\n private _updateStaticPin = () => {\n const position = this._staticPinPosition();\n if (!position) return;\n this.props.onStaticPinPositionChange?.(position);\n };\n\n private _addTouch(touch: TouchPoint) {\n this.touches.push(touch);\n this.setState({ touches: [...this.touches] });\n }\n\n private _removeTouch(touch: TouchPoint) {\n this.touches.splice(this.touches.indexOf(touch), 1);\n this.setState({ touches: [...this.touches] });\n }\n\n /**\n * Handles the double tap event\n *\n * @param e\n *\n * @private\n */\n _handleDoubleTap(e: GestureResponderEvent) {\n const { onDoubleTapBefore, onDoubleTapAfter, doubleTapZoomToCenter } =\n this.props;\n\n onDoubleTapBefore?.(e, this._getZoomableViewEventObject());\n\n const nextZoomStep = this._getNextZoomStep();\n if (nextZoomStep == null) return;\n\n const { originalPageX, originalPageY } = this.state;\n\n // define new zoom position coordinates\n const zoomPositionCoordinates = {\n x: e.nativeEvent.pageX - originalPageX,\n y: e.nativeEvent.pageY - originalPageY,\n };\n\n // if doubleTapZoomToCenter enabled -> always zoom to center instead\n if (doubleTapZoomToCenter) {\n zoomPositionCoordinates.x = 0;\n zoomPositionCoordinates.y = 0;\n }\n\n this.zoomTo(nextZoomStep, zoomPositionCoordinates);\n\n onDoubleTapAfter?.(\n e,\n this._getZoomableViewEventObject({ zoomLevel: nextZoomStep })\n );\n }\n\n /**\n * Returns the next zoom step based on current step and zoomStep property.\n * If we are zoomed all the way in -> return to initialzoom\n *\n * @returns {*}\n */\n _getNextZoomStep() {\n const { zoomStep, maxZoom, initialZoom } = this.props;\n const { zoomLevel } = this;\n\n if (maxZoom == null) return;\n\n if (zoomLevel.toFixed(2) === maxZoom.toFixed(2)) {\n return initialZoom;\n }\n\n if (zoomStep == null) return;\n\n const nextZoomStep = zoomLevel * (1 + zoomStep);\n if (nextZoomStep > maxZoom) {\n return maxZoom;\n }\n\n return nextZoomStep;\n }\n\n /**\n * Zooms to a specific level. A \"zoom center\" can be provided, which specifies\n * the point that will remain in the same position on the screen after the zoom.\n * The coordinates of the zoom center is relative to the zoom subject.\n * { x: 0, y: 0 } is the very center of the zoom subject.\n *\n * @param newZoomLevel\n * @param zoomCenter relative coords compared to the zoom subject. Default to the center.\n */\n zoomTo(newZoomLevel: number, zoomCenter = { x: 0, y: 0 }) {\n if (!this.props.zoomEnabled) return false;\n if (this.props.maxZoom && newZoomLevel > this.props.maxZoom) return false;\n if (this.props.minZoom && newZoomLevel < this.props.minZoom) return false;\n\n this.props.onZoomBefore?.(null, null, this._getZoomableViewEventObject());\n\n // == Perform Zoom Animation ==\n // Calculates panAnim values based on changes in zoomAnim.\n let prevScale = this.zoomLevel;\n // Since zoomAnim is calculated in native driver,\n // it will jitter panAnim once in a while,\n // because here panAnim is being calculated in js.\n // However the jittering should mostly occur in simulator.\n const listenerId = this.zoomAnim.addListener(({ value: newScale }) => {\n this.panAnim.setValue({\n x: calcNewScaledOffsetForZoomCentering(\n this.offsetX,\n this.state.originalWidth,\n prevScale,\n newScale,\n zoomCenter.x\n ),\n y: calcNewScaledOffsetForZoomCentering(\n this.offsetY,\n this.state.originalHeight,\n prevScale,\n newScale,\n zoomCenter.y\n ),\n });\n prevScale = newScale;\n });\n getZoomToAnimation(this.zoomAnim, newZoomLevel).start(() => {\n this.zoomAnim.removeListener(listenerId);\n });\n // == Zoom Animation Ends ==\n\n this.props.onZoomAfter?.(null, null, this._getZoomableViewEventObject());\n return true;\n }\n\n /**\n * Zooms in or out by a specified change level\n * Use a positive number for `zoomLevelChange` to zoom in\n * Use a negative number for `zoomLevelChange` to zoom out\n *\n * Returns a promise if everything was updated and a boolean, whether it could be updated or if it exceeded the min/max zoom limits.\n *\n * @param {number | null} zoomLevelChange\n *\n * @return {bool}\n */\n zoomBy(zoomLevelChange: number) {\n // if no zoom level Change given -> just use zoom step\n zoomLevelChange ||= this.props.zoomStep || 0;\n return this.zoomTo(this.zoomLevel + zoomLevelChange);\n }\n\n /**\n * Moves the zoomed view to a specified position\n * Returns a promise when finished\n *\n * @param {number} newOffsetX the new position we want to move it to (x-axis)\n * @param {number} newOffsetY the new position we want to move it to (y-axis)\n *\n * @return {bool}\n */\n moveTo(newOffsetX: number, newOffsetY: number) {\n const { originalWidth, originalHeight } = this.state;\n if (!originalWidth || !originalHeight) return;\n\n const offsetX = (newOffsetX - originalWidth / 2) / this.zoomLevel;\n const offsetY = (newOffsetY - originalHeight / 2) / this.zoomLevel;\n\n this._setNewOffsetPosition(-offsetX, -offsetY);\n }\n\n /**\n * Moves the zoomed view by a certain amount.\n *\n * Returns a promise when finished\n *\n * @param {number} offsetChangeX the amount we want to move the offset by (x-axis)\n * @param {number} offsetChangeY the amount we want to move the offset by (y-axis)\n *\n * @return {bool}\n */\n moveBy(offsetChangeX: number, offsetChangeY: number) {\n const offsetX =\n (this.offsetX * this.zoomLevel - offsetChangeX) / this.zoomLevel;\n const offsetY =\n (this.offsetY * this.zoomLevel - offsetChangeY) / this.zoomLevel;\n\n this._setNewOffsetPosition(offsetX, offsetY);\n }\n\n render() {\n const {\n staticPinIcon,\n children,\n visualTouchFeedbackEnabled,\n doubleTapDelay,\n staticPinPosition,\n onStaticPinLongPress,\n onStaticPinPress,\n pinProps,\n } = this.props;\n const { pinSize, touches, debugPoints = [] } = this.state;\n\n return (\n {\n this.props.onLayout?.(event);\n this.grabZoomSubjectOriginalMeasurements();\n }}\n >\n \n {children}\n \n\n {visualTouchFeedbackEnabled &&\n touches?.map(\n (touch) =>\n doubleTapDelay && (\n {\n this._removeTouch(touch);\n }}\n />\n )\n )}\n\n {/* For Debugging Only */}\n {debugPoints.map(({ x, y }, index) => {\n return ;\n })}\n\n {staticPinPosition && (\n {\n this.setState({ pinSize: size });\n }}\n pinProps={pinProps}\n />\n )}\n \n );\n }\n}\n\nconst styles = StyleSheet.create({\n container: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n overflow: 'hidden',\n position: 'relative',\n },\n zoomSubject: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n width: '100%',\n },\n});\n\nexport default ReactNativeZoomableView;\n\nexport { ReactNativeZoomableView };\n"]} \ No newline at end of file +{"version":3,"sources":["ReactNativeZoomableView.tsx"],"names":["initialState","originalWidth","originalHeight","originalPageX","originalPageY","pinSize","width","height","ReactNativeZoomableView","Component","gestureStarted","v","_gestureStarted","constructor","props","Animated","ValueXY","x","y","Value","value","boundaryCrossedAnimInEffect","position","onStaticPinPositionChange","requestAnimationFrame","setTimeout","zoomSubjectWrapperRef","current","measureInWindow","state","setState","e","gestureState","onStartShouldSetPanResponder","_getZoomableViewEventObject","onLongPress","longPressTimeout","longPressDuration","onPanResponderGrant","panAnim","stopAnimation","zoomAnim","raisePin","gestureType","_resolveAndHandleTap","debugPoints","lastGestureCenterPosition","disableMomentum","panEnabled","disablePanOnInitialZoom","zoomLevel","initialZoom","vx","vy","start","clearTimeout","onPanResponderEnd","onZoomEnd","onShiftingEnd","staticPinPosition","_updateStaticPin","dropPin","onPanResponderMove","numberActiveTouches","_handlePanResponderGrant","_handlePanResponderEnd","lastGestureTouchDistance","_handlePinching","Math","abs","dx","dy","isShiftGesture","_handleShifting","now","Date","doubleTapFirstTapReleaseTimestamp","doubleTapDelay","doubleTapFirstTap","_addTouch","id","toString","isSecondTap","singleTapTimeoutId","_handleDoubleTap","nativeEvent","pageX","pageY","persist","tapX","tapY","timing","toValue","offsetX","offsetY","useNativeDriver","duration","onSingleTap","contentWidth","contentHeight","pinX","pinY","setValue","viewportPosition","imageSize","zoomableEvent","_staticPinPosition","gestureHandlers","PanResponder","create","_handleStartShouldSetPanResponder","_handlePanResponderMove","onPanResponderRelease","onPanResponderTerminate","evt","onPanResponderTerminationRequest","onShouldBlockNativeResponder","onStartShouldSetPanResponderCapture","onMoveShouldSetPanResponderCapture","zoomAnimatedValue","panAnimatedValueXY","initialOffsetX","initialOffsetY","addListener","animatePin","pinAnim","easing","Easing","out","ease","__setOffset","__getOffset","axis","offset","offsetState","__offsets","bindToBorders","containerSize","contentSize","boundOffset","panBoundaryPadding","boundariesApplied","toFixed","componentDidUpdate","prevProps","prevState","zoomEnabled","onTransformInvocationInitialized","_invokeOnTransform","successful","currState","originalMeasurementsChanged","staticPinPositionChanged","componentDidMount","grabZoomSubjectOriginalMeasurements","measureZoomSubjectInterval","setInterval","componentWillUnmount","clearInterval","zoomableViewEvent","onTransform","onStaticPinPositionMove","debouncedOnStaticPinPositionChange","overwriteObj","maxZoom","minZoom","pinchToZoomInSensitivity","pinchToZoomOutSensitivity","distance","onZoomBefore","zoomGrowthFromLastGestureState","pinchToZoomSensitivity","deltaGrowth","deltaGrowthAdjustedBySensitivity","newZoomLevel","gestureCenterPoint","zoomCenter","debug","_setPinchDebugPoints","oldOffsetX","oldOffsetY","oldScale","newScale","offsetShift","_calcOffsetShiftSinceLastGestureState","onZoomAfter","gestureResponderEvent","points","touches","movementSensibility","shift","shiftX","shiftY","moveX","moveY","_setNewOffsetPosition","newOffsetX","newOffsetY","onShiftingBefore","onShiftingAfter","touch","push","_removeTouch","splice","indexOf","onDoubleTapBefore","onDoubleTapAfter","doubleTapZoomToCenter","nextZoomStep","_getNextZoomStep","zoomPositionCoordinates","zoomTo","zoomStep","listenerId","prevScale","removeListener","zoomBy","zoomLevelChange","moveTo","moveBy","offsetChangeX","offsetChangeY","render","staticPinIcon","children","visualTouchFeedbackEnabled","onStaticPinLongPress","onStaticPinPress","pinProps","styles","container","panHandlers","event","onLayout","zoomSubject","style","transform","scale","getTranslateTransform","map","index","size","undefined","StyleSheet","alignItems","flex","justifyContent","overflow"],"mappings":"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","sourcesContent":["import React, { Component, createRef, RefObject } from 'react';\nimport {\n Animated,\n Easing,\n GestureResponderEvent,\n PanResponder,\n PanResponderCallbacks,\n PanResponderGestureState,\n PanResponderInstance,\n StyleSheet,\n View,\n} from 'react-native';\n\nimport {\n Vec2D,\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState,\n TouchPoint,\n ZoomableViewEvent,\n Size2D,\n} from './typings';\n\nimport { AnimatedTouchFeedback } from './components';\nimport { DebugTouchPoint } from './debugHelper';\nimport {\n calcGestureCenterPoint,\n calcGestureTouchDistance,\n calcNewScaledOffsetForZoomCentering,\n} from './helper';\nimport { applyPanBoundariesToOffset } from './helper/applyPanBoundariesToOffset';\nimport { viewportPositionToImagePosition } from './helper/coordinateConversion';\nimport { StaticPin } from './components/StaticPin';\nimport { debounce } from 'lodash';\nimport {\n getBoundaryCrossedAnim,\n getPanMomentumDecayAnim,\n getZoomToAnimation,\n} from './animations';\n\nconst initialState: ReactNativeZoomableViewState = {\n originalWidth: 0,\n originalHeight: 0,\n originalPageX: 0,\n originalPageY: 0,\n pinSize: { width: 0, height: 0 },\n};\n\nclass ReactNativeZoomableView extends Component<\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState\n> {\n zoomSubjectWrapperRef: RefObject;\n gestureHandlers: PanResponderInstance;\n doubleTapFirstTapReleaseTimestamp: number | undefined;\n\n static defaultProps = {\n zoomEnabled: true,\n panEnabled: true,\n initialZoom: 1,\n initialOffsetX: 0,\n initialOffsetY: 0,\n maxZoom: 1.5,\n minZoom: 0.5,\n pinchToZoomInSensitivity: 1,\n pinchToZoomOutSensitivity: 1,\n movementSensibility: 1,\n doubleTapDelay: 300,\n bindToBorders: true,\n zoomStep: 0.5,\n onLongPress: null,\n longPressDuration: 700,\n contentWidth: undefined,\n contentHeight: undefined,\n panBoundaryPadding: 0,\n visualTouchFeedbackEnabled: true,\n staticPinPosition: undefined,\n staticPinIcon: undefined,\n onStaticPinPositionChange: undefined,\n onStaticPinPositionMove: undefined,\n animatePin: true,\n disablePanOnInitialZoom: false,\n };\n\n private panAnim = new Animated.ValueXY({ x: 0, y: 0 });\n private zoomAnim = new Animated.Value(1);\n private pinAnim = new Animated.ValueXY({ x: 0, y: 0 });\n\n private __offsets = {\n x: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n y: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n };\n\n private zoomLevel = 1;\n private lastGestureCenterPosition: { x: number; y: number } | null = null;\n private lastGestureTouchDistance: number | null = null;\n private gestureType: 'pinch' | 'shift' | null;\n\n private _gestureStarted = false;\n private set gestureStarted(v: boolean) {\n this._gestureStarted = v;\n }\n\n public get gestureStarted() {\n return this._gestureStarted;\n }\n\n /**\n * Last press time (used to evaluate whether user double tapped)\n * @type {number}\n */\n private longPressTimeout: NodeJS.Timeout | null = null;\n private onTransformInvocationInitialized: boolean | undefined;\n private singleTapTimeoutId: NodeJS.Timeout | undefined;\n private touches: TouchPoint[] = [];\n private doubleTapFirstTap: TouchPoint | undefined;\n private measureZoomSubjectInterval: NodeJS.Timer | undefined;\n\n constructor(props: ReactNativeZoomableViewProps) {\n super(props);\n // This needs to be done before anything else to initialize the state.\n // Otherwise, the logic below may reference the state when it's undefined,\n // causing runtime errors.\n this.state = { ...initialState };\n\n this.gestureHandlers = PanResponder.create({\n onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,\n onPanResponderGrant: this._handlePanResponderGrant,\n onPanResponderMove: this._handlePanResponderMove,\n onPanResponderRelease: this._handlePanResponderEnd,\n onPanResponderTerminate: (evt, gestureState) => {\n // We should also call _handlePanResponderEnd\n // to properly perform cleanups when the gesture is terminated\n // (aka gesture handling responsibility is taken over by another component).\n // This also fixes a weird issue where\n // on real device, sometimes onPanResponderRelease is not called when you lift 2 fingers up,\n // but onPanResponderTerminate is called instead for no apparent reason.\n this._handlePanResponderEnd(evt, gestureState);\n this.props.onPanResponderTerminate?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n );\n },\n onPanResponderTerminationRequest: (evt, gestureState) =>\n !!this.props.onPanResponderTerminationRequest?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ),\n // Defaults to true to prevent parent components, such as React Navigation's tab view, from taking over as responder.\n onShouldBlockNativeResponder: (evt, gestureState) =>\n this.props.onShouldBlockNativeResponder?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ) ?? true,\n onStartShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onStartShouldSetPanResponderCapture?.(evt, gestureState),\n onMoveShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onMoveShouldSetPanResponderCapture?.(evt, gestureState),\n });\n\n this.zoomSubjectWrapperRef = createRef();\n\n if (this.props.zoomAnimatedValue)\n this.zoomAnim = this.props.zoomAnimatedValue;\n if (this.props.panAnimatedValueXY)\n this.panAnim = this.props.panAnimatedValueXY;\n\n if (this.props.initialZoom) this.zoomLevel = this.props.initialZoom;\n if (this.props.initialOffsetX != null)\n this.offsetX = this.props.initialOffsetX;\n if (this.props.initialOffsetY != null)\n this.offsetY = this.props.initialOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n this.panAnim.addListener(({ x, y }) => {\n this.offsetX = x;\n this.offsetY = y;\n });\n this.zoomAnim.addListener(({ value }) => {\n this.zoomLevel = value;\n });\n\n this.lastGestureTouchDistance = 150;\n\n this.gestureType = null;\n }\n\n private raisePin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: -10 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private dropPin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: 0 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private set offsetX(x: number) {\n this.__setOffset('x', x);\n }\n\n private set offsetY(y: number) {\n this.__setOffset('y', y);\n }\n\n private get offsetX() {\n return this.__getOffset('x');\n }\n\n private get offsetY() {\n return this.__getOffset('y');\n }\n\n private __setOffset(axis: 'x' | 'y', offset: number) {\n const offsetState = this.__offsets[axis];\n\n if (this.props.bindToBorders) {\n const containerSize =\n axis === 'x' ? this.state.originalWidth : this.state.originalHeight;\n const contentSize =\n axis === 'x'\n ? this.props.contentWidth || this.state.originalWidth\n : this.props.contentHeight || this.state.originalHeight;\n\n const boundOffset =\n contentSize && containerSize && this.props.panBoundaryPadding != null\n ? applyPanBoundariesToOffset(\n offset,\n containerSize,\n contentSize,\n this.zoomLevel,\n this.props.panBoundaryPadding\n )\n : offset;\n\n if (!this.gestureType && !offsetState.boundaryCrossedAnimInEffect) {\n const boundariesApplied =\n boundOffset !== offset &&\n boundOffset.toFixed(3) !== offset.toFixed(3);\n if (boundariesApplied) {\n offsetState.boundaryCrossedAnimInEffect = true;\n getBoundaryCrossedAnim(this.panAnim[axis], boundOffset).start(() => {\n offsetState.boundaryCrossedAnimInEffect = false;\n });\n return;\n }\n }\n }\n\n offsetState.value = offset;\n }\n\n private __getOffset(axis: 'x' | 'y') {\n return this.__offsets[axis].value;\n }\n\n componentDidUpdate(\n prevProps: ReactNativeZoomableViewProps,\n prevState: ReactNativeZoomableViewState\n ) {\n const { zoomEnabled, initialZoom } = this.props;\n if (prevProps.zoomEnabled && !zoomEnabled && initialZoom) {\n this.zoomLevel = initialZoom;\n this.zoomAnim.setValue(this.zoomLevel);\n }\n if (\n !this.onTransformInvocationInitialized &&\n this._invokeOnTransform().successful\n ) {\n this.panAnim.addListener(() => this._invokeOnTransform());\n this.zoomAnim.addListener(() => this._invokeOnTransform());\n this.onTransformInvocationInitialized = true;\n }\n\n const currState = this.state;\n const originalMeasurementsChanged =\n currState.originalHeight !== prevState.originalHeight ||\n currState.originalWidth !== prevState.originalWidth ||\n currState.originalPageX !== prevState.originalPageX ||\n currState.originalPageY !== prevState.originalPageY;\n\n const staticPinPositionChanged =\n prevProps.staticPinPosition?.x !== this.props.staticPinPosition?.x ||\n prevProps.staticPinPosition?.y !== this.props.staticPinPosition?.y;\n\n if (\n this.onTransformInvocationInitialized &&\n (originalMeasurementsChanged || staticPinPositionChanged)\n ) {\n this._invokeOnTransform();\n }\n }\n\n componentDidMount() {\n this.grabZoomSubjectOriginalMeasurements();\n // We've already run `grabZoomSubjectOriginalMeasurements` at various events\n // to make sure the measurements are promptly updated.\n // However, there might be cases we haven't accounted for, especially when\n // native processes are involved. To account for those cases,\n // we'll use an interval here to ensure we're always up-to-date.\n // The `setState` in `grabZoomSubjectOriginalMeasurements` won't trigger a rerender\n // if the values given haven't changed, so we're not running performance risk here.\n this.measureZoomSubjectInterval = setInterval(\n this.grabZoomSubjectOriginalMeasurements,\n 1e3\n );\n }\n\n componentWillUnmount() {\n this.measureZoomSubjectInterval &&\n clearInterval(this.measureZoomSubjectInterval);\n }\n\n debouncedOnStaticPinPositionChange = debounce(\n (position: Vec2D) => this.props.onStaticPinPositionChange?.(position),\n 100\n );\n\n /**\n * try to invoke onTransform\n * @private\n */\n _invokeOnTransform() {\n const zoomableViewEvent = this._getZoomableViewEventObject();\n const position = this._staticPinPosition();\n\n if (!zoomableViewEvent.originalWidth || !zoomableViewEvent.originalHeight)\n return { successful: false };\n\n this.props.onTransform?.(zoomableViewEvent);\n\n if (position) {\n this.props.onStaticPinPositionMove?.(position);\n this.debouncedOnStaticPinPositionChange(position);\n }\n\n return { successful: true };\n }\n\n /**\n * Returns additional information about components current state for external event hooks\n *\n * @returns {{}}\n * @private\n */\n _getZoomableViewEventObject(overwriteObj = {}): ZoomableViewEvent {\n return {\n zoomLevel: this.zoomLevel,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n originalHeight: this.state.originalHeight,\n originalWidth: this.state.originalWidth,\n originalPageX: this.state.originalPageX,\n originalPageY: this.state.originalPageY,\n ...overwriteObj,\n } as ZoomableViewEvent;\n }\n\n /**\n * Get the original box dimensions and save them for later use.\n * (They will be used to calculate boxBorders)\n *\n * @private\n */\n private grabZoomSubjectOriginalMeasurements = () => {\n // make sure we measure after animations are complete\n requestAnimationFrame(() => {\n // this setTimeout is here to fix a weird issue on iOS where the measurements are all `0`\n // when navigating back (react-navigation stack) from another view\n // while closing the keyboard at the same time\n setTimeout(() => {\n // In normal conditions, we're supposed to measure zoomSubject instead of its wrapper.\n // However, our zoomSubject may have been transformed by an initial zoomLevel or offset,\n // in which case these measurements will not represent the true \"original\" measurements.\n // We just need to make sure the zoomSubjectWrapper perfectly aligns with the zoomSubject\n // (no border, space, or anything between them)\n const zoomSubjectWrapperRef = this.zoomSubjectWrapperRef;\n // we don't wanna measure when zoomSubjectWrapperRef is not yet available or has been unmounted\n zoomSubjectWrapperRef.current?.measureInWindow(\n (x, y, width, height) => {\n // When the component is off-screen, these become all 0s, so we don't set them\n // to avoid messing up calculations, especially ones that are done right after\n // the component transitions from hidden to visible.\n if (!x && !y && !width && !height) return;\n\n // If these values are all the same, don't re-set them in state\n // this way we don't re-render\n if (\n this.state.originalWidth === width &&\n this.state.originalHeight === height &&\n this.state.originalPageX === x &&\n this.state.originalPageY === y\n ) {\n return;\n }\n\n this.setState({\n originalWidth: width,\n originalHeight: height,\n originalPageX: x,\n originalPageY: y,\n });\n }\n );\n });\n });\n };\n\n /**\n * Handles the start of touch events and checks for taps\n *\n * @param e\n * @param gestureState\n * @returns {boolean}\n *\n * @private\n */\n _handleStartShouldSetPanResponder = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onStartShouldSetPanResponder) {\n this.props.onStartShouldSetPanResponder(\n e,\n gestureState,\n this._getZoomableViewEventObject(),\n false\n );\n }\n\n // Always set pan responder on start\n // of gesture so we can handle tap.\n // \"Pan threshold validation\" will be handled\n // in `onPanResponderMove` instead of in `onMoveShouldSetPanResponder`\n return true;\n };\n\n /**\n * Calculates pinch distance\n *\n * @param e\n * @param gestureState\n * @private\n */\n _handlePanResponderGrant: NonNullable<\n PanResponderCallbacks['onPanResponderGrant']\n > = (e, gestureState) => {\n if (this.props.onLongPress) {\n this.longPressTimeout = setTimeout(() => {\n this.props.onLongPress?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n this.longPressTimeout = null;\n }, this.props.longPressDuration);\n }\n\n this.props.onPanResponderGrant?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n this.panAnim.stopAnimation();\n this.zoomAnim.stopAnimation();\n this.gestureStarted = true;\n\n this.raisePin();\n };\n\n /**\n * Handles the end of touch events\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderEnd: NonNullable<\n PanResponderCallbacks['onPanResponderEnd']\n > = (e, gestureState) => {\n if (!this.gestureType) {\n this._resolveAndHandleTap(e);\n }\n\n this.setState({ debugPoints: [] });\n\n this.lastGestureCenterPosition = null;\n\n const disableMomentum =\n this.props.disableMomentum ||\n (this.props.panEnabled &&\n this.gestureType === 'shift' &&\n this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom);\n\n // Trigger final shift animation unless disablePanOnInitialZoom is set and we're on the initial zoom level\n // or disableMomentum\n if (!disableMomentum) {\n getPanMomentumDecayAnim(this.panAnim, {\n x: gestureState.vx / this.zoomLevel,\n y: gestureState.vy / this.zoomLevel,\n }).start();\n }\n\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n this.props.onPanResponderEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n if (this.gestureType === 'pinch') {\n this.props.onZoomEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n } else if (this.gestureType === 'shift') {\n this.props.onShiftingEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n if (this.props.staticPinPosition) {\n this._updateStaticPin();\n }\n\n this.dropPin();\n\n this.gestureType = null;\n this.gestureStarted = false;\n };\n\n /**\n * Handles the actual movement of our pan responder\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderMove = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onPanResponderMove) {\n if (\n this.props.onPanResponderMove(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return false;\n }\n }\n\n // Only supports 2 touches and below,\n // any invalid number will cause the gesture to end.\n if (gestureState.numberActiveTouches <= 2) {\n if (!this.gestureStarted) {\n this._handlePanResponderGrant(e, gestureState);\n }\n } else {\n if (this.gestureStarted) {\n this._handlePanResponderEnd(e, gestureState);\n }\n return true;\n }\n\n if (gestureState.numberActiveTouches === 2) {\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'pinch') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n this.lastGestureTouchDistance = calcGestureTouchDistance(\n e,\n gestureState\n );\n }\n this.gestureType = 'pinch';\n this._handlePinching(e, gestureState);\n } else if (gestureState.numberActiveTouches === 1) {\n if (\n this.longPressTimeout &&\n (Math.abs(gestureState.dx) > 5 || Math.abs(gestureState.dy) > 5)\n ) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'shift') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n }\n\n const { dx, dy } = gestureState;\n const isShiftGesture = Math.abs(dx) > 2 || Math.abs(dy) > 2;\n if (isShiftGesture) {\n this.gestureType = 'shift';\n this._handleShifting(gestureState);\n }\n }\n };\n\n /**\n * Handles the pinch movement and zooming\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePinching(\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) {\n if (!this.props.zoomEnabled) return;\n\n const {\n maxZoom,\n minZoom,\n pinchToZoomInSensitivity,\n pinchToZoomOutSensitivity,\n } = this.props;\n\n const distance = calcGestureTouchDistance(e, gestureState);\n\n if (\n this.props.onZoomBefore &&\n this.props.onZoomBefore(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return;\n }\n\n if (!distance) return;\n if (!this.lastGestureTouchDistance) return;\n\n // define the new zoom level and take zoom level sensitivity into consideration\n const zoomGrowthFromLastGestureState =\n distance / this.lastGestureTouchDistance;\n this.lastGestureTouchDistance = distance;\n\n const pinchToZoomSensitivity =\n zoomGrowthFromLastGestureState < 1\n ? pinchToZoomOutSensitivity\n : pinchToZoomInSensitivity;\n\n if (pinchToZoomSensitivity == null) return;\n const deltaGrowth = zoomGrowthFromLastGestureState - 1;\n // 0 - no resistance\n // 10 - 90% resistance\n const deltaGrowthAdjustedBySensitivity =\n deltaGrowth * (1 - (pinchToZoomSensitivity * 9) / 100);\n\n let newZoomLevel = this.zoomLevel * (1 + deltaGrowthAdjustedBySensitivity);\n\n // make sure max and min zoom levels are respected\n if (maxZoom != null && newZoomLevel > maxZoom) {\n newZoomLevel = maxZoom;\n }\n\n if (minZoom != null && newZoomLevel < minZoom) {\n newZoomLevel = minZoom;\n }\n\n const gestureCenterPoint = calcGestureCenterPoint(e, gestureState);\n\n if (!gestureCenterPoint) return;\n\n let zoomCenter = {\n x: gestureCenterPoint.x - this.state.originalPageX,\n y: gestureCenterPoint.y - this.state.originalPageY,\n };\n\n if (this.props.staticPinPosition) {\n // When we use a static pin position, the zoom centre is the same as that position,\n // otherwise the pin moves around way too much while zooming.\n zoomCenter = {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n };\n }\n\n // Uncomment to debug\n this.props.debug && this._setPinchDebugPoints(e, zoomCenter);\n\n const { originalHeight, originalWidth } = this.state;\n\n const oldOffsetX = this.offsetX;\n const oldOffsetY = this.offsetY;\n const oldScale = this.zoomLevel;\n const newScale = newZoomLevel;\n\n if (!originalHeight || !originalWidth) return;\n\n let offsetY = calcNewScaledOffsetForZoomCentering(\n oldOffsetY,\n originalHeight,\n oldScale,\n newScale,\n zoomCenter.y\n );\n let offsetX = calcNewScaledOffsetForZoomCentering(\n oldOffsetX,\n originalWidth,\n oldScale,\n newScale,\n zoomCenter.x\n );\n\n const offsetShift =\n this._calcOffsetShiftSinceLastGestureState(gestureCenterPoint);\n if (offsetShift) {\n offsetX += offsetShift.x;\n offsetY += offsetShift.y;\n }\n\n this.offsetX = offsetX;\n this.offsetY = offsetY;\n this.zoomLevel = newScale;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n this.props.onZoomAfter?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n /**\n * Used to debug pinch events\n * @param gestureResponderEvent\n * @param zoomCenter\n * @param points\n */\n _setPinchDebugPoints(\n gestureResponderEvent: GestureResponderEvent,\n zoomCenter: Vec2D,\n ...points: Vec2D[]\n ) {\n const { touches } = gestureResponderEvent.nativeEvent;\n const { originalPageY, originalPageX } = this.state;\n\n this.setState({\n debugPoints: [\n {\n x: touches[0].pageX - originalPageX,\n y: touches[0].pageY - originalPageY,\n },\n {\n x: touches[1].pageX - originalPageX,\n y: touches[1].pageY - originalPageY,\n },\n zoomCenter,\n ...points,\n ],\n });\n }\n\n /**\n * Calculates the amount the offset should shift since the last position during panning\n *\n * @param {Vec2D} gestureCenterPoint\n *\n * @private\n */\n _calcOffsetShiftSinceLastGestureState(gestureCenterPoint: Vec2D) {\n const { movementSensibility } = this.props;\n\n let shift = null;\n\n if (this.lastGestureCenterPosition && movementSensibility) {\n const dx = gestureCenterPoint.x - this.lastGestureCenterPosition.x;\n const dy = gestureCenterPoint.y - this.lastGestureCenterPosition.y;\n\n const shiftX = dx / this.zoomLevel / movementSensibility;\n const shiftY = dy / this.zoomLevel / movementSensibility;\n\n shift = {\n x: shiftX,\n y: shiftY,\n };\n }\n\n this.lastGestureCenterPosition = gestureCenterPoint;\n\n return shift;\n }\n\n /**\n * Handles movement by tap and move\n *\n * @param gestureState\n *\n * @private\n */\n _handleShifting(gestureState: PanResponderGestureState) {\n // Skips shifting if panEnabled is false or disablePanOnInitialZoom is true and we're on the initial zoom level\n if (\n !this.props.panEnabled ||\n (this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom)\n ) {\n return;\n }\n const shift = this._calcOffsetShiftSinceLastGestureState({\n x: gestureState.moveX,\n y: gestureState.moveY,\n });\n if (!shift) return;\n\n const offsetX = this.offsetX + shift.x;\n const offsetY = this.offsetY + shift.y;\n\n if (\n this.props.debug &&\n this.state.originalPageX &&\n this.state.originalPageY\n ) {\n const x = gestureState.moveX - this.state.originalPageX;\n const y = gestureState.moveY - this.state.originalPageY;\n this.setState({ debugPoints: [{ x, y }] });\n }\n\n this._setNewOffsetPosition(offsetX, offsetY);\n\n this.raisePin();\n }\n\n /**\n * Set the state to offset moved\n *\n * @param {number} newOffsetX\n * @param {number} newOffsetY\n * @returns\n */\n _setNewOffsetPosition(newOffsetX: number, newOffsetY: number) {\n const { onShiftingBefore, onShiftingAfter } = this.props;\n\n if (onShiftingBefore?.(null, null, this._getZoomableViewEventObject())) {\n return;\n }\n\n this.offsetX = newOffsetX;\n this.offsetY = newOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n onShiftingAfter?.(null, null, this._getZoomableViewEventObject());\n }\n\n /**\n * Check whether the press event is double tap\n * or single tap and handle the event accordingly\n *\n * @param e\n *\n * @private\n */\n private _resolveAndHandleTap = (e: GestureResponderEvent) => {\n const now = Date.now();\n if (\n this.doubleTapFirstTapReleaseTimestamp &&\n this.props.doubleTapDelay &&\n now - this.doubleTapFirstTapReleaseTimestamp < this.props.doubleTapDelay\n ) {\n this.doubleTapFirstTap &&\n this._addTouch({\n ...this.doubleTapFirstTap,\n id: now.toString(),\n isSecondTap: true,\n });\n this.singleTapTimeoutId && clearTimeout(this.singleTapTimeoutId);\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n delete this.doubleTapFirstTap;\n this._handleDoubleTap(e);\n } else {\n this.doubleTapFirstTapReleaseTimestamp = now;\n this.doubleTapFirstTap = {\n id: now.toString(),\n x: e.nativeEvent.pageX - this.state.originalPageX,\n y: e.nativeEvent.pageY - this.state.originalPageY,\n };\n this._addTouch(this.doubleTapFirstTap);\n\n // persist event so e.nativeEvent is preserved after a timeout delay\n e.persist();\n this.singleTapTimeoutId = setTimeout(() => {\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n\n // Pan to the tapped location\n if (this.props.staticPinPosition && this.doubleTapFirstTap) {\n const tapX =\n this.props.staticPinPosition.x - this.doubleTapFirstTap.x;\n const tapY =\n this.props.staticPinPosition.y - this.doubleTapFirstTap.y;\n\n Animated.timing(this.panAnim, {\n toValue: {\n x: this.offsetX + tapX / this.zoomLevel,\n y: this.offsetY + tapY / this.zoomLevel,\n },\n useNativeDriver: true,\n duration: 200,\n }).start(() => {\n this._updateStaticPin();\n });\n }\n\n this.props.onSingleTap?.(e, this._getZoomableViewEventObject());\n }, this.props.doubleTapDelay);\n }\n };\n\n moveStaticPinTo = (position: Vec2D, duration?: number) => {\n const { originalWidth, originalHeight } = this.state;\n const { staticPinPosition, contentWidth, contentHeight } = this.props;\n\n if (!staticPinPosition) return;\n if (!originalWidth || !originalHeight) return;\n if (!contentWidth || !contentHeight) return;\n\n // Offset for the static pin\n const pinX = staticPinPosition.x - originalWidth / 2;\n const pinY = staticPinPosition.y - originalHeight / 2;\n\n this.offsetX = contentWidth / 2 - position.x + pinX / this.zoomLevel;\n this.offsetY = contentHeight / 2 - position.y + pinY / this.zoomLevel;\n\n if (duration) {\n Animated.timing(this.panAnim, {\n toValue: { x: this.offsetX, y: this.offsetY },\n useNativeDriver: true,\n duration,\n }).start();\n } else {\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n }\n };\n\n private _staticPinPosition = () => {\n if (!this.props.staticPinPosition) return;\n if (!this.props.contentWidth || !this.props.contentHeight) return;\n\n return viewportPositionToImagePosition({\n viewportPosition: {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n },\n imageSize: {\n height: this.props.contentHeight,\n width: this.props.contentWidth,\n },\n zoomableEvent: {\n ...this._getZoomableViewEventObject(),\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n zoomLevel: this.zoomLevel,\n },\n });\n };\n\n private _updateStaticPin = () => {\n const position = this._staticPinPosition();\n if (!position) return;\n this.props.onStaticPinPositionChange?.(position);\n };\n\n private _addTouch(touch: TouchPoint) {\n this.touches.push(touch);\n this.setState({ touches: [...this.touches] });\n }\n\n private _removeTouch(touch: TouchPoint) {\n this.touches.splice(this.touches.indexOf(touch), 1);\n this.setState({ touches: [...this.touches] });\n }\n\n /**\n * Handles the double tap event\n *\n * @param e\n *\n * @private\n */\n _handleDoubleTap(e: GestureResponderEvent) {\n const { onDoubleTapBefore, onDoubleTapAfter, doubleTapZoomToCenter } =\n this.props;\n\n onDoubleTapBefore?.(e, this._getZoomableViewEventObject());\n\n const nextZoomStep = this._getNextZoomStep();\n if (nextZoomStep == null) return;\n\n const { originalPageX, originalPageY } = this.state;\n\n // define new zoom position coordinates\n const zoomPositionCoordinates = {\n x: e.nativeEvent.pageX - originalPageX,\n y: e.nativeEvent.pageY - originalPageY,\n };\n\n // if doubleTapZoomToCenter enabled -> always zoom to center instead\n if (doubleTapZoomToCenter) {\n zoomPositionCoordinates.x = 0;\n zoomPositionCoordinates.y = 0;\n }\n\n this.zoomTo(nextZoomStep, zoomPositionCoordinates);\n\n onDoubleTapAfter?.(\n e,\n this._getZoomableViewEventObject({ zoomLevel: nextZoomStep })\n );\n }\n\n /**\n * Returns the next zoom step based on current step and zoomStep property.\n * If we are zoomed all the way in -> return to initialzoom\n *\n * @returns {*}\n */\n _getNextZoomStep() {\n const { zoomStep, maxZoom, initialZoom } = this.props;\n const { zoomLevel } = this;\n\n if (maxZoom == null) return;\n\n if (zoomLevel.toFixed(2) === maxZoom.toFixed(2)) {\n return initialZoom;\n }\n\n if (zoomStep == null) return;\n\n const nextZoomStep = zoomLevel * (1 + zoomStep);\n if (nextZoomStep > maxZoom) {\n return maxZoom;\n }\n\n return nextZoomStep;\n }\n\n /**\n * Zooms to a specific level. A \"zoom center\" can be provided, which specifies\n * the point that will remain in the same position on the screen after the zoom.\n * The coordinates of the zoom center is relative to the zoom subject.\n * { x: 0, y: 0 } is the very center of the zoom subject.\n *\n * @param newZoomLevel\n * @param zoomCenter\n */\n zoomTo(newZoomLevel: number, zoomCenter?: Vec2D) {\n if (!this.props.zoomEnabled) return false;\n if (this.props.maxZoom && newZoomLevel > this.props.maxZoom) return false;\n if (this.props.minZoom && newZoomLevel < this.props.minZoom) return false;\n\n this.props.onZoomBefore?.(null, null, this._getZoomableViewEventObject());\n\n // == Perform Pan Animation to preserve the zoom center while zooming ==\n let listenerId: string | undefined;\n if (zoomCenter) {\n // Calculates panAnim values based on changes in zoomAnim.\n let prevScale = this.zoomLevel;\n // Since zoomAnim is calculated in native driver,\n // it will jitter panAnim once in a while,\n // because here panAnim is being calculated in js.\n // However the jittering should mostly occur in simulator.\n listenerId = this.zoomAnim.addListener(({ value: newScale }) => {\n this.panAnim.setValue({\n x: calcNewScaledOffsetForZoomCentering(\n this.offsetX,\n this.state.originalWidth,\n prevScale,\n newScale,\n zoomCenter.x\n ),\n y: calcNewScaledOffsetForZoomCentering(\n this.offsetY,\n this.state.originalHeight,\n prevScale,\n newScale,\n zoomCenter.y\n ),\n });\n prevScale = newScale;\n });\n }\n\n // == Perform Zoom Animation ==\n getZoomToAnimation(this.zoomAnim, newZoomLevel).start(() => {\n if (!listenerId) return;\n this.zoomAnim.removeListener(listenerId);\n });\n // == Zoom Animation Ends ==\n\n this.props.onZoomAfter?.(null, null, this._getZoomableViewEventObject());\n return true;\n }\n\n /**\n * Zooms in or out by a specified change level\n * Use a positive number for `zoomLevelChange` to zoom in\n * Use a negative number for `zoomLevelChange` to zoom out\n *\n * Returns a promise if everything was updated and a boolean, whether it could be updated or if it exceeded the min/max zoom limits.\n *\n * @param {number | null} zoomLevelChange\n *\n * @return {bool}\n */\n zoomBy(zoomLevelChange: number) {\n // if no zoom level Change given -> just use zoom step\n zoomLevelChange ||= this.props.zoomStep || 0;\n return this.zoomTo(this.zoomLevel + zoomLevelChange);\n }\n\n /**\n * Moves the zoomed view to a specified position\n * Returns a promise when finished\n *\n * @param {number} newOffsetX the new position we want to move it to (x-axis)\n * @param {number} newOffsetY the new position we want to move it to (y-axis)\n *\n * @return {bool}\n */\n moveTo(newOffsetX: number, newOffsetY: number) {\n const { originalWidth, originalHeight } = this.state;\n if (!originalWidth || !originalHeight) return;\n\n const offsetX = (newOffsetX - originalWidth / 2) / this.zoomLevel;\n const offsetY = (newOffsetY - originalHeight / 2) / this.zoomLevel;\n\n this._setNewOffsetPosition(-offsetX, -offsetY);\n }\n\n /**\n * Moves the zoomed view by a certain amount.\n *\n * Returns a promise when finished\n *\n * @param {number} offsetChangeX the amount we want to move the offset by (x-axis)\n * @param {number} offsetChangeY the amount we want to move the offset by (y-axis)\n *\n * @return {bool}\n */\n moveBy(offsetChangeX: number, offsetChangeY: number) {\n const offsetX =\n (this.offsetX * this.zoomLevel - offsetChangeX) / this.zoomLevel;\n const offsetY =\n (this.offsetY * this.zoomLevel - offsetChangeY) / this.zoomLevel;\n\n this._setNewOffsetPosition(offsetX, offsetY);\n }\n\n render() {\n const {\n staticPinIcon,\n children,\n visualTouchFeedbackEnabled,\n doubleTapDelay,\n staticPinPosition,\n onStaticPinLongPress,\n onStaticPinPress,\n pinProps,\n } = this.props;\n const { pinSize, touches, debugPoints = [] } = this.state;\n\n return (\n {\n this.props.onLayout?.(event);\n this.grabZoomSubjectOriginalMeasurements();\n }}\n >\n \n {children}\n \n\n {visualTouchFeedbackEnabled &&\n touches?.map(\n (touch) =>\n doubleTapDelay && (\n {\n this._removeTouch(touch);\n }}\n />\n )\n )}\n\n {/* For Debugging Only */}\n {debugPoints.map(({ x, y }, index) => {\n return ;\n })}\n\n {staticPinPosition && (\n {\n this.setState({ pinSize: size });\n }}\n pinProps={pinProps}\n />\n )}\n \n );\n }\n}\n\nconst styles = StyleSheet.create({\n container: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n overflow: 'hidden',\n position: 'relative',\n },\n zoomSubject: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n width: '100%',\n },\n});\n\nexport default ReactNativeZoomableView;\n\nexport { ReactNativeZoomableView };\n"]} \ No newline at end of file diff --git a/lib/module/ReactNativeZoomableView.js b/lib/module/ReactNativeZoomableView.js index 07ac5fc..af2e1bf 100644 --- a/lib/module/ReactNativeZoomableView.js +++ b/lib/module/ReactNativeZoomableView.js @@ -947,37 +947,41 @@ class ReactNativeZoomableView extends Component { * { x: 0, y: 0 } is the very center of the zoom subject. * * @param newZoomLevel - * @param zoomCenter relative coords compared to the zoom subject. Default to the center. + * @param zoomCenter */ - zoomTo(newZoomLevel, zoomCenter = { - x: 0, - y: 0 - }) { + zoomTo(newZoomLevel, zoomCenter) { var _this$props$onZoomBef, _this$props17, _this$props$onZoomAft2, _this$props18; if (!this.props.zoomEnabled) return false; if (this.props.maxZoom && newZoomLevel > this.props.maxZoom) return false; if (this.props.minZoom && newZoomLevel < this.props.minZoom) return false; - (_this$props$onZoomBef = (_this$props17 = this.props).onZoomBefore) === null || _this$props$onZoomBef === void 0 ? void 0 : _this$props$onZoomBef.call(_this$props17, null, null, this._getZoomableViewEventObject()); // == Perform Zoom Animation == - // Calculates panAnim values based on changes in zoomAnim. + (_this$props$onZoomBef = (_this$props17 = this.props).onZoomBefore) === null || _this$props$onZoomBef === void 0 ? void 0 : _this$props$onZoomBef.call(_this$props17, null, null, this._getZoomableViewEventObject()); // == Perform Pan Animation to preserve the zoom center while zooming == - let prevScale = this.zoomLevel; // Since zoomAnim is calculated in native driver, - // it will jitter panAnim once in a while, - // because here panAnim is being calculated in js. - // However the jittering should mostly occur in simulator. + let listenerId; - const listenerId = this.zoomAnim.addListener(({ - value: newScale - }) => { - this.panAnim.setValue({ - x: calcNewScaledOffsetForZoomCentering(this.offsetX, this.state.originalWidth, prevScale, newScale, zoomCenter.x), - y: calcNewScaledOffsetForZoomCentering(this.offsetY, this.state.originalHeight, prevScale, newScale, zoomCenter.y) + if (zoomCenter) { + // Calculates panAnim values based on changes in zoomAnim. + let prevScale = this.zoomLevel; // Since zoomAnim is calculated in native driver, + // it will jitter panAnim once in a while, + // because here panAnim is being calculated in js. + // However the jittering should mostly occur in simulator. + + listenerId = this.zoomAnim.addListener(({ + value: newScale + }) => { + this.panAnim.setValue({ + x: calcNewScaledOffsetForZoomCentering(this.offsetX, this.state.originalWidth, prevScale, newScale, zoomCenter.x), + y: calcNewScaledOffsetForZoomCentering(this.offsetY, this.state.originalHeight, prevScale, newScale, zoomCenter.y) + }); + prevScale = newScale; }); - prevScale = newScale; - }); + } // == Perform Zoom Animation == + + getZoomToAnimation(this.zoomAnim, newZoomLevel).start(() => { + if (!listenerId) return; this.zoomAnim.removeListener(listenerId); }); // == Zoom Animation Ends == diff --git a/lib/module/ReactNativeZoomableView.js.map b/lib/module/ReactNativeZoomableView.js.map index 1e52ff6..2aba8ff 100644 --- a/lib/module/ReactNativeZoomableView.js.map +++ b/lib/module/ReactNativeZoomableView.js.map @@ -1 +1 @@ -{"version":3,"sources":["ReactNativeZoomableView.tsx"],"names":["React","Component","createRef","Animated","Easing","PanResponder","StyleSheet","View","AnimatedTouchFeedback","DebugTouchPoint","calcGestureCenterPoint","calcGestureTouchDistance","calcNewScaledOffsetForZoomCentering","applyPanBoundariesToOffset","viewportPositionToImagePosition","StaticPin","debounce","getBoundaryCrossedAnim","getPanMomentumDecayAnim","getZoomToAnimation","initialState","originalWidth","originalHeight","originalPageX","originalPageY","pinSize","width","height","ReactNativeZoomableView","gestureStarted","v","_gestureStarted","constructor","props","ValueXY","x","y","Value","value","boundaryCrossedAnimInEffect","position","onStaticPinPositionChange","requestAnimationFrame","setTimeout","zoomSubjectWrapperRef","current","measureInWindow","state","setState","e","gestureState","onStartShouldSetPanResponder","_getZoomableViewEventObject","onLongPress","longPressTimeout","longPressDuration","onPanResponderGrant","panAnim","stopAnimation","zoomAnim","raisePin","gestureType","_resolveAndHandleTap","debugPoints","lastGestureCenterPosition","disableMomentum","panEnabled","disablePanOnInitialZoom","zoomLevel","initialZoom","vx","vy","start","clearTimeout","onPanResponderEnd","onZoomEnd","onShiftingEnd","staticPinPosition","_updateStaticPin","dropPin","onPanResponderMove","numberActiveTouches","_handlePanResponderGrant","_handlePanResponderEnd","lastGestureTouchDistance","_handlePinching","Math","abs","dx","dy","isShiftGesture","_handleShifting","now","Date","doubleTapFirstTapReleaseTimestamp","doubleTapDelay","doubleTapFirstTap","_addTouch","id","toString","isSecondTap","singleTapTimeoutId","_handleDoubleTap","nativeEvent","pageX","pageY","persist","tapX","tapY","timing","toValue","offsetX","offsetY","useNativeDriver","duration","onSingleTap","contentWidth","contentHeight","pinX","pinY","setValue","viewportPosition","imageSize","zoomableEvent","_staticPinPosition","gestureHandlers","create","_handleStartShouldSetPanResponder","_handlePanResponderMove","onPanResponderRelease","onPanResponderTerminate","evt","onPanResponderTerminationRequest","onShouldBlockNativeResponder","onStartShouldSetPanResponderCapture","onMoveShouldSetPanResponderCapture","zoomAnimatedValue","panAnimatedValueXY","initialOffsetX","initialOffsetY","addListener","animatePin","pinAnim","easing","out","ease","__setOffset","__getOffset","axis","offset","offsetState","__offsets","bindToBorders","containerSize","contentSize","boundOffset","panBoundaryPadding","boundariesApplied","toFixed","componentDidUpdate","prevProps","prevState","zoomEnabled","onTransformInvocationInitialized","_invokeOnTransform","successful","currState","originalMeasurementsChanged","staticPinPositionChanged","componentDidMount","grabZoomSubjectOriginalMeasurements","measureZoomSubjectInterval","setInterval","componentWillUnmount","clearInterval","zoomableViewEvent","onTransform","onStaticPinPositionMove","debouncedOnStaticPinPositionChange","overwriteObj","maxZoom","minZoom","pinchToZoomInSensitivity","pinchToZoomOutSensitivity","distance","onZoomBefore","zoomGrowthFromLastGestureState","pinchToZoomSensitivity","deltaGrowth","deltaGrowthAdjustedBySensitivity","newZoomLevel","gestureCenterPoint","zoomCenter","debug","_setPinchDebugPoints","oldOffsetX","oldOffsetY","oldScale","newScale","offsetShift","_calcOffsetShiftSinceLastGestureState","onZoomAfter","gestureResponderEvent","points","touches","movementSensibility","shift","shiftX","shiftY","moveX","moveY","_setNewOffsetPosition","newOffsetX","newOffsetY","onShiftingBefore","onShiftingAfter","touch","push","_removeTouch","splice","indexOf","onDoubleTapBefore","onDoubleTapAfter","doubleTapZoomToCenter","nextZoomStep","_getNextZoomStep","zoomPositionCoordinates","zoomTo","zoomStep","prevScale","listenerId","removeListener","zoomBy","zoomLevelChange","moveTo","moveBy","offsetChangeX","offsetChangeY","render","staticPinIcon","children","visualTouchFeedbackEnabled","onStaticPinLongPress","onStaticPinPress","pinProps","styles","container","panHandlers","event","onLayout","zoomSubject","style","transform","scale","getTranslateTransform","map","index","size","undefined","alignItems","flex","justifyContent","overflow"],"mappings":"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","sourcesContent":["import React, { Component, createRef, RefObject } from 'react';\nimport {\n Animated,\n Easing,\n GestureResponderEvent,\n PanResponder,\n PanResponderCallbacks,\n PanResponderGestureState,\n PanResponderInstance,\n StyleSheet,\n View,\n} from 'react-native';\n\nimport {\n Vec2D,\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState,\n TouchPoint,\n ZoomableViewEvent,\n Size2D,\n} from './typings';\n\nimport { AnimatedTouchFeedback } from './components';\nimport { DebugTouchPoint } from './debugHelper';\nimport {\n calcGestureCenterPoint,\n calcGestureTouchDistance,\n calcNewScaledOffsetForZoomCentering,\n} from './helper';\nimport { applyPanBoundariesToOffset } from './helper/applyPanBoundariesToOffset';\nimport { viewportPositionToImagePosition } from './helper/coordinateConversion';\nimport { StaticPin } from './components/StaticPin';\nimport { debounce } from 'lodash';\nimport {\n getBoundaryCrossedAnim,\n getPanMomentumDecayAnim,\n getZoomToAnimation,\n} from './animations';\n\nconst initialState: ReactNativeZoomableViewState = {\n originalWidth: 0,\n originalHeight: 0,\n originalPageX: 0,\n originalPageY: 0,\n pinSize: { width: 0, height: 0 },\n};\n\nclass ReactNativeZoomableView extends Component<\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState\n> {\n zoomSubjectWrapperRef: RefObject;\n gestureHandlers: PanResponderInstance;\n doubleTapFirstTapReleaseTimestamp: number | undefined;\n\n static defaultProps = {\n zoomEnabled: true,\n panEnabled: true,\n initialZoom: 1,\n initialOffsetX: 0,\n initialOffsetY: 0,\n maxZoom: 1.5,\n minZoom: 0.5,\n pinchToZoomInSensitivity: 1,\n pinchToZoomOutSensitivity: 1,\n movementSensibility: 1,\n doubleTapDelay: 300,\n bindToBorders: true,\n zoomStep: 0.5,\n onLongPress: null,\n longPressDuration: 700,\n contentWidth: undefined,\n contentHeight: undefined,\n panBoundaryPadding: 0,\n visualTouchFeedbackEnabled: true,\n staticPinPosition: undefined,\n staticPinIcon: undefined,\n onStaticPinPositionChange: undefined,\n onStaticPinPositionMove: undefined,\n animatePin: true,\n disablePanOnInitialZoom: false,\n };\n\n private panAnim = new Animated.ValueXY({ x: 0, y: 0 });\n private zoomAnim = new Animated.Value(1);\n private pinAnim = new Animated.ValueXY({ x: 0, y: 0 });\n\n private __offsets = {\n x: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n y: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n };\n\n private zoomLevel = 1;\n private lastGestureCenterPosition: { x: number; y: number } | null = null;\n private lastGestureTouchDistance: number | null = null;\n private gestureType: 'pinch' | 'shift' | null;\n\n private _gestureStarted = false;\n private set gestureStarted(v: boolean) {\n this._gestureStarted = v;\n }\n\n public get gestureStarted() {\n return this._gestureStarted;\n }\n\n /**\n * Last press time (used to evaluate whether user double tapped)\n * @type {number}\n */\n private longPressTimeout: NodeJS.Timeout | null = null;\n private onTransformInvocationInitialized: boolean | undefined;\n private singleTapTimeoutId: NodeJS.Timeout | undefined;\n private touches: TouchPoint[] = [];\n private doubleTapFirstTap: TouchPoint | undefined;\n private measureZoomSubjectInterval: NodeJS.Timer | undefined;\n\n constructor(props: ReactNativeZoomableViewProps) {\n super(props);\n // This needs to be done before anything else to initialize the state.\n // Otherwise, the logic below may reference the state when it's undefined,\n // causing runtime errors.\n this.state = { ...initialState };\n\n this.gestureHandlers = PanResponder.create({\n onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,\n onPanResponderGrant: this._handlePanResponderGrant,\n onPanResponderMove: this._handlePanResponderMove,\n onPanResponderRelease: this._handlePanResponderEnd,\n onPanResponderTerminate: (evt, gestureState) => {\n // We should also call _handlePanResponderEnd\n // to properly perform cleanups when the gesture is terminated\n // (aka gesture handling responsibility is taken over by another component).\n // This also fixes a weird issue where\n // on real device, sometimes onPanResponderRelease is not called when you lift 2 fingers up,\n // but onPanResponderTerminate is called instead for no apparent reason.\n this._handlePanResponderEnd(evt, gestureState);\n this.props.onPanResponderTerminate?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n );\n },\n onPanResponderTerminationRequest: (evt, gestureState) =>\n !!this.props.onPanResponderTerminationRequest?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ),\n // Defaults to true to prevent parent components, such as React Navigation's tab view, from taking over as responder.\n onShouldBlockNativeResponder: (evt, gestureState) =>\n this.props.onShouldBlockNativeResponder?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ) ?? true,\n onStartShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onStartShouldSetPanResponderCapture?.(evt, gestureState),\n onMoveShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onMoveShouldSetPanResponderCapture?.(evt, gestureState),\n });\n\n this.zoomSubjectWrapperRef = createRef();\n\n if (this.props.zoomAnimatedValue)\n this.zoomAnim = this.props.zoomAnimatedValue;\n if (this.props.panAnimatedValueXY)\n this.panAnim = this.props.panAnimatedValueXY;\n\n if (this.props.initialZoom) this.zoomLevel = this.props.initialZoom;\n if (this.props.initialOffsetX != null)\n this.offsetX = this.props.initialOffsetX;\n if (this.props.initialOffsetY != null)\n this.offsetY = this.props.initialOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n this.panAnim.addListener(({ x, y }) => {\n this.offsetX = x;\n this.offsetY = y;\n });\n this.zoomAnim.addListener(({ value }) => {\n this.zoomLevel = value;\n });\n\n this.lastGestureTouchDistance = 150;\n\n this.gestureType = null;\n }\n\n private raisePin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: -10 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private dropPin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: 0 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private set offsetX(x: number) {\n this.__setOffset('x', x);\n }\n\n private set offsetY(y: number) {\n this.__setOffset('y', y);\n }\n\n private get offsetX() {\n return this.__getOffset('x');\n }\n\n private get offsetY() {\n return this.__getOffset('y');\n }\n\n private __setOffset(axis: 'x' | 'y', offset: number) {\n const offsetState = this.__offsets[axis];\n\n if (this.props.bindToBorders) {\n const containerSize =\n axis === 'x' ? this.state.originalWidth : this.state.originalHeight;\n const contentSize =\n axis === 'x'\n ? this.props.contentWidth || this.state.originalWidth\n : this.props.contentHeight || this.state.originalHeight;\n\n const boundOffset =\n contentSize && containerSize && this.props.panBoundaryPadding != null\n ? applyPanBoundariesToOffset(\n offset,\n containerSize,\n contentSize,\n this.zoomLevel,\n this.props.panBoundaryPadding\n )\n : offset;\n\n if (!this.gestureType && !offsetState.boundaryCrossedAnimInEffect) {\n const boundariesApplied =\n boundOffset !== offset &&\n boundOffset.toFixed(3) !== offset.toFixed(3);\n if (boundariesApplied) {\n offsetState.boundaryCrossedAnimInEffect = true;\n getBoundaryCrossedAnim(this.panAnim[axis], boundOffset).start(() => {\n offsetState.boundaryCrossedAnimInEffect = false;\n });\n return;\n }\n }\n }\n\n offsetState.value = offset;\n }\n\n private __getOffset(axis: 'x' | 'y') {\n return this.__offsets[axis].value;\n }\n\n componentDidUpdate(\n prevProps: ReactNativeZoomableViewProps,\n prevState: ReactNativeZoomableViewState\n ) {\n const { zoomEnabled, initialZoom } = this.props;\n if (prevProps.zoomEnabled && !zoomEnabled && initialZoom) {\n this.zoomLevel = initialZoom;\n this.zoomAnim.setValue(this.zoomLevel);\n }\n if (\n !this.onTransformInvocationInitialized &&\n this._invokeOnTransform().successful\n ) {\n this.panAnim.addListener(() => this._invokeOnTransform());\n this.zoomAnim.addListener(() => this._invokeOnTransform());\n this.onTransformInvocationInitialized = true;\n }\n\n const currState = this.state;\n const originalMeasurementsChanged =\n currState.originalHeight !== prevState.originalHeight ||\n currState.originalWidth !== prevState.originalWidth ||\n currState.originalPageX !== prevState.originalPageX ||\n currState.originalPageY !== prevState.originalPageY;\n\n const staticPinPositionChanged =\n prevProps.staticPinPosition?.x !== this.props.staticPinPosition?.x ||\n prevProps.staticPinPosition?.y !== this.props.staticPinPosition?.y;\n\n if (\n this.onTransformInvocationInitialized &&\n (originalMeasurementsChanged || staticPinPositionChanged)\n ) {\n this._invokeOnTransform();\n }\n }\n\n componentDidMount() {\n this.grabZoomSubjectOriginalMeasurements();\n // We've already run `grabZoomSubjectOriginalMeasurements` at various events\n // to make sure the measurements are promptly updated.\n // However, there might be cases we haven't accounted for, especially when\n // native processes are involved. To account for those cases,\n // we'll use an interval here to ensure we're always up-to-date.\n // The `setState` in `grabZoomSubjectOriginalMeasurements` won't trigger a rerender\n // if the values given haven't changed, so we're not running performance risk here.\n this.measureZoomSubjectInterval = setInterval(\n this.grabZoomSubjectOriginalMeasurements,\n 1e3\n );\n }\n\n componentWillUnmount() {\n this.measureZoomSubjectInterval &&\n clearInterval(this.measureZoomSubjectInterval);\n }\n\n debouncedOnStaticPinPositionChange = debounce(\n (position: Vec2D) => this.props.onStaticPinPositionChange?.(position),\n 100\n );\n\n /**\n * try to invoke onTransform\n * @private\n */\n _invokeOnTransform() {\n const zoomableViewEvent = this._getZoomableViewEventObject();\n const position = this._staticPinPosition();\n\n if (!zoomableViewEvent.originalWidth || !zoomableViewEvent.originalHeight)\n return { successful: false };\n\n this.props.onTransform?.(zoomableViewEvent);\n\n if (position) {\n this.props.onStaticPinPositionMove?.(position);\n this.debouncedOnStaticPinPositionChange(position);\n }\n\n return { successful: true };\n }\n\n /**\n * Returns additional information about components current state for external event hooks\n *\n * @returns {{}}\n * @private\n */\n _getZoomableViewEventObject(overwriteObj = {}): ZoomableViewEvent {\n return {\n zoomLevel: this.zoomLevel,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n originalHeight: this.state.originalHeight,\n originalWidth: this.state.originalWidth,\n originalPageX: this.state.originalPageX,\n originalPageY: this.state.originalPageY,\n ...overwriteObj,\n } as ZoomableViewEvent;\n }\n\n /**\n * Get the original box dimensions and save them for later use.\n * (They will be used to calculate boxBorders)\n *\n * @private\n */\n private grabZoomSubjectOriginalMeasurements = () => {\n // make sure we measure after animations are complete\n requestAnimationFrame(() => {\n // this setTimeout is here to fix a weird issue on iOS where the measurements are all `0`\n // when navigating back (react-navigation stack) from another view\n // while closing the keyboard at the same time\n setTimeout(() => {\n // In normal conditions, we're supposed to measure zoomSubject instead of its wrapper.\n // However, our zoomSubject may have been transformed by an initial zoomLevel or offset,\n // in which case these measurements will not represent the true \"original\" measurements.\n // We just need to make sure the zoomSubjectWrapper perfectly aligns with the zoomSubject\n // (no border, space, or anything between them)\n const zoomSubjectWrapperRef = this.zoomSubjectWrapperRef;\n // we don't wanna measure when zoomSubjectWrapperRef is not yet available or has been unmounted\n zoomSubjectWrapperRef.current?.measureInWindow(\n (x, y, width, height) => {\n // When the component is off-screen, these become all 0s, so we don't set them\n // to avoid messing up calculations, especially ones that are done right after\n // the component transitions from hidden to visible.\n if (!x && !y && !width && !height) return;\n\n // If these values are all the same, don't re-set them in state\n // this way we don't re-render\n if (\n this.state.originalWidth === width &&\n this.state.originalHeight === height &&\n this.state.originalPageX === x &&\n this.state.originalPageY === y\n ) {\n return;\n }\n\n this.setState({\n originalWidth: width,\n originalHeight: height,\n originalPageX: x,\n originalPageY: y,\n });\n }\n );\n });\n });\n };\n\n /**\n * Handles the start of touch events and checks for taps\n *\n * @param e\n * @param gestureState\n * @returns {boolean}\n *\n * @private\n */\n _handleStartShouldSetPanResponder = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onStartShouldSetPanResponder) {\n this.props.onStartShouldSetPanResponder(\n e,\n gestureState,\n this._getZoomableViewEventObject(),\n false\n );\n }\n\n // Always set pan responder on start\n // of gesture so we can handle tap.\n // \"Pan threshold validation\" will be handled\n // in `onPanResponderMove` instead of in `onMoveShouldSetPanResponder`\n return true;\n };\n\n /**\n * Calculates pinch distance\n *\n * @param e\n * @param gestureState\n * @private\n */\n _handlePanResponderGrant: NonNullable<\n PanResponderCallbacks['onPanResponderGrant']\n > = (e, gestureState) => {\n if (this.props.onLongPress) {\n this.longPressTimeout = setTimeout(() => {\n this.props.onLongPress?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n this.longPressTimeout = null;\n }, this.props.longPressDuration);\n }\n\n this.props.onPanResponderGrant?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n this.panAnim.stopAnimation();\n this.zoomAnim.stopAnimation();\n this.gestureStarted = true;\n\n this.raisePin();\n };\n\n /**\n * Handles the end of touch events\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderEnd: NonNullable<\n PanResponderCallbacks['onPanResponderEnd']\n > = (e, gestureState) => {\n if (!this.gestureType) {\n this._resolveAndHandleTap(e);\n }\n\n this.setState({ debugPoints: [] });\n\n this.lastGestureCenterPosition = null;\n\n const disableMomentum =\n this.props.disableMomentum ||\n (this.props.panEnabled &&\n this.gestureType === 'shift' &&\n this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom);\n\n // Trigger final shift animation unless disablePanOnInitialZoom is set and we're on the initial zoom level\n // or disableMomentum\n if (!disableMomentum) {\n getPanMomentumDecayAnim(this.panAnim, {\n x: gestureState.vx / this.zoomLevel,\n y: gestureState.vy / this.zoomLevel,\n }).start();\n }\n\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n this.props.onPanResponderEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n if (this.gestureType === 'pinch') {\n this.props.onZoomEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n } else if (this.gestureType === 'shift') {\n this.props.onShiftingEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n if (this.props.staticPinPosition) {\n this._updateStaticPin();\n }\n\n this.dropPin();\n\n this.gestureType = null;\n this.gestureStarted = false;\n };\n\n /**\n * Handles the actual movement of our pan responder\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderMove = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onPanResponderMove) {\n if (\n this.props.onPanResponderMove(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return false;\n }\n }\n\n // Only supports 2 touches and below,\n // any invalid number will cause the gesture to end.\n if (gestureState.numberActiveTouches <= 2) {\n if (!this.gestureStarted) {\n this._handlePanResponderGrant(e, gestureState);\n }\n } else {\n if (this.gestureStarted) {\n this._handlePanResponderEnd(e, gestureState);\n }\n return true;\n }\n\n if (gestureState.numberActiveTouches === 2) {\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'pinch') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n this.lastGestureTouchDistance = calcGestureTouchDistance(\n e,\n gestureState\n );\n }\n this.gestureType = 'pinch';\n this._handlePinching(e, gestureState);\n } else if (gestureState.numberActiveTouches === 1) {\n if (\n this.longPressTimeout &&\n (Math.abs(gestureState.dx) > 5 || Math.abs(gestureState.dy) > 5)\n ) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'shift') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n }\n\n const { dx, dy } = gestureState;\n const isShiftGesture = Math.abs(dx) > 2 || Math.abs(dy) > 2;\n if (isShiftGesture) {\n this.gestureType = 'shift';\n this._handleShifting(gestureState);\n }\n }\n };\n\n /**\n * Handles the pinch movement and zooming\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePinching(\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) {\n if (!this.props.zoomEnabled) return;\n\n const {\n maxZoom,\n minZoom,\n pinchToZoomInSensitivity,\n pinchToZoomOutSensitivity,\n } = this.props;\n\n const distance = calcGestureTouchDistance(e, gestureState);\n\n if (\n this.props.onZoomBefore &&\n this.props.onZoomBefore(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return;\n }\n\n if (!distance) return;\n if (!this.lastGestureTouchDistance) return;\n\n // define the new zoom level and take zoom level sensitivity into consideration\n const zoomGrowthFromLastGestureState =\n distance / this.lastGestureTouchDistance;\n this.lastGestureTouchDistance = distance;\n\n const pinchToZoomSensitivity =\n zoomGrowthFromLastGestureState < 1\n ? pinchToZoomOutSensitivity\n : pinchToZoomInSensitivity;\n\n if (pinchToZoomSensitivity == null) return;\n const deltaGrowth = zoomGrowthFromLastGestureState - 1;\n // 0 - no resistance\n // 10 - 90% resistance\n const deltaGrowthAdjustedBySensitivity =\n deltaGrowth * (1 - (pinchToZoomSensitivity * 9) / 100);\n\n let newZoomLevel = this.zoomLevel * (1 + deltaGrowthAdjustedBySensitivity);\n\n // make sure max and min zoom levels are respected\n if (maxZoom != null && newZoomLevel > maxZoom) {\n newZoomLevel = maxZoom;\n }\n\n if (minZoom != null && newZoomLevel < minZoom) {\n newZoomLevel = minZoom;\n }\n\n const gestureCenterPoint = calcGestureCenterPoint(e, gestureState);\n\n if (!gestureCenterPoint) return;\n\n let zoomCenter = {\n x: gestureCenterPoint.x - this.state.originalPageX,\n y: gestureCenterPoint.y - this.state.originalPageY,\n };\n\n if (this.props.staticPinPosition) {\n // When we use a static pin position, the zoom centre is the same as that position,\n // otherwise the pin moves around way too much while zooming.\n zoomCenter = {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n };\n }\n\n // Uncomment to debug\n this.props.debug && this._setPinchDebugPoints(e, zoomCenter);\n\n const { originalHeight, originalWidth } = this.state;\n\n const oldOffsetX = this.offsetX;\n const oldOffsetY = this.offsetY;\n const oldScale = this.zoomLevel;\n const newScale = newZoomLevel;\n\n if (!originalHeight || !originalWidth) return;\n\n let offsetY = calcNewScaledOffsetForZoomCentering(\n oldOffsetY,\n originalHeight,\n oldScale,\n newScale,\n zoomCenter.y\n );\n let offsetX = calcNewScaledOffsetForZoomCentering(\n oldOffsetX,\n originalWidth,\n oldScale,\n newScale,\n zoomCenter.x\n );\n\n const offsetShift =\n this._calcOffsetShiftSinceLastGestureState(gestureCenterPoint);\n if (offsetShift) {\n offsetX += offsetShift.x;\n offsetY += offsetShift.y;\n }\n\n this.offsetX = offsetX;\n this.offsetY = offsetY;\n this.zoomLevel = newScale;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n this.props.onZoomAfter?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n /**\n * Used to debug pinch events\n * @param gestureResponderEvent\n * @param zoomCenter\n * @param points\n */\n _setPinchDebugPoints(\n gestureResponderEvent: GestureResponderEvent,\n zoomCenter: Vec2D,\n ...points: Vec2D[]\n ) {\n const { touches } = gestureResponderEvent.nativeEvent;\n const { originalPageY, originalPageX } = this.state;\n\n this.setState({\n debugPoints: [\n {\n x: touches[0].pageX - originalPageX,\n y: touches[0].pageY - originalPageY,\n },\n {\n x: touches[1].pageX - originalPageX,\n y: touches[1].pageY - originalPageY,\n },\n zoomCenter,\n ...points,\n ],\n });\n }\n\n /**\n * Calculates the amount the offset should shift since the last position during panning\n *\n * @param {Vec2D} gestureCenterPoint\n *\n * @private\n */\n _calcOffsetShiftSinceLastGestureState(gestureCenterPoint: Vec2D) {\n const { movementSensibility } = this.props;\n\n let shift = null;\n\n if (this.lastGestureCenterPosition && movementSensibility) {\n const dx = gestureCenterPoint.x - this.lastGestureCenterPosition.x;\n const dy = gestureCenterPoint.y - this.lastGestureCenterPosition.y;\n\n const shiftX = dx / this.zoomLevel / movementSensibility;\n const shiftY = dy / this.zoomLevel / movementSensibility;\n\n shift = {\n x: shiftX,\n y: shiftY,\n };\n }\n\n this.lastGestureCenterPosition = gestureCenterPoint;\n\n return shift;\n }\n\n /**\n * Handles movement by tap and move\n *\n * @param gestureState\n *\n * @private\n */\n _handleShifting(gestureState: PanResponderGestureState) {\n // Skips shifting if panEnabled is false or disablePanOnInitialZoom is true and we're on the initial zoom level\n if (\n !this.props.panEnabled ||\n (this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom)\n ) {\n return;\n }\n const shift = this._calcOffsetShiftSinceLastGestureState({\n x: gestureState.moveX,\n y: gestureState.moveY,\n });\n if (!shift) return;\n\n const offsetX = this.offsetX + shift.x;\n const offsetY = this.offsetY + shift.y;\n\n if (\n this.props.debug &&\n this.state.originalPageX &&\n this.state.originalPageY\n ) {\n const x = gestureState.moveX - this.state.originalPageX;\n const y = gestureState.moveY - this.state.originalPageY;\n this.setState({ debugPoints: [{ x, y }] });\n }\n\n this._setNewOffsetPosition(offsetX, offsetY);\n\n this.raisePin();\n }\n\n /**\n * Set the state to offset moved\n *\n * @param {number} newOffsetX\n * @param {number} newOffsetY\n * @returns\n */\n _setNewOffsetPosition(newOffsetX: number, newOffsetY: number) {\n const { onShiftingBefore, onShiftingAfter } = this.props;\n\n if (onShiftingBefore?.(null, null, this._getZoomableViewEventObject())) {\n return;\n }\n\n this.offsetX = newOffsetX;\n this.offsetY = newOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n onShiftingAfter?.(null, null, this._getZoomableViewEventObject());\n }\n\n /**\n * Check whether the press event is double tap\n * or single tap and handle the event accordingly\n *\n * @param e\n *\n * @private\n */\n private _resolveAndHandleTap = (e: GestureResponderEvent) => {\n const now = Date.now();\n if (\n this.doubleTapFirstTapReleaseTimestamp &&\n this.props.doubleTapDelay &&\n now - this.doubleTapFirstTapReleaseTimestamp < this.props.doubleTapDelay\n ) {\n this.doubleTapFirstTap &&\n this._addTouch({\n ...this.doubleTapFirstTap,\n id: now.toString(),\n isSecondTap: true,\n });\n this.singleTapTimeoutId && clearTimeout(this.singleTapTimeoutId);\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n delete this.doubleTapFirstTap;\n this._handleDoubleTap(e);\n } else {\n this.doubleTapFirstTapReleaseTimestamp = now;\n this.doubleTapFirstTap = {\n id: now.toString(),\n x: e.nativeEvent.pageX - this.state.originalPageX,\n y: e.nativeEvent.pageY - this.state.originalPageY,\n };\n this._addTouch(this.doubleTapFirstTap);\n\n // persist event so e.nativeEvent is preserved after a timeout delay\n e.persist();\n this.singleTapTimeoutId = setTimeout(() => {\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n\n // Pan to the tapped location\n if (this.props.staticPinPosition && this.doubleTapFirstTap) {\n const tapX =\n this.props.staticPinPosition.x - this.doubleTapFirstTap.x;\n const tapY =\n this.props.staticPinPosition.y - this.doubleTapFirstTap.y;\n\n Animated.timing(this.panAnim, {\n toValue: {\n x: this.offsetX + tapX / this.zoomLevel,\n y: this.offsetY + tapY / this.zoomLevel,\n },\n useNativeDriver: true,\n duration: 200,\n }).start(() => {\n this._updateStaticPin();\n });\n }\n\n this.props.onSingleTap?.(e, this._getZoomableViewEventObject());\n }, this.props.doubleTapDelay);\n }\n };\n\n moveStaticPinTo = (position: Vec2D, duration?: number) => {\n const { originalWidth, originalHeight } = this.state;\n const { staticPinPosition, contentWidth, contentHeight } = this.props;\n\n if (!staticPinPosition) return;\n if (!originalWidth || !originalHeight) return;\n if (!contentWidth || !contentHeight) return;\n\n // Offset for the static pin\n const pinX = staticPinPosition.x - originalWidth / 2;\n const pinY = staticPinPosition.y - originalHeight / 2;\n\n this.offsetX = contentWidth / 2 - position.x + pinX / this.zoomLevel;\n this.offsetY = contentHeight / 2 - position.y + pinY / this.zoomLevel;\n\n if (duration) {\n Animated.timing(this.panAnim, {\n toValue: { x: this.offsetX, y: this.offsetY },\n useNativeDriver: true,\n duration,\n }).start();\n } else {\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n }\n };\n\n private _staticPinPosition = () => {\n if (!this.props.staticPinPosition) return;\n if (!this.props.contentWidth || !this.props.contentHeight) return;\n\n return viewportPositionToImagePosition({\n viewportPosition: {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n },\n imageSize: {\n height: this.props.contentHeight,\n width: this.props.contentWidth,\n },\n zoomableEvent: {\n ...this._getZoomableViewEventObject(),\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n zoomLevel: this.zoomLevel,\n },\n });\n };\n\n private _updateStaticPin = () => {\n const position = this._staticPinPosition();\n if (!position) return;\n this.props.onStaticPinPositionChange?.(position);\n };\n\n private _addTouch(touch: TouchPoint) {\n this.touches.push(touch);\n this.setState({ touches: [...this.touches] });\n }\n\n private _removeTouch(touch: TouchPoint) {\n this.touches.splice(this.touches.indexOf(touch), 1);\n this.setState({ touches: [...this.touches] });\n }\n\n /**\n * Handles the double tap event\n *\n * @param e\n *\n * @private\n */\n _handleDoubleTap(e: GestureResponderEvent) {\n const { onDoubleTapBefore, onDoubleTapAfter, doubleTapZoomToCenter } =\n this.props;\n\n onDoubleTapBefore?.(e, this._getZoomableViewEventObject());\n\n const nextZoomStep = this._getNextZoomStep();\n if (nextZoomStep == null) return;\n\n const { originalPageX, originalPageY } = this.state;\n\n // define new zoom position coordinates\n const zoomPositionCoordinates = {\n x: e.nativeEvent.pageX - originalPageX,\n y: e.nativeEvent.pageY - originalPageY,\n };\n\n // if doubleTapZoomToCenter enabled -> always zoom to center instead\n if (doubleTapZoomToCenter) {\n zoomPositionCoordinates.x = 0;\n zoomPositionCoordinates.y = 0;\n }\n\n this.zoomTo(nextZoomStep, zoomPositionCoordinates);\n\n onDoubleTapAfter?.(\n e,\n this._getZoomableViewEventObject({ zoomLevel: nextZoomStep })\n );\n }\n\n /**\n * Returns the next zoom step based on current step and zoomStep property.\n * If we are zoomed all the way in -> return to initialzoom\n *\n * @returns {*}\n */\n _getNextZoomStep() {\n const { zoomStep, maxZoom, initialZoom } = this.props;\n const { zoomLevel } = this;\n\n if (maxZoom == null) return;\n\n if (zoomLevel.toFixed(2) === maxZoom.toFixed(2)) {\n return initialZoom;\n }\n\n if (zoomStep == null) return;\n\n const nextZoomStep = zoomLevel * (1 + zoomStep);\n if (nextZoomStep > maxZoom) {\n return maxZoom;\n }\n\n return nextZoomStep;\n }\n\n /**\n * Zooms to a specific level. A \"zoom center\" can be provided, which specifies\n * the point that will remain in the same position on the screen after the zoom.\n * The coordinates of the zoom center is relative to the zoom subject.\n * { x: 0, y: 0 } is the very center of the zoom subject.\n *\n * @param newZoomLevel\n * @param zoomCenter relative coords compared to the zoom subject. Default to the center.\n */\n zoomTo(newZoomLevel: number, zoomCenter = { x: 0, y: 0 }) {\n if (!this.props.zoomEnabled) return false;\n if (this.props.maxZoom && newZoomLevel > this.props.maxZoom) return false;\n if (this.props.minZoom && newZoomLevel < this.props.minZoom) return false;\n\n this.props.onZoomBefore?.(null, null, this._getZoomableViewEventObject());\n\n // == Perform Zoom Animation ==\n // Calculates panAnim values based on changes in zoomAnim.\n let prevScale = this.zoomLevel;\n // Since zoomAnim is calculated in native driver,\n // it will jitter panAnim once in a while,\n // because here panAnim is being calculated in js.\n // However the jittering should mostly occur in simulator.\n const listenerId = this.zoomAnim.addListener(({ value: newScale }) => {\n this.panAnim.setValue({\n x: calcNewScaledOffsetForZoomCentering(\n this.offsetX,\n this.state.originalWidth,\n prevScale,\n newScale,\n zoomCenter.x\n ),\n y: calcNewScaledOffsetForZoomCentering(\n this.offsetY,\n this.state.originalHeight,\n prevScale,\n newScale,\n zoomCenter.y\n ),\n });\n prevScale = newScale;\n });\n getZoomToAnimation(this.zoomAnim, newZoomLevel).start(() => {\n this.zoomAnim.removeListener(listenerId);\n });\n // == Zoom Animation Ends ==\n\n this.props.onZoomAfter?.(null, null, this._getZoomableViewEventObject());\n return true;\n }\n\n /**\n * Zooms in or out by a specified change level\n * Use a positive number for `zoomLevelChange` to zoom in\n * Use a negative number for `zoomLevelChange` to zoom out\n *\n * Returns a promise if everything was updated and a boolean, whether it could be updated or if it exceeded the min/max zoom limits.\n *\n * @param {number | null} zoomLevelChange\n *\n * @return {bool}\n */\n zoomBy(zoomLevelChange: number) {\n // if no zoom level Change given -> just use zoom step\n zoomLevelChange ||= this.props.zoomStep || 0;\n return this.zoomTo(this.zoomLevel + zoomLevelChange);\n }\n\n /**\n * Moves the zoomed view to a specified position\n * Returns a promise when finished\n *\n * @param {number} newOffsetX the new position we want to move it to (x-axis)\n * @param {number} newOffsetY the new position we want to move it to (y-axis)\n *\n * @return {bool}\n */\n moveTo(newOffsetX: number, newOffsetY: number) {\n const { originalWidth, originalHeight } = this.state;\n if (!originalWidth || !originalHeight) return;\n\n const offsetX = (newOffsetX - originalWidth / 2) / this.zoomLevel;\n const offsetY = (newOffsetY - originalHeight / 2) / this.zoomLevel;\n\n this._setNewOffsetPosition(-offsetX, -offsetY);\n }\n\n /**\n * Moves the zoomed view by a certain amount.\n *\n * Returns a promise when finished\n *\n * @param {number} offsetChangeX the amount we want to move the offset by (x-axis)\n * @param {number} offsetChangeY the amount we want to move the offset by (y-axis)\n *\n * @return {bool}\n */\n moveBy(offsetChangeX: number, offsetChangeY: number) {\n const offsetX =\n (this.offsetX * this.zoomLevel - offsetChangeX) / this.zoomLevel;\n const offsetY =\n (this.offsetY * this.zoomLevel - offsetChangeY) / this.zoomLevel;\n\n this._setNewOffsetPosition(offsetX, offsetY);\n }\n\n render() {\n const {\n staticPinIcon,\n children,\n visualTouchFeedbackEnabled,\n doubleTapDelay,\n staticPinPosition,\n onStaticPinLongPress,\n onStaticPinPress,\n pinProps,\n } = this.props;\n const { pinSize, touches, debugPoints = [] } = this.state;\n\n return (\n {\n this.props.onLayout?.(event);\n this.grabZoomSubjectOriginalMeasurements();\n }}\n >\n \n {children}\n \n\n {visualTouchFeedbackEnabled &&\n touches?.map(\n (touch) =>\n doubleTapDelay && (\n {\n this._removeTouch(touch);\n }}\n />\n )\n )}\n\n {/* For Debugging Only */}\n {debugPoints.map(({ x, y }, index) => {\n return ;\n })}\n\n {staticPinPosition && (\n {\n this.setState({ pinSize: size });\n }}\n pinProps={pinProps}\n />\n )}\n \n );\n }\n}\n\nconst styles = StyleSheet.create({\n container: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n overflow: 'hidden',\n position: 'relative',\n },\n zoomSubject: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n width: '100%',\n },\n});\n\nexport default ReactNativeZoomableView;\n\nexport { ReactNativeZoomableView };\n"]} \ No newline at end of file +{"version":3,"sources":["ReactNativeZoomableView.tsx"],"names":["React","Component","createRef","Animated","Easing","PanResponder","StyleSheet","View","AnimatedTouchFeedback","DebugTouchPoint","calcGestureCenterPoint","calcGestureTouchDistance","calcNewScaledOffsetForZoomCentering","applyPanBoundariesToOffset","viewportPositionToImagePosition","StaticPin","debounce","getBoundaryCrossedAnim","getPanMomentumDecayAnim","getZoomToAnimation","initialState","originalWidth","originalHeight","originalPageX","originalPageY","pinSize","width","height","ReactNativeZoomableView","gestureStarted","v","_gestureStarted","constructor","props","ValueXY","x","y","Value","value","boundaryCrossedAnimInEffect","position","onStaticPinPositionChange","requestAnimationFrame","setTimeout","zoomSubjectWrapperRef","current","measureInWindow","state","setState","e","gestureState","onStartShouldSetPanResponder","_getZoomableViewEventObject","onLongPress","longPressTimeout","longPressDuration","onPanResponderGrant","panAnim","stopAnimation","zoomAnim","raisePin","gestureType","_resolveAndHandleTap","debugPoints","lastGestureCenterPosition","disableMomentum","panEnabled","disablePanOnInitialZoom","zoomLevel","initialZoom","vx","vy","start","clearTimeout","onPanResponderEnd","onZoomEnd","onShiftingEnd","staticPinPosition","_updateStaticPin","dropPin","onPanResponderMove","numberActiveTouches","_handlePanResponderGrant","_handlePanResponderEnd","lastGestureTouchDistance","_handlePinching","Math","abs","dx","dy","isShiftGesture","_handleShifting","now","Date","doubleTapFirstTapReleaseTimestamp","doubleTapDelay","doubleTapFirstTap","_addTouch","id","toString","isSecondTap","singleTapTimeoutId","_handleDoubleTap","nativeEvent","pageX","pageY","persist","tapX","tapY","timing","toValue","offsetX","offsetY","useNativeDriver","duration","onSingleTap","contentWidth","contentHeight","pinX","pinY","setValue","viewportPosition","imageSize","zoomableEvent","_staticPinPosition","gestureHandlers","create","_handleStartShouldSetPanResponder","_handlePanResponderMove","onPanResponderRelease","onPanResponderTerminate","evt","onPanResponderTerminationRequest","onShouldBlockNativeResponder","onStartShouldSetPanResponderCapture","onMoveShouldSetPanResponderCapture","zoomAnimatedValue","panAnimatedValueXY","initialOffsetX","initialOffsetY","addListener","animatePin","pinAnim","easing","out","ease","__setOffset","__getOffset","axis","offset","offsetState","__offsets","bindToBorders","containerSize","contentSize","boundOffset","panBoundaryPadding","boundariesApplied","toFixed","componentDidUpdate","prevProps","prevState","zoomEnabled","onTransformInvocationInitialized","_invokeOnTransform","successful","currState","originalMeasurementsChanged","staticPinPositionChanged","componentDidMount","grabZoomSubjectOriginalMeasurements","measureZoomSubjectInterval","setInterval","componentWillUnmount","clearInterval","zoomableViewEvent","onTransform","onStaticPinPositionMove","debouncedOnStaticPinPositionChange","overwriteObj","maxZoom","minZoom","pinchToZoomInSensitivity","pinchToZoomOutSensitivity","distance","onZoomBefore","zoomGrowthFromLastGestureState","pinchToZoomSensitivity","deltaGrowth","deltaGrowthAdjustedBySensitivity","newZoomLevel","gestureCenterPoint","zoomCenter","debug","_setPinchDebugPoints","oldOffsetX","oldOffsetY","oldScale","newScale","offsetShift","_calcOffsetShiftSinceLastGestureState","onZoomAfter","gestureResponderEvent","points","touches","movementSensibility","shift","shiftX","shiftY","moveX","moveY","_setNewOffsetPosition","newOffsetX","newOffsetY","onShiftingBefore","onShiftingAfter","touch","push","_removeTouch","splice","indexOf","onDoubleTapBefore","onDoubleTapAfter","doubleTapZoomToCenter","nextZoomStep","_getNextZoomStep","zoomPositionCoordinates","zoomTo","zoomStep","listenerId","prevScale","removeListener","zoomBy","zoomLevelChange","moveTo","moveBy","offsetChangeX","offsetChangeY","render","staticPinIcon","children","visualTouchFeedbackEnabled","onStaticPinLongPress","onStaticPinPress","pinProps","styles","container","panHandlers","event","onLayout","zoomSubject","style","transform","scale","getTranslateTransform","map","index","size","undefined","alignItems","flex","justifyContent","overflow"],"mappings":"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","sourcesContent":["import React, { Component, createRef, RefObject } from 'react';\nimport {\n Animated,\n Easing,\n GestureResponderEvent,\n PanResponder,\n PanResponderCallbacks,\n PanResponderGestureState,\n PanResponderInstance,\n StyleSheet,\n View,\n} from 'react-native';\n\nimport {\n Vec2D,\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState,\n TouchPoint,\n ZoomableViewEvent,\n Size2D,\n} from './typings';\n\nimport { AnimatedTouchFeedback } from './components';\nimport { DebugTouchPoint } from './debugHelper';\nimport {\n calcGestureCenterPoint,\n calcGestureTouchDistance,\n calcNewScaledOffsetForZoomCentering,\n} from './helper';\nimport { applyPanBoundariesToOffset } from './helper/applyPanBoundariesToOffset';\nimport { viewportPositionToImagePosition } from './helper/coordinateConversion';\nimport { StaticPin } from './components/StaticPin';\nimport { debounce } from 'lodash';\nimport {\n getBoundaryCrossedAnim,\n getPanMomentumDecayAnim,\n getZoomToAnimation,\n} from './animations';\n\nconst initialState: ReactNativeZoomableViewState = {\n originalWidth: 0,\n originalHeight: 0,\n originalPageX: 0,\n originalPageY: 0,\n pinSize: { width: 0, height: 0 },\n};\n\nclass ReactNativeZoomableView extends Component<\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState\n> {\n zoomSubjectWrapperRef: RefObject;\n gestureHandlers: PanResponderInstance;\n doubleTapFirstTapReleaseTimestamp: number | undefined;\n\n static defaultProps = {\n zoomEnabled: true,\n panEnabled: true,\n initialZoom: 1,\n initialOffsetX: 0,\n initialOffsetY: 0,\n maxZoom: 1.5,\n minZoom: 0.5,\n pinchToZoomInSensitivity: 1,\n pinchToZoomOutSensitivity: 1,\n movementSensibility: 1,\n doubleTapDelay: 300,\n bindToBorders: true,\n zoomStep: 0.5,\n onLongPress: null,\n longPressDuration: 700,\n contentWidth: undefined,\n contentHeight: undefined,\n panBoundaryPadding: 0,\n visualTouchFeedbackEnabled: true,\n staticPinPosition: undefined,\n staticPinIcon: undefined,\n onStaticPinPositionChange: undefined,\n onStaticPinPositionMove: undefined,\n animatePin: true,\n disablePanOnInitialZoom: false,\n };\n\n private panAnim = new Animated.ValueXY({ x: 0, y: 0 });\n private zoomAnim = new Animated.Value(1);\n private pinAnim = new Animated.ValueXY({ x: 0, y: 0 });\n\n private __offsets = {\n x: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n y: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n };\n\n private zoomLevel = 1;\n private lastGestureCenterPosition: { x: number; y: number } | null = null;\n private lastGestureTouchDistance: number | null = null;\n private gestureType: 'pinch' | 'shift' | null;\n\n private _gestureStarted = false;\n private set gestureStarted(v: boolean) {\n this._gestureStarted = v;\n }\n\n public get gestureStarted() {\n return this._gestureStarted;\n }\n\n /**\n * Last press time (used to evaluate whether user double tapped)\n * @type {number}\n */\n private longPressTimeout: NodeJS.Timeout | null = null;\n private onTransformInvocationInitialized: boolean | undefined;\n private singleTapTimeoutId: NodeJS.Timeout | undefined;\n private touches: TouchPoint[] = [];\n private doubleTapFirstTap: TouchPoint | undefined;\n private measureZoomSubjectInterval: NodeJS.Timer | undefined;\n\n constructor(props: ReactNativeZoomableViewProps) {\n super(props);\n // This needs to be done before anything else to initialize the state.\n // Otherwise, the logic below may reference the state when it's undefined,\n // causing runtime errors.\n this.state = { ...initialState };\n\n this.gestureHandlers = PanResponder.create({\n onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,\n onPanResponderGrant: this._handlePanResponderGrant,\n onPanResponderMove: this._handlePanResponderMove,\n onPanResponderRelease: this._handlePanResponderEnd,\n onPanResponderTerminate: (evt, gestureState) => {\n // We should also call _handlePanResponderEnd\n // to properly perform cleanups when the gesture is terminated\n // (aka gesture handling responsibility is taken over by another component).\n // This also fixes a weird issue where\n // on real device, sometimes onPanResponderRelease is not called when you lift 2 fingers up,\n // but onPanResponderTerminate is called instead for no apparent reason.\n this._handlePanResponderEnd(evt, gestureState);\n this.props.onPanResponderTerminate?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n );\n },\n onPanResponderTerminationRequest: (evt, gestureState) =>\n !!this.props.onPanResponderTerminationRequest?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ),\n // Defaults to true to prevent parent components, such as React Navigation's tab view, from taking over as responder.\n onShouldBlockNativeResponder: (evt, gestureState) =>\n this.props.onShouldBlockNativeResponder?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ) ?? true,\n onStartShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onStartShouldSetPanResponderCapture?.(evt, gestureState),\n onMoveShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onMoveShouldSetPanResponderCapture?.(evt, gestureState),\n });\n\n this.zoomSubjectWrapperRef = createRef();\n\n if (this.props.zoomAnimatedValue)\n this.zoomAnim = this.props.zoomAnimatedValue;\n if (this.props.panAnimatedValueXY)\n this.panAnim = this.props.panAnimatedValueXY;\n\n if (this.props.initialZoom) this.zoomLevel = this.props.initialZoom;\n if (this.props.initialOffsetX != null)\n this.offsetX = this.props.initialOffsetX;\n if (this.props.initialOffsetY != null)\n this.offsetY = this.props.initialOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n this.panAnim.addListener(({ x, y }) => {\n this.offsetX = x;\n this.offsetY = y;\n });\n this.zoomAnim.addListener(({ value }) => {\n this.zoomLevel = value;\n });\n\n this.lastGestureTouchDistance = 150;\n\n this.gestureType = null;\n }\n\n private raisePin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: -10 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private dropPin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: 0 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private set offsetX(x: number) {\n this.__setOffset('x', x);\n }\n\n private set offsetY(y: number) {\n this.__setOffset('y', y);\n }\n\n private get offsetX() {\n return this.__getOffset('x');\n }\n\n private get offsetY() {\n return this.__getOffset('y');\n }\n\n private __setOffset(axis: 'x' | 'y', offset: number) {\n const offsetState = this.__offsets[axis];\n\n if (this.props.bindToBorders) {\n const containerSize =\n axis === 'x' ? this.state.originalWidth : this.state.originalHeight;\n const contentSize =\n axis === 'x'\n ? this.props.contentWidth || this.state.originalWidth\n : this.props.contentHeight || this.state.originalHeight;\n\n const boundOffset =\n contentSize && containerSize && this.props.panBoundaryPadding != null\n ? applyPanBoundariesToOffset(\n offset,\n containerSize,\n contentSize,\n this.zoomLevel,\n this.props.panBoundaryPadding\n )\n : offset;\n\n if (!this.gestureType && !offsetState.boundaryCrossedAnimInEffect) {\n const boundariesApplied =\n boundOffset !== offset &&\n boundOffset.toFixed(3) !== offset.toFixed(3);\n if (boundariesApplied) {\n offsetState.boundaryCrossedAnimInEffect = true;\n getBoundaryCrossedAnim(this.panAnim[axis], boundOffset).start(() => {\n offsetState.boundaryCrossedAnimInEffect = false;\n });\n return;\n }\n }\n }\n\n offsetState.value = offset;\n }\n\n private __getOffset(axis: 'x' | 'y') {\n return this.__offsets[axis].value;\n }\n\n componentDidUpdate(\n prevProps: ReactNativeZoomableViewProps,\n prevState: ReactNativeZoomableViewState\n ) {\n const { zoomEnabled, initialZoom } = this.props;\n if (prevProps.zoomEnabled && !zoomEnabled && initialZoom) {\n this.zoomLevel = initialZoom;\n this.zoomAnim.setValue(this.zoomLevel);\n }\n if (\n !this.onTransformInvocationInitialized &&\n this._invokeOnTransform().successful\n ) {\n this.panAnim.addListener(() => this._invokeOnTransform());\n this.zoomAnim.addListener(() => this._invokeOnTransform());\n this.onTransformInvocationInitialized = true;\n }\n\n const currState = this.state;\n const originalMeasurementsChanged =\n currState.originalHeight !== prevState.originalHeight ||\n currState.originalWidth !== prevState.originalWidth ||\n currState.originalPageX !== prevState.originalPageX ||\n currState.originalPageY !== prevState.originalPageY;\n\n const staticPinPositionChanged =\n prevProps.staticPinPosition?.x !== this.props.staticPinPosition?.x ||\n prevProps.staticPinPosition?.y !== this.props.staticPinPosition?.y;\n\n if (\n this.onTransformInvocationInitialized &&\n (originalMeasurementsChanged || staticPinPositionChanged)\n ) {\n this._invokeOnTransform();\n }\n }\n\n componentDidMount() {\n this.grabZoomSubjectOriginalMeasurements();\n // We've already run `grabZoomSubjectOriginalMeasurements` at various events\n // to make sure the measurements are promptly updated.\n // However, there might be cases we haven't accounted for, especially when\n // native processes are involved. To account for those cases,\n // we'll use an interval here to ensure we're always up-to-date.\n // The `setState` in `grabZoomSubjectOriginalMeasurements` won't trigger a rerender\n // if the values given haven't changed, so we're not running performance risk here.\n this.measureZoomSubjectInterval = setInterval(\n this.grabZoomSubjectOriginalMeasurements,\n 1e3\n );\n }\n\n componentWillUnmount() {\n this.measureZoomSubjectInterval &&\n clearInterval(this.measureZoomSubjectInterval);\n }\n\n debouncedOnStaticPinPositionChange = debounce(\n (position: Vec2D) => this.props.onStaticPinPositionChange?.(position),\n 100\n );\n\n /**\n * try to invoke onTransform\n * @private\n */\n _invokeOnTransform() {\n const zoomableViewEvent = this._getZoomableViewEventObject();\n const position = this._staticPinPosition();\n\n if (!zoomableViewEvent.originalWidth || !zoomableViewEvent.originalHeight)\n return { successful: false };\n\n this.props.onTransform?.(zoomableViewEvent);\n\n if (position) {\n this.props.onStaticPinPositionMove?.(position);\n this.debouncedOnStaticPinPositionChange(position);\n }\n\n return { successful: true };\n }\n\n /**\n * Returns additional information about components current state for external event hooks\n *\n * @returns {{}}\n * @private\n */\n _getZoomableViewEventObject(overwriteObj = {}): ZoomableViewEvent {\n return {\n zoomLevel: this.zoomLevel,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n originalHeight: this.state.originalHeight,\n originalWidth: this.state.originalWidth,\n originalPageX: this.state.originalPageX,\n originalPageY: this.state.originalPageY,\n ...overwriteObj,\n } as ZoomableViewEvent;\n }\n\n /**\n * Get the original box dimensions and save them for later use.\n * (They will be used to calculate boxBorders)\n *\n * @private\n */\n private grabZoomSubjectOriginalMeasurements = () => {\n // make sure we measure after animations are complete\n requestAnimationFrame(() => {\n // this setTimeout is here to fix a weird issue on iOS where the measurements are all `0`\n // when navigating back (react-navigation stack) from another view\n // while closing the keyboard at the same time\n setTimeout(() => {\n // In normal conditions, we're supposed to measure zoomSubject instead of its wrapper.\n // However, our zoomSubject may have been transformed by an initial zoomLevel or offset,\n // in which case these measurements will not represent the true \"original\" measurements.\n // We just need to make sure the zoomSubjectWrapper perfectly aligns with the zoomSubject\n // (no border, space, or anything between them)\n const zoomSubjectWrapperRef = this.zoomSubjectWrapperRef;\n // we don't wanna measure when zoomSubjectWrapperRef is not yet available or has been unmounted\n zoomSubjectWrapperRef.current?.measureInWindow(\n (x, y, width, height) => {\n // When the component is off-screen, these become all 0s, so we don't set them\n // to avoid messing up calculations, especially ones that are done right after\n // the component transitions from hidden to visible.\n if (!x && !y && !width && !height) return;\n\n // If these values are all the same, don't re-set them in state\n // this way we don't re-render\n if (\n this.state.originalWidth === width &&\n this.state.originalHeight === height &&\n this.state.originalPageX === x &&\n this.state.originalPageY === y\n ) {\n return;\n }\n\n this.setState({\n originalWidth: width,\n originalHeight: height,\n originalPageX: x,\n originalPageY: y,\n });\n }\n );\n });\n });\n };\n\n /**\n * Handles the start of touch events and checks for taps\n *\n * @param e\n * @param gestureState\n * @returns {boolean}\n *\n * @private\n */\n _handleStartShouldSetPanResponder = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onStartShouldSetPanResponder) {\n this.props.onStartShouldSetPanResponder(\n e,\n gestureState,\n this._getZoomableViewEventObject(),\n false\n );\n }\n\n // Always set pan responder on start\n // of gesture so we can handle tap.\n // \"Pan threshold validation\" will be handled\n // in `onPanResponderMove` instead of in `onMoveShouldSetPanResponder`\n return true;\n };\n\n /**\n * Calculates pinch distance\n *\n * @param e\n * @param gestureState\n * @private\n */\n _handlePanResponderGrant: NonNullable<\n PanResponderCallbacks['onPanResponderGrant']\n > = (e, gestureState) => {\n if (this.props.onLongPress) {\n this.longPressTimeout = setTimeout(() => {\n this.props.onLongPress?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n this.longPressTimeout = null;\n }, this.props.longPressDuration);\n }\n\n this.props.onPanResponderGrant?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n this.panAnim.stopAnimation();\n this.zoomAnim.stopAnimation();\n this.gestureStarted = true;\n\n this.raisePin();\n };\n\n /**\n * Handles the end of touch events\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderEnd: NonNullable<\n PanResponderCallbacks['onPanResponderEnd']\n > = (e, gestureState) => {\n if (!this.gestureType) {\n this._resolveAndHandleTap(e);\n }\n\n this.setState({ debugPoints: [] });\n\n this.lastGestureCenterPosition = null;\n\n const disableMomentum =\n this.props.disableMomentum ||\n (this.props.panEnabled &&\n this.gestureType === 'shift' &&\n this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom);\n\n // Trigger final shift animation unless disablePanOnInitialZoom is set and we're on the initial zoom level\n // or disableMomentum\n if (!disableMomentum) {\n getPanMomentumDecayAnim(this.panAnim, {\n x: gestureState.vx / this.zoomLevel,\n y: gestureState.vy / this.zoomLevel,\n }).start();\n }\n\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n this.props.onPanResponderEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n if (this.gestureType === 'pinch') {\n this.props.onZoomEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n } else if (this.gestureType === 'shift') {\n this.props.onShiftingEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n if (this.props.staticPinPosition) {\n this._updateStaticPin();\n }\n\n this.dropPin();\n\n this.gestureType = null;\n this.gestureStarted = false;\n };\n\n /**\n * Handles the actual movement of our pan responder\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderMove = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onPanResponderMove) {\n if (\n this.props.onPanResponderMove(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return false;\n }\n }\n\n // Only supports 2 touches and below,\n // any invalid number will cause the gesture to end.\n if (gestureState.numberActiveTouches <= 2) {\n if (!this.gestureStarted) {\n this._handlePanResponderGrant(e, gestureState);\n }\n } else {\n if (this.gestureStarted) {\n this._handlePanResponderEnd(e, gestureState);\n }\n return true;\n }\n\n if (gestureState.numberActiveTouches === 2) {\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'pinch') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n this.lastGestureTouchDistance = calcGestureTouchDistance(\n e,\n gestureState\n );\n }\n this.gestureType = 'pinch';\n this._handlePinching(e, gestureState);\n } else if (gestureState.numberActiveTouches === 1) {\n if (\n this.longPressTimeout &&\n (Math.abs(gestureState.dx) > 5 || Math.abs(gestureState.dy) > 5)\n ) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'shift') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n }\n\n const { dx, dy } = gestureState;\n const isShiftGesture = Math.abs(dx) > 2 || Math.abs(dy) > 2;\n if (isShiftGesture) {\n this.gestureType = 'shift';\n this._handleShifting(gestureState);\n }\n }\n };\n\n /**\n * Handles the pinch movement and zooming\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePinching(\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) {\n if (!this.props.zoomEnabled) return;\n\n const {\n maxZoom,\n minZoom,\n pinchToZoomInSensitivity,\n pinchToZoomOutSensitivity,\n } = this.props;\n\n const distance = calcGestureTouchDistance(e, gestureState);\n\n if (\n this.props.onZoomBefore &&\n this.props.onZoomBefore(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return;\n }\n\n if (!distance) return;\n if (!this.lastGestureTouchDistance) return;\n\n // define the new zoom level and take zoom level sensitivity into consideration\n const zoomGrowthFromLastGestureState =\n distance / this.lastGestureTouchDistance;\n this.lastGestureTouchDistance = distance;\n\n const pinchToZoomSensitivity =\n zoomGrowthFromLastGestureState < 1\n ? pinchToZoomOutSensitivity\n : pinchToZoomInSensitivity;\n\n if (pinchToZoomSensitivity == null) return;\n const deltaGrowth = zoomGrowthFromLastGestureState - 1;\n // 0 - no resistance\n // 10 - 90% resistance\n const deltaGrowthAdjustedBySensitivity =\n deltaGrowth * (1 - (pinchToZoomSensitivity * 9) / 100);\n\n let newZoomLevel = this.zoomLevel * (1 + deltaGrowthAdjustedBySensitivity);\n\n // make sure max and min zoom levels are respected\n if (maxZoom != null && newZoomLevel > maxZoom) {\n newZoomLevel = maxZoom;\n }\n\n if (minZoom != null && newZoomLevel < minZoom) {\n newZoomLevel = minZoom;\n }\n\n const gestureCenterPoint = calcGestureCenterPoint(e, gestureState);\n\n if (!gestureCenterPoint) return;\n\n let zoomCenter = {\n x: gestureCenterPoint.x - this.state.originalPageX,\n y: gestureCenterPoint.y - this.state.originalPageY,\n };\n\n if (this.props.staticPinPosition) {\n // When we use a static pin position, the zoom centre is the same as that position,\n // otherwise the pin moves around way too much while zooming.\n zoomCenter = {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n };\n }\n\n // Uncomment to debug\n this.props.debug && this._setPinchDebugPoints(e, zoomCenter);\n\n const { originalHeight, originalWidth } = this.state;\n\n const oldOffsetX = this.offsetX;\n const oldOffsetY = this.offsetY;\n const oldScale = this.zoomLevel;\n const newScale = newZoomLevel;\n\n if (!originalHeight || !originalWidth) return;\n\n let offsetY = calcNewScaledOffsetForZoomCentering(\n oldOffsetY,\n originalHeight,\n oldScale,\n newScale,\n zoomCenter.y\n );\n let offsetX = calcNewScaledOffsetForZoomCentering(\n oldOffsetX,\n originalWidth,\n oldScale,\n newScale,\n zoomCenter.x\n );\n\n const offsetShift =\n this._calcOffsetShiftSinceLastGestureState(gestureCenterPoint);\n if (offsetShift) {\n offsetX += offsetShift.x;\n offsetY += offsetShift.y;\n }\n\n this.offsetX = offsetX;\n this.offsetY = offsetY;\n this.zoomLevel = newScale;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n this.props.onZoomAfter?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n /**\n * Used to debug pinch events\n * @param gestureResponderEvent\n * @param zoomCenter\n * @param points\n */\n _setPinchDebugPoints(\n gestureResponderEvent: GestureResponderEvent,\n zoomCenter: Vec2D,\n ...points: Vec2D[]\n ) {\n const { touches } = gestureResponderEvent.nativeEvent;\n const { originalPageY, originalPageX } = this.state;\n\n this.setState({\n debugPoints: [\n {\n x: touches[0].pageX - originalPageX,\n y: touches[0].pageY - originalPageY,\n },\n {\n x: touches[1].pageX - originalPageX,\n y: touches[1].pageY - originalPageY,\n },\n zoomCenter,\n ...points,\n ],\n });\n }\n\n /**\n * Calculates the amount the offset should shift since the last position during panning\n *\n * @param {Vec2D} gestureCenterPoint\n *\n * @private\n */\n _calcOffsetShiftSinceLastGestureState(gestureCenterPoint: Vec2D) {\n const { movementSensibility } = this.props;\n\n let shift = null;\n\n if (this.lastGestureCenterPosition && movementSensibility) {\n const dx = gestureCenterPoint.x - this.lastGestureCenterPosition.x;\n const dy = gestureCenterPoint.y - this.lastGestureCenterPosition.y;\n\n const shiftX = dx / this.zoomLevel / movementSensibility;\n const shiftY = dy / this.zoomLevel / movementSensibility;\n\n shift = {\n x: shiftX,\n y: shiftY,\n };\n }\n\n this.lastGestureCenterPosition = gestureCenterPoint;\n\n return shift;\n }\n\n /**\n * Handles movement by tap and move\n *\n * @param gestureState\n *\n * @private\n */\n _handleShifting(gestureState: PanResponderGestureState) {\n // Skips shifting if panEnabled is false or disablePanOnInitialZoom is true and we're on the initial zoom level\n if (\n !this.props.panEnabled ||\n (this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom)\n ) {\n return;\n }\n const shift = this._calcOffsetShiftSinceLastGestureState({\n x: gestureState.moveX,\n y: gestureState.moveY,\n });\n if (!shift) return;\n\n const offsetX = this.offsetX + shift.x;\n const offsetY = this.offsetY + shift.y;\n\n if (\n this.props.debug &&\n this.state.originalPageX &&\n this.state.originalPageY\n ) {\n const x = gestureState.moveX - this.state.originalPageX;\n const y = gestureState.moveY - this.state.originalPageY;\n this.setState({ debugPoints: [{ x, y }] });\n }\n\n this._setNewOffsetPosition(offsetX, offsetY);\n\n this.raisePin();\n }\n\n /**\n * Set the state to offset moved\n *\n * @param {number} newOffsetX\n * @param {number} newOffsetY\n * @returns\n */\n _setNewOffsetPosition(newOffsetX: number, newOffsetY: number) {\n const { onShiftingBefore, onShiftingAfter } = this.props;\n\n if (onShiftingBefore?.(null, null, this._getZoomableViewEventObject())) {\n return;\n }\n\n this.offsetX = newOffsetX;\n this.offsetY = newOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n onShiftingAfter?.(null, null, this._getZoomableViewEventObject());\n }\n\n /**\n * Check whether the press event is double tap\n * or single tap and handle the event accordingly\n *\n * @param e\n *\n * @private\n */\n private _resolveAndHandleTap = (e: GestureResponderEvent) => {\n const now = Date.now();\n if (\n this.doubleTapFirstTapReleaseTimestamp &&\n this.props.doubleTapDelay &&\n now - this.doubleTapFirstTapReleaseTimestamp < this.props.doubleTapDelay\n ) {\n this.doubleTapFirstTap &&\n this._addTouch({\n ...this.doubleTapFirstTap,\n id: now.toString(),\n isSecondTap: true,\n });\n this.singleTapTimeoutId && clearTimeout(this.singleTapTimeoutId);\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n delete this.doubleTapFirstTap;\n this._handleDoubleTap(e);\n } else {\n this.doubleTapFirstTapReleaseTimestamp = now;\n this.doubleTapFirstTap = {\n id: now.toString(),\n x: e.nativeEvent.pageX - this.state.originalPageX,\n y: e.nativeEvent.pageY - this.state.originalPageY,\n };\n this._addTouch(this.doubleTapFirstTap);\n\n // persist event so e.nativeEvent is preserved after a timeout delay\n e.persist();\n this.singleTapTimeoutId = setTimeout(() => {\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n\n // Pan to the tapped location\n if (this.props.staticPinPosition && this.doubleTapFirstTap) {\n const tapX =\n this.props.staticPinPosition.x - this.doubleTapFirstTap.x;\n const tapY =\n this.props.staticPinPosition.y - this.doubleTapFirstTap.y;\n\n Animated.timing(this.panAnim, {\n toValue: {\n x: this.offsetX + tapX / this.zoomLevel,\n y: this.offsetY + tapY / this.zoomLevel,\n },\n useNativeDriver: true,\n duration: 200,\n }).start(() => {\n this._updateStaticPin();\n });\n }\n\n this.props.onSingleTap?.(e, this._getZoomableViewEventObject());\n }, this.props.doubleTapDelay);\n }\n };\n\n moveStaticPinTo = (position: Vec2D, duration?: number) => {\n const { originalWidth, originalHeight } = this.state;\n const { staticPinPosition, contentWidth, contentHeight } = this.props;\n\n if (!staticPinPosition) return;\n if (!originalWidth || !originalHeight) return;\n if (!contentWidth || !contentHeight) return;\n\n // Offset for the static pin\n const pinX = staticPinPosition.x - originalWidth / 2;\n const pinY = staticPinPosition.y - originalHeight / 2;\n\n this.offsetX = contentWidth / 2 - position.x + pinX / this.zoomLevel;\n this.offsetY = contentHeight / 2 - position.y + pinY / this.zoomLevel;\n\n if (duration) {\n Animated.timing(this.panAnim, {\n toValue: { x: this.offsetX, y: this.offsetY },\n useNativeDriver: true,\n duration,\n }).start();\n } else {\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n }\n };\n\n private _staticPinPosition = () => {\n if (!this.props.staticPinPosition) return;\n if (!this.props.contentWidth || !this.props.contentHeight) return;\n\n return viewportPositionToImagePosition({\n viewportPosition: {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n },\n imageSize: {\n height: this.props.contentHeight,\n width: this.props.contentWidth,\n },\n zoomableEvent: {\n ...this._getZoomableViewEventObject(),\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n zoomLevel: this.zoomLevel,\n },\n });\n };\n\n private _updateStaticPin = () => {\n const position = this._staticPinPosition();\n if (!position) return;\n this.props.onStaticPinPositionChange?.(position);\n };\n\n private _addTouch(touch: TouchPoint) {\n this.touches.push(touch);\n this.setState({ touches: [...this.touches] });\n }\n\n private _removeTouch(touch: TouchPoint) {\n this.touches.splice(this.touches.indexOf(touch), 1);\n this.setState({ touches: [...this.touches] });\n }\n\n /**\n * Handles the double tap event\n *\n * @param e\n *\n * @private\n */\n _handleDoubleTap(e: GestureResponderEvent) {\n const { onDoubleTapBefore, onDoubleTapAfter, doubleTapZoomToCenter } =\n this.props;\n\n onDoubleTapBefore?.(e, this._getZoomableViewEventObject());\n\n const nextZoomStep = this._getNextZoomStep();\n if (nextZoomStep == null) return;\n\n const { originalPageX, originalPageY } = this.state;\n\n // define new zoom position coordinates\n const zoomPositionCoordinates = {\n x: e.nativeEvent.pageX - originalPageX,\n y: e.nativeEvent.pageY - originalPageY,\n };\n\n // if doubleTapZoomToCenter enabled -> always zoom to center instead\n if (doubleTapZoomToCenter) {\n zoomPositionCoordinates.x = 0;\n zoomPositionCoordinates.y = 0;\n }\n\n this.zoomTo(nextZoomStep, zoomPositionCoordinates);\n\n onDoubleTapAfter?.(\n e,\n this._getZoomableViewEventObject({ zoomLevel: nextZoomStep })\n );\n }\n\n /**\n * Returns the next zoom step based on current step and zoomStep property.\n * If we are zoomed all the way in -> return to initialzoom\n *\n * @returns {*}\n */\n _getNextZoomStep() {\n const { zoomStep, maxZoom, initialZoom } = this.props;\n const { zoomLevel } = this;\n\n if (maxZoom == null) return;\n\n if (zoomLevel.toFixed(2) === maxZoom.toFixed(2)) {\n return initialZoom;\n }\n\n if (zoomStep == null) return;\n\n const nextZoomStep = zoomLevel * (1 + zoomStep);\n if (nextZoomStep > maxZoom) {\n return maxZoom;\n }\n\n return nextZoomStep;\n }\n\n /**\n * Zooms to a specific level. A \"zoom center\" can be provided, which specifies\n * the point that will remain in the same position on the screen after the zoom.\n * The coordinates of the zoom center is relative to the zoom subject.\n * { x: 0, y: 0 } is the very center of the zoom subject.\n *\n * @param newZoomLevel\n * @param zoomCenter\n */\n zoomTo(newZoomLevel: number, zoomCenter?: Vec2D) {\n if (!this.props.zoomEnabled) return false;\n if (this.props.maxZoom && newZoomLevel > this.props.maxZoom) return false;\n if (this.props.minZoom && newZoomLevel < this.props.minZoom) return false;\n\n this.props.onZoomBefore?.(null, null, this._getZoomableViewEventObject());\n\n // == Perform Pan Animation to preserve the zoom center while zooming ==\n let listenerId: string | undefined;\n if (zoomCenter) {\n // Calculates panAnim values based on changes in zoomAnim.\n let prevScale = this.zoomLevel;\n // Since zoomAnim is calculated in native driver,\n // it will jitter panAnim once in a while,\n // because here panAnim is being calculated in js.\n // However the jittering should mostly occur in simulator.\n listenerId = this.zoomAnim.addListener(({ value: newScale }) => {\n this.panAnim.setValue({\n x: calcNewScaledOffsetForZoomCentering(\n this.offsetX,\n this.state.originalWidth,\n prevScale,\n newScale,\n zoomCenter.x\n ),\n y: calcNewScaledOffsetForZoomCentering(\n this.offsetY,\n this.state.originalHeight,\n prevScale,\n newScale,\n zoomCenter.y\n ),\n });\n prevScale = newScale;\n });\n }\n\n // == Perform Zoom Animation ==\n getZoomToAnimation(this.zoomAnim, newZoomLevel).start(() => {\n if (!listenerId) return;\n this.zoomAnim.removeListener(listenerId);\n });\n // == Zoom Animation Ends ==\n\n this.props.onZoomAfter?.(null, null, this._getZoomableViewEventObject());\n return true;\n }\n\n /**\n * Zooms in or out by a specified change level\n * Use a positive number for `zoomLevelChange` to zoom in\n * Use a negative number for `zoomLevelChange` to zoom out\n *\n * Returns a promise if everything was updated and a boolean, whether it could be updated or if it exceeded the min/max zoom limits.\n *\n * @param {number | null} zoomLevelChange\n *\n * @return {bool}\n */\n zoomBy(zoomLevelChange: number) {\n // if no zoom level Change given -> just use zoom step\n zoomLevelChange ||= this.props.zoomStep || 0;\n return this.zoomTo(this.zoomLevel + zoomLevelChange);\n }\n\n /**\n * Moves the zoomed view to a specified position\n * Returns a promise when finished\n *\n * @param {number} newOffsetX the new position we want to move it to (x-axis)\n * @param {number} newOffsetY the new position we want to move it to (y-axis)\n *\n * @return {bool}\n */\n moveTo(newOffsetX: number, newOffsetY: number) {\n const { originalWidth, originalHeight } = this.state;\n if (!originalWidth || !originalHeight) return;\n\n const offsetX = (newOffsetX - originalWidth / 2) / this.zoomLevel;\n const offsetY = (newOffsetY - originalHeight / 2) / this.zoomLevel;\n\n this._setNewOffsetPosition(-offsetX, -offsetY);\n }\n\n /**\n * Moves the zoomed view by a certain amount.\n *\n * Returns a promise when finished\n *\n * @param {number} offsetChangeX the amount we want to move the offset by (x-axis)\n * @param {number} offsetChangeY the amount we want to move the offset by (y-axis)\n *\n * @return {bool}\n */\n moveBy(offsetChangeX: number, offsetChangeY: number) {\n const offsetX =\n (this.offsetX * this.zoomLevel - offsetChangeX) / this.zoomLevel;\n const offsetY =\n (this.offsetY * this.zoomLevel - offsetChangeY) / this.zoomLevel;\n\n this._setNewOffsetPosition(offsetX, offsetY);\n }\n\n render() {\n const {\n staticPinIcon,\n children,\n visualTouchFeedbackEnabled,\n doubleTapDelay,\n staticPinPosition,\n onStaticPinLongPress,\n onStaticPinPress,\n pinProps,\n } = this.props;\n const { pinSize, touches, debugPoints = [] } = this.state;\n\n return (\n {\n this.props.onLayout?.(event);\n this.grabZoomSubjectOriginalMeasurements();\n }}\n >\n \n {children}\n \n\n {visualTouchFeedbackEnabled &&\n touches?.map(\n (touch) =>\n doubleTapDelay && (\n {\n this._removeTouch(touch);\n }}\n />\n )\n )}\n\n {/* For Debugging Only */}\n {debugPoints.map(({ x, y }, index) => {\n return ;\n })}\n\n {staticPinPosition && (\n {\n this.setState({ pinSize: size });\n }}\n pinProps={pinProps}\n />\n )}\n \n );\n }\n}\n\nconst styles = StyleSheet.create({\n container: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n overflow: 'hidden',\n position: 'relative',\n },\n zoomSubject: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n width: '100%',\n },\n});\n\nexport default ReactNativeZoomableView;\n\nexport { ReactNativeZoomableView };\n"]} \ No newline at end of file diff --git a/lib/typescript/ReactNativeZoomableView.d.ts b/lib/typescript/ReactNativeZoomableView.d.ts index 7f84620..48edb63 100644 --- a/lib/typescript/ReactNativeZoomableView.d.ts +++ b/lib/typescript/ReactNativeZoomableView.d.ts @@ -203,12 +203,9 @@ declare class ReactNativeZoomableView extends Component this.props.maxZoom) return false; if (this.props.minZoom && newZoomLevel < this.props.minZoom) return false; this.props.onZoomBefore?.(null, null, this._getZoomableViewEventObject()); - // == Perform Zoom Animation == - // Calculates panAnim values based on changes in zoomAnim. - let prevScale = this.zoomLevel; - // Since zoomAnim is calculated in native driver, - // it will jitter panAnim once in a while, - // because here panAnim is being calculated in js. - // However the jittering should mostly occur in simulator. - const listenerId = this.zoomAnim.addListener(({ value: newScale }) => { - this.panAnim.setValue({ - x: calcNewScaledOffsetForZoomCentering( - this.offsetX, - this.state.originalWidth, - prevScale, - newScale, - zoomCenter.x - ), - y: calcNewScaledOffsetForZoomCentering( - this.offsetY, - this.state.originalHeight, - prevScale, - newScale, - zoomCenter.y - ), + // == Perform Pan Animation to preserve the zoom center while zooming == + let listenerId: string | undefined; + if (zoomCenter) { + // Calculates panAnim values based on changes in zoomAnim. + let prevScale = this.zoomLevel; + // Since zoomAnim is calculated in native driver, + // it will jitter panAnim once in a while, + // because here panAnim is being calculated in js. + // However the jittering should mostly occur in simulator. + listenerId = this.zoomAnim.addListener(({ value: newScale }) => { + this.panAnim.setValue({ + x: calcNewScaledOffsetForZoomCentering( + this.offsetX, + this.state.originalWidth, + prevScale, + newScale, + zoomCenter.x + ), + y: calcNewScaledOffsetForZoomCentering( + this.offsetY, + this.state.originalHeight, + prevScale, + newScale, + zoomCenter.y + ), + }); + prevScale = newScale; }); - prevScale = newScale; - }); + } + + // == Perform Zoom Animation == getZoomToAnimation(this.zoomAnim, newZoomLevel).start(() => { + if (!listenerId) return; this.zoomAnim.removeListener(listenerId); }); // == Zoom Animation Ends == From ad6a6aaeb270096db9fc0c52be46255ac15fea5a Mon Sep 17 00:00:00 2001 From: thomasvo Date: Fri, 10 Jan 2025 13:49:45 -0800 Subject: [PATCH 2/4] doc --- lib/commonjs/ReactNativeZoomableView.js | 2 +- lib/commonjs/ReactNativeZoomableView.js.map | 2 +- lib/module/ReactNativeZoomableView.js | 2 +- lib/module/ReactNativeZoomableView.js.map | 2 +- lib/typescript/ReactNativeZoomableView.d.ts | 2 +- src/ReactNativeZoomableView.tsx | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/commonjs/ReactNativeZoomableView.js b/lib/commonjs/ReactNativeZoomableView.js index 4ce481f..f371947 100644 --- a/lib/commonjs/ReactNativeZoomableView.js +++ b/lib/commonjs/ReactNativeZoomableView.js @@ -971,7 +971,7 @@ class ReactNativeZoomableView extends _react.Component { * { x: 0, y: 0 } is the very center of the zoom subject. * * @param newZoomLevel - * @param zoomCenter + * @param zoomCenter - If not supplied, the container's center is the zoom center */ diff --git a/lib/commonjs/ReactNativeZoomableView.js.map b/lib/commonjs/ReactNativeZoomableView.js.map index f9547bd..ba109d7 100644 --- a/lib/commonjs/ReactNativeZoomableView.js.map +++ b/lib/commonjs/ReactNativeZoomableView.js.map @@ -1 +1 @@ -{"version":3,"sources":["ReactNativeZoomableView.tsx"],"names":["initialState","originalWidth","originalHeight","originalPageX","originalPageY","pinSize","width","height","ReactNativeZoomableView","Component","gestureStarted","v","_gestureStarted","constructor","props","Animated","ValueXY","x","y","Value","value","boundaryCrossedAnimInEffect","position","onStaticPinPositionChange","requestAnimationFrame","setTimeout","zoomSubjectWrapperRef","current","measureInWindow","state","setState","e","gestureState","onStartShouldSetPanResponder","_getZoomableViewEventObject","onLongPress","longPressTimeout","longPressDuration","onPanResponderGrant","panAnim","stopAnimation","zoomAnim","raisePin","gestureType","_resolveAndHandleTap","debugPoints","lastGestureCenterPosition","disableMomentum","panEnabled","disablePanOnInitialZoom","zoomLevel","initialZoom","vx","vy","start","clearTimeout","onPanResponderEnd","onZoomEnd","onShiftingEnd","staticPinPosition","_updateStaticPin","dropPin","onPanResponderMove","numberActiveTouches","_handlePanResponderGrant","_handlePanResponderEnd","lastGestureTouchDistance","_handlePinching","Math","abs","dx","dy","isShiftGesture","_handleShifting","now","Date","doubleTapFirstTapReleaseTimestamp","doubleTapDelay","doubleTapFirstTap","_addTouch","id","toString","isSecondTap","singleTapTimeoutId","_handleDoubleTap","nativeEvent","pageX","pageY","persist","tapX","tapY","timing","toValue","offsetX","offsetY","useNativeDriver","duration","onSingleTap","contentWidth","contentHeight","pinX","pinY","setValue","viewportPosition","imageSize","zoomableEvent","_staticPinPosition","gestureHandlers","PanResponder","create","_handleStartShouldSetPanResponder","_handlePanResponderMove","onPanResponderRelease","onPanResponderTerminate","evt","onPanResponderTerminationRequest","onShouldBlockNativeResponder","onStartShouldSetPanResponderCapture","onMoveShouldSetPanResponderCapture","zoomAnimatedValue","panAnimatedValueXY","initialOffsetX","initialOffsetY","addListener","animatePin","pinAnim","easing","Easing","out","ease","__setOffset","__getOffset","axis","offset","offsetState","__offsets","bindToBorders","containerSize","contentSize","boundOffset","panBoundaryPadding","boundariesApplied","toFixed","componentDidUpdate","prevProps","prevState","zoomEnabled","onTransformInvocationInitialized","_invokeOnTransform","successful","currState","originalMeasurementsChanged","staticPinPositionChanged","componentDidMount","grabZoomSubjectOriginalMeasurements","measureZoomSubjectInterval","setInterval","componentWillUnmount","clearInterval","zoomableViewEvent","onTransform","onStaticPinPositionMove","debouncedOnStaticPinPositionChange","overwriteObj","maxZoom","minZoom","pinchToZoomInSensitivity","pinchToZoomOutSensitivity","distance","onZoomBefore","zoomGrowthFromLastGestureState","pinchToZoomSensitivity","deltaGrowth","deltaGrowthAdjustedBySensitivity","newZoomLevel","gestureCenterPoint","zoomCenter","debug","_setPinchDebugPoints","oldOffsetX","oldOffsetY","oldScale","newScale","offsetShift","_calcOffsetShiftSinceLastGestureState","onZoomAfter","gestureResponderEvent","points","touches","movementSensibility","shift","shiftX","shiftY","moveX","moveY","_setNewOffsetPosition","newOffsetX","newOffsetY","onShiftingBefore","onShiftingAfter","touch","push","_removeTouch","splice","indexOf","onDoubleTapBefore","onDoubleTapAfter","doubleTapZoomToCenter","nextZoomStep","_getNextZoomStep","zoomPositionCoordinates","zoomTo","zoomStep","listenerId","prevScale","removeListener","zoomBy","zoomLevelChange","moveTo","moveBy","offsetChangeX","offsetChangeY","render","staticPinIcon","children","visualTouchFeedbackEnabled","onStaticPinLongPress","onStaticPinPress","pinProps","styles","container","panHandlers","event","onLayout","zoomSubject","style","transform","scale","getTranslateTransform","map","index","size","undefined","StyleSheet","alignItems","flex","justifyContent","overflow"],"mappings":"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","sourcesContent":["import React, { Component, createRef, RefObject } from 'react';\nimport {\n Animated,\n Easing,\n GestureResponderEvent,\n PanResponder,\n PanResponderCallbacks,\n PanResponderGestureState,\n PanResponderInstance,\n StyleSheet,\n View,\n} from 'react-native';\n\nimport {\n Vec2D,\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState,\n TouchPoint,\n ZoomableViewEvent,\n Size2D,\n} from './typings';\n\nimport { AnimatedTouchFeedback } from './components';\nimport { DebugTouchPoint } from './debugHelper';\nimport {\n calcGestureCenterPoint,\n calcGestureTouchDistance,\n calcNewScaledOffsetForZoomCentering,\n} from './helper';\nimport { applyPanBoundariesToOffset } from './helper/applyPanBoundariesToOffset';\nimport { viewportPositionToImagePosition } from './helper/coordinateConversion';\nimport { StaticPin } from './components/StaticPin';\nimport { debounce } from 'lodash';\nimport {\n getBoundaryCrossedAnim,\n getPanMomentumDecayAnim,\n getZoomToAnimation,\n} from './animations';\n\nconst initialState: ReactNativeZoomableViewState = {\n originalWidth: 0,\n originalHeight: 0,\n originalPageX: 0,\n originalPageY: 0,\n pinSize: { width: 0, height: 0 },\n};\n\nclass ReactNativeZoomableView extends Component<\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState\n> {\n zoomSubjectWrapperRef: RefObject;\n gestureHandlers: PanResponderInstance;\n doubleTapFirstTapReleaseTimestamp: number | undefined;\n\n static defaultProps = {\n zoomEnabled: true,\n panEnabled: true,\n initialZoom: 1,\n initialOffsetX: 0,\n initialOffsetY: 0,\n maxZoom: 1.5,\n minZoom: 0.5,\n pinchToZoomInSensitivity: 1,\n pinchToZoomOutSensitivity: 1,\n movementSensibility: 1,\n doubleTapDelay: 300,\n bindToBorders: true,\n zoomStep: 0.5,\n onLongPress: null,\n longPressDuration: 700,\n contentWidth: undefined,\n contentHeight: undefined,\n panBoundaryPadding: 0,\n visualTouchFeedbackEnabled: true,\n staticPinPosition: undefined,\n staticPinIcon: undefined,\n onStaticPinPositionChange: undefined,\n onStaticPinPositionMove: undefined,\n animatePin: true,\n disablePanOnInitialZoom: false,\n };\n\n private panAnim = new Animated.ValueXY({ x: 0, y: 0 });\n private zoomAnim = new Animated.Value(1);\n private pinAnim = new Animated.ValueXY({ x: 0, y: 0 });\n\n private __offsets = {\n x: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n y: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n };\n\n private zoomLevel = 1;\n private lastGestureCenterPosition: { x: number; y: number } | null = null;\n private lastGestureTouchDistance: number | null = null;\n private gestureType: 'pinch' | 'shift' | null;\n\n private _gestureStarted = false;\n private set gestureStarted(v: boolean) {\n this._gestureStarted = v;\n }\n\n public get gestureStarted() {\n return this._gestureStarted;\n }\n\n /**\n * Last press time (used to evaluate whether user double tapped)\n * @type {number}\n */\n private longPressTimeout: NodeJS.Timeout | null = null;\n private onTransformInvocationInitialized: boolean | undefined;\n private singleTapTimeoutId: NodeJS.Timeout | undefined;\n private touches: TouchPoint[] = [];\n private doubleTapFirstTap: TouchPoint | undefined;\n private measureZoomSubjectInterval: NodeJS.Timer | undefined;\n\n constructor(props: ReactNativeZoomableViewProps) {\n super(props);\n // This needs to be done before anything else to initialize the state.\n // Otherwise, the logic below may reference the state when it's undefined,\n // causing runtime errors.\n this.state = { ...initialState };\n\n this.gestureHandlers = PanResponder.create({\n onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,\n onPanResponderGrant: this._handlePanResponderGrant,\n onPanResponderMove: this._handlePanResponderMove,\n onPanResponderRelease: this._handlePanResponderEnd,\n onPanResponderTerminate: (evt, gestureState) => {\n // We should also call _handlePanResponderEnd\n // to properly perform cleanups when the gesture is terminated\n // (aka gesture handling responsibility is taken over by another component).\n // This also fixes a weird issue where\n // on real device, sometimes onPanResponderRelease is not called when you lift 2 fingers up,\n // but onPanResponderTerminate is called instead for no apparent reason.\n this._handlePanResponderEnd(evt, gestureState);\n this.props.onPanResponderTerminate?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n );\n },\n onPanResponderTerminationRequest: (evt, gestureState) =>\n !!this.props.onPanResponderTerminationRequest?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ),\n // Defaults to true to prevent parent components, such as React Navigation's tab view, from taking over as responder.\n onShouldBlockNativeResponder: (evt, gestureState) =>\n this.props.onShouldBlockNativeResponder?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ) ?? true,\n onStartShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onStartShouldSetPanResponderCapture?.(evt, gestureState),\n onMoveShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onMoveShouldSetPanResponderCapture?.(evt, gestureState),\n });\n\n this.zoomSubjectWrapperRef = createRef();\n\n if (this.props.zoomAnimatedValue)\n this.zoomAnim = this.props.zoomAnimatedValue;\n if (this.props.panAnimatedValueXY)\n this.panAnim = this.props.panAnimatedValueXY;\n\n if (this.props.initialZoom) this.zoomLevel = this.props.initialZoom;\n if (this.props.initialOffsetX != null)\n this.offsetX = this.props.initialOffsetX;\n if (this.props.initialOffsetY != null)\n this.offsetY = this.props.initialOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n this.panAnim.addListener(({ x, y }) => {\n this.offsetX = x;\n this.offsetY = y;\n });\n this.zoomAnim.addListener(({ value }) => {\n this.zoomLevel = value;\n });\n\n this.lastGestureTouchDistance = 150;\n\n this.gestureType = null;\n }\n\n private raisePin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: -10 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private dropPin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: 0 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private set offsetX(x: number) {\n this.__setOffset('x', x);\n }\n\n private set offsetY(y: number) {\n this.__setOffset('y', y);\n }\n\n private get offsetX() {\n return this.__getOffset('x');\n }\n\n private get offsetY() {\n return this.__getOffset('y');\n }\n\n private __setOffset(axis: 'x' | 'y', offset: number) {\n const offsetState = this.__offsets[axis];\n\n if (this.props.bindToBorders) {\n const containerSize =\n axis === 'x' ? this.state.originalWidth : this.state.originalHeight;\n const contentSize =\n axis === 'x'\n ? this.props.contentWidth || this.state.originalWidth\n : this.props.contentHeight || this.state.originalHeight;\n\n const boundOffset =\n contentSize && containerSize && this.props.panBoundaryPadding != null\n ? applyPanBoundariesToOffset(\n offset,\n containerSize,\n contentSize,\n this.zoomLevel,\n this.props.panBoundaryPadding\n )\n : offset;\n\n if (!this.gestureType && !offsetState.boundaryCrossedAnimInEffect) {\n const boundariesApplied =\n boundOffset !== offset &&\n boundOffset.toFixed(3) !== offset.toFixed(3);\n if (boundariesApplied) {\n offsetState.boundaryCrossedAnimInEffect = true;\n getBoundaryCrossedAnim(this.panAnim[axis], boundOffset).start(() => {\n offsetState.boundaryCrossedAnimInEffect = false;\n });\n return;\n }\n }\n }\n\n offsetState.value = offset;\n }\n\n private __getOffset(axis: 'x' | 'y') {\n return this.__offsets[axis].value;\n }\n\n componentDidUpdate(\n prevProps: ReactNativeZoomableViewProps,\n prevState: ReactNativeZoomableViewState\n ) {\n const { zoomEnabled, initialZoom } = this.props;\n if (prevProps.zoomEnabled && !zoomEnabled && initialZoom) {\n this.zoomLevel = initialZoom;\n this.zoomAnim.setValue(this.zoomLevel);\n }\n if (\n !this.onTransformInvocationInitialized &&\n this._invokeOnTransform().successful\n ) {\n this.panAnim.addListener(() => this._invokeOnTransform());\n this.zoomAnim.addListener(() => this._invokeOnTransform());\n this.onTransformInvocationInitialized = true;\n }\n\n const currState = this.state;\n const originalMeasurementsChanged =\n currState.originalHeight !== prevState.originalHeight ||\n currState.originalWidth !== prevState.originalWidth ||\n currState.originalPageX !== prevState.originalPageX ||\n currState.originalPageY !== prevState.originalPageY;\n\n const staticPinPositionChanged =\n prevProps.staticPinPosition?.x !== this.props.staticPinPosition?.x ||\n prevProps.staticPinPosition?.y !== this.props.staticPinPosition?.y;\n\n if (\n this.onTransformInvocationInitialized &&\n (originalMeasurementsChanged || staticPinPositionChanged)\n ) {\n this._invokeOnTransform();\n }\n }\n\n componentDidMount() {\n this.grabZoomSubjectOriginalMeasurements();\n // We've already run `grabZoomSubjectOriginalMeasurements` at various events\n // to make sure the measurements are promptly updated.\n // However, there might be cases we haven't accounted for, especially when\n // native processes are involved. To account for those cases,\n // we'll use an interval here to ensure we're always up-to-date.\n // The `setState` in `grabZoomSubjectOriginalMeasurements` won't trigger a rerender\n // if the values given haven't changed, so we're not running performance risk here.\n this.measureZoomSubjectInterval = setInterval(\n this.grabZoomSubjectOriginalMeasurements,\n 1e3\n );\n }\n\n componentWillUnmount() {\n this.measureZoomSubjectInterval &&\n clearInterval(this.measureZoomSubjectInterval);\n }\n\n debouncedOnStaticPinPositionChange = debounce(\n (position: Vec2D) => this.props.onStaticPinPositionChange?.(position),\n 100\n );\n\n /**\n * try to invoke onTransform\n * @private\n */\n _invokeOnTransform() {\n const zoomableViewEvent = this._getZoomableViewEventObject();\n const position = this._staticPinPosition();\n\n if (!zoomableViewEvent.originalWidth || !zoomableViewEvent.originalHeight)\n return { successful: false };\n\n this.props.onTransform?.(zoomableViewEvent);\n\n if (position) {\n this.props.onStaticPinPositionMove?.(position);\n this.debouncedOnStaticPinPositionChange(position);\n }\n\n return { successful: true };\n }\n\n /**\n * Returns additional information about components current state for external event hooks\n *\n * @returns {{}}\n * @private\n */\n _getZoomableViewEventObject(overwriteObj = {}): ZoomableViewEvent {\n return {\n zoomLevel: this.zoomLevel,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n originalHeight: this.state.originalHeight,\n originalWidth: this.state.originalWidth,\n originalPageX: this.state.originalPageX,\n originalPageY: this.state.originalPageY,\n ...overwriteObj,\n } as ZoomableViewEvent;\n }\n\n /**\n * Get the original box dimensions and save them for later use.\n * (They will be used to calculate boxBorders)\n *\n * @private\n */\n private grabZoomSubjectOriginalMeasurements = () => {\n // make sure we measure after animations are complete\n requestAnimationFrame(() => {\n // this setTimeout is here to fix a weird issue on iOS where the measurements are all `0`\n // when navigating back (react-navigation stack) from another view\n // while closing the keyboard at the same time\n setTimeout(() => {\n // In normal conditions, we're supposed to measure zoomSubject instead of its wrapper.\n // However, our zoomSubject may have been transformed by an initial zoomLevel or offset,\n // in which case these measurements will not represent the true \"original\" measurements.\n // We just need to make sure the zoomSubjectWrapper perfectly aligns with the zoomSubject\n // (no border, space, or anything between them)\n const zoomSubjectWrapperRef = this.zoomSubjectWrapperRef;\n // we don't wanna measure when zoomSubjectWrapperRef is not yet available or has been unmounted\n zoomSubjectWrapperRef.current?.measureInWindow(\n (x, y, width, height) => {\n // When the component is off-screen, these become all 0s, so we don't set them\n // to avoid messing up calculations, especially ones that are done right after\n // the component transitions from hidden to visible.\n if (!x && !y && !width && !height) return;\n\n // If these values are all the same, don't re-set them in state\n // this way we don't re-render\n if (\n this.state.originalWidth === width &&\n this.state.originalHeight === height &&\n this.state.originalPageX === x &&\n this.state.originalPageY === y\n ) {\n return;\n }\n\n this.setState({\n originalWidth: width,\n originalHeight: height,\n originalPageX: x,\n originalPageY: y,\n });\n }\n );\n });\n });\n };\n\n /**\n * Handles the start of touch events and checks for taps\n *\n * @param e\n * @param gestureState\n * @returns {boolean}\n *\n * @private\n */\n _handleStartShouldSetPanResponder = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onStartShouldSetPanResponder) {\n this.props.onStartShouldSetPanResponder(\n e,\n gestureState,\n this._getZoomableViewEventObject(),\n false\n );\n }\n\n // Always set pan responder on start\n // of gesture so we can handle tap.\n // \"Pan threshold validation\" will be handled\n // in `onPanResponderMove` instead of in `onMoveShouldSetPanResponder`\n return true;\n };\n\n /**\n * Calculates pinch distance\n *\n * @param e\n * @param gestureState\n * @private\n */\n _handlePanResponderGrant: NonNullable<\n PanResponderCallbacks['onPanResponderGrant']\n > = (e, gestureState) => {\n if (this.props.onLongPress) {\n this.longPressTimeout = setTimeout(() => {\n this.props.onLongPress?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n this.longPressTimeout = null;\n }, this.props.longPressDuration);\n }\n\n this.props.onPanResponderGrant?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n this.panAnim.stopAnimation();\n this.zoomAnim.stopAnimation();\n this.gestureStarted = true;\n\n this.raisePin();\n };\n\n /**\n * Handles the end of touch events\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderEnd: NonNullable<\n PanResponderCallbacks['onPanResponderEnd']\n > = (e, gestureState) => {\n if (!this.gestureType) {\n this._resolveAndHandleTap(e);\n }\n\n this.setState({ debugPoints: [] });\n\n this.lastGestureCenterPosition = null;\n\n const disableMomentum =\n this.props.disableMomentum ||\n (this.props.panEnabled &&\n this.gestureType === 'shift' &&\n this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom);\n\n // Trigger final shift animation unless disablePanOnInitialZoom is set and we're on the initial zoom level\n // or disableMomentum\n if (!disableMomentum) {\n getPanMomentumDecayAnim(this.panAnim, {\n x: gestureState.vx / this.zoomLevel,\n y: gestureState.vy / this.zoomLevel,\n }).start();\n }\n\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n this.props.onPanResponderEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n if (this.gestureType === 'pinch') {\n this.props.onZoomEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n } else if (this.gestureType === 'shift') {\n this.props.onShiftingEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n if (this.props.staticPinPosition) {\n this._updateStaticPin();\n }\n\n this.dropPin();\n\n this.gestureType = null;\n this.gestureStarted = false;\n };\n\n /**\n * Handles the actual movement of our pan responder\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderMove = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onPanResponderMove) {\n if (\n this.props.onPanResponderMove(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return false;\n }\n }\n\n // Only supports 2 touches and below,\n // any invalid number will cause the gesture to end.\n if (gestureState.numberActiveTouches <= 2) {\n if (!this.gestureStarted) {\n this._handlePanResponderGrant(e, gestureState);\n }\n } else {\n if (this.gestureStarted) {\n this._handlePanResponderEnd(e, gestureState);\n }\n return true;\n }\n\n if (gestureState.numberActiveTouches === 2) {\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'pinch') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n this.lastGestureTouchDistance = calcGestureTouchDistance(\n e,\n gestureState\n );\n }\n this.gestureType = 'pinch';\n this._handlePinching(e, gestureState);\n } else if (gestureState.numberActiveTouches === 1) {\n if (\n this.longPressTimeout &&\n (Math.abs(gestureState.dx) > 5 || Math.abs(gestureState.dy) > 5)\n ) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'shift') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n }\n\n const { dx, dy } = gestureState;\n const isShiftGesture = Math.abs(dx) > 2 || Math.abs(dy) > 2;\n if (isShiftGesture) {\n this.gestureType = 'shift';\n this._handleShifting(gestureState);\n }\n }\n };\n\n /**\n * Handles the pinch movement and zooming\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePinching(\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) {\n if (!this.props.zoomEnabled) return;\n\n const {\n maxZoom,\n minZoom,\n pinchToZoomInSensitivity,\n pinchToZoomOutSensitivity,\n } = this.props;\n\n const distance = calcGestureTouchDistance(e, gestureState);\n\n if (\n this.props.onZoomBefore &&\n this.props.onZoomBefore(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return;\n }\n\n if (!distance) return;\n if (!this.lastGestureTouchDistance) return;\n\n // define the new zoom level and take zoom level sensitivity into consideration\n const zoomGrowthFromLastGestureState =\n distance / this.lastGestureTouchDistance;\n this.lastGestureTouchDistance = distance;\n\n const pinchToZoomSensitivity =\n zoomGrowthFromLastGestureState < 1\n ? pinchToZoomOutSensitivity\n : pinchToZoomInSensitivity;\n\n if (pinchToZoomSensitivity == null) return;\n const deltaGrowth = zoomGrowthFromLastGestureState - 1;\n // 0 - no resistance\n // 10 - 90% resistance\n const deltaGrowthAdjustedBySensitivity =\n deltaGrowth * (1 - (pinchToZoomSensitivity * 9) / 100);\n\n let newZoomLevel = this.zoomLevel * (1 + deltaGrowthAdjustedBySensitivity);\n\n // make sure max and min zoom levels are respected\n if (maxZoom != null && newZoomLevel > maxZoom) {\n newZoomLevel = maxZoom;\n }\n\n if (minZoom != null && newZoomLevel < minZoom) {\n newZoomLevel = minZoom;\n }\n\n const gestureCenterPoint = calcGestureCenterPoint(e, gestureState);\n\n if (!gestureCenterPoint) return;\n\n let zoomCenter = {\n x: gestureCenterPoint.x - this.state.originalPageX,\n y: gestureCenterPoint.y - this.state.originalPageY,\n };\n\n if (this.props.staticPinPosition) {\n // When we use a static pin position, the zoom centre is the same as that position,\n // otherwise the pin moves around way too much while zooming.\n zoomCenter = {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n };\n }\n\n // Uncomment to debug\n this.props.debug && this._setPinchDebugPoints(e, zoomCenter);\n\n const { originalHeight, originalWidth } = this.state;\n\n const oldOffsetX = this.offsetX;\n const oldOffsetY = this.offsetY;\n const oldScale = this.zoomLevel;\n const newScale = newZoomLevel;\n\n if (!originalHeight || !originalWidth) return;\n\n let offsetY = calcNewScaledOffsetForZoomCentering(\n oldOffsetY,\n originalHeight,\n oldScale,\n newScale,\n zoomCenter.y\n );\n let offsetX = calcNewScaledOffsetForZoomCentering(\n oldOffsetX,\n originalWidth,\n oldScale,\n newScale,\n zoomCenter.x\n );\n\n const offsetShift =\n this._calcOffsetShiftSinceLastGestureState(gestureCenterPoint);\n if (offsetShift) {\n offsetX += offsetShift.x;\n offsetY += offsetShift.y;\n }\n\n this.offsetX = offsetX;\n this.offsetY = offsetY;\n this.zoomLevel = newScale;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n this.props.onZoomAfter?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n /**\n * Used to debug pinch events\n * @param gestureResponderEvent\n * @param zoomCenter\n * @param points\n */\n _setPinchDebugPoints(\n gestureResponderEvent: GestureResponderEvent,\n zoomCenter: Vec2D,\n ...points: Vec2D[]\n ) {\n const { touches } = gestureResponderEvent.nativeEvent;\n const { originalPageY, originalPageX } = this.state;\n\n this.setState({\n debugPoints: [\n {\n x: touches[0].pageX - originalPageX,\n y: touches[0].pageY - originalPageY,\n },\n {\n x: touches[1].pageX - originalPageX,\n y: touches[1].pageY - originalPageY,\n },\n zoomCenter,\n ...points,\n ],\n });\n }\n\n /**\n * Calculates the amount the offset should shift since the last position during panning\n *\n * @param {Vec2D} gestureCenterPoint\n *\n * @private\n */\n _calcOffsetShiftSinceLastGestureState(gestureCenterPoint: Vec2D) {\n const { movementSensibility } = this.props;\n\n let shift = null;\n\n if (this.lastGestureCenterPosition && movementSensibility) {\n const dx = gestureCenterPoint.x - this.lastGestureCenterPosition.x;\n const dy = gestureCenterPoint.y - this.lastGestureCenterPosition.y;\n\n const shiftX = dx / this.zoomLevel / movementSensibility;\n const shiftY = dy / this.zoomLevel / movementSensibility;\n\n shift = {\n x: shiftX,\n y: shiftY,\n };\n }\n\n this.lastGestureCenterPosition = gestureCenterPoint;\n\n return shift;\n }\n\n /**\n * Handles movement by tap and move\n *\n * @param gestureState\n *\n * @private\n */\n _handleShifting(gestureState: PanResponderGestureState) {\n // Skips shifting if panEnabled is false or disablePanOnInitialZoom is true and we're on the initial zoom level\n if (\n !this.props.panEnabled ||\n (this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom)\n ) {\n return;\n }\n const shift = this._calcOffsetShiftSinceLastGestureState({\n x: gestureState.moveX,\n y: gestureState.moveY,\n });\n if (!shift) return;\n\n const offsetX = this.offsetX + shift.x;\n const offsetY = this.offsetY + shift.y;\n\n if (\n this.props.debug &&\n this.state.originalPageX &&\n this.state.originalPageY\n ) {\n const x = gestureState.moveX - this.state.originalPageX;\n const y = gestureState.moveY - this.state.originalPageY;\n this.setState({ debugPoints: [{ x, y }] });\n }\n\n this._setNewOffsetPosition(offsetX, offsetY);\n\n this.raisePin();\n }\n\n /**\n * Set the state to offset moved\n *\n * @param {number} newOffsetX\n * @param {number} newOffsetY\n * @returns\n */\n _setNewOffsetPosition(newOffsetX: number, newOffsetY: number) {\n const { onShiftingBefore, onShiftingAfter } = this.props;\n\n if (onShiftingBefore?.(null, null, this._getZoomableViewEventObject())) {\n return;\n }\n\n this.offsetX = newOffsetX;\n this.offsetY = newOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n onShiftingAfter?.(null, null, this._getZoomableViewEventObject());\n }\n\n /**\n * Check whether the press event is double tap\n * or single tap and handle the event accordingly\n *\n * @param e\n *\n * @private\n */\n private _resolveAndHandleTap = (e: GestureResponderEvent) => {\n const now = Date.now();\n if (\n this.doubleTapFirstTapReleaseTimestamp &&\n this.props.doubleTapDelay &&\n now - this.doubleTapFirstTapReleaseTimestamp < this.props.doubleTapDelay\n ) {\n this.doubleTapFirstTap &&\n this._addTouch({\n ...this.doubleTapFirstTap,\n id: now.toString(),\n isSecondTap: true,\n });\n this.singleTapTimeoutId && clearTimeout(this.singleTapTimeoutId);\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n delete this.doubleTapFirstTap;\n this._handleDoubleTap(e);\n } else {\n this.doubleTapFirstTapReleaseTimestamp = now;\n this.doubleTapFirstTap = {\n id: now.toString(),\n x: e.nativeEvent.pageX - this.state.originalPageX,\n y: e.nativeEvent.pageY - this.state.originalPageY,\n };\n this._addTouch(this.doubleTapFirstTap);\n\n // persist event so e.nativeEvent is preserved after a timeout delay\n e.persist();\n this.singleTapTimeoutId = setTimeout(() => {\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n\n // Pan to the tapped location\n if (this.props.staticPinPosition && this.doubleTapFirstTap) {\n const tapX =\n this.props.staticPinPosition.x - this.doubleTapFirstTap.x;\n const tapY =\n this.props.staticPinPosition.y - this.doubleTapFirstTap.y;\n\n Animated.timing(this.panAnim, {\n toValue: {\n x: this.offsetX + tapX / this.zoomLevel,\n y: this.offsetY + tapY / this.zoomLevel,\n },\n useNativeDriver: true,\n duration: 200,\n }).start(() => {\n this._updateStaticPin();\n });\n }\n\n this.props.onSingleTap?.(e, this._getZoomableViewEventObject());\n }, this.props.doubleTapDelay);\n }\n };\n\n moveStaticPinTo = (position: Vec2D, duration?: number) => {\n const { originalWidth, originalHeight } = this.state;\n const { staticPinPosition, contentWidth, contentHeight } = this.props;\n\n if (!staticPinPosition) return;\n if (!originalWidth || !originalHeight) return;\n if (!contentWidth || !contentHeight) return;\n\n // Offset for the static pin\n const pinX = staticPinPosition.x - originalWidth / 2;\n const pinY = staticPinPosition.y - originalHeight / 2;\n\n this.offsetX = contentWidth / 2 - position.x + pinX / this.zoomLevel;\n this.offsetY = contentHeight / 2 - position.y + pinY / this.zoomLevel;\n\n if (duration) {\n Animated.timing(this.panAnim, {\n toValue: { x: this.offsetX, y: this.offsetY },\n useNativeDriver: true,\n duration,\n }).start();\n } else {\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n }\n };\n\n private _staticPinPosition = () => {\n if (!this.props.staticPinPosition) return;\n if (!this.props.contentWidth || !this.props.contentHeight) return;\n\n return viewportPositionToImagePosition({\n viewportPosition: {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n },\n imageSize: {\n height: this.props.contentHeight,\n width: this.props.contentWidth,\n },\n zoomableEvent: {\n ...this._getZoomableViewEventObject(),\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n zoomLevel: this.zoomLevel,\n },\n });\n };\n\n private _updateStaticPin = () => {\n const position = this._staticPinPosition();\n if (!position) return;\n this.props.onStaticPinPositionChange?.(position);\n };\n\n private _addTouch(touch: TouchPoint) {\n this.touches.push(touch);\n this.setState({ touches: [...this.touches] });\n }\n\n private _removeTouch(touch: TouchPoint) {\n this.touches.splice(this.touches.indexOf(touch), 1);\n this.setState({ touches: [...this.touches] });\n }\n\n /**\n * Handles the double tap event\n *\n * @param e\n *\n * @private\n */\n _handleDoubleTap(e: GestureResponderEvent) {\n const { onDoubleTapBefore, onDoubleTapAfter, doubleTapZoomToCenter } =\n this.props;\n\n onDoubleTapBefore?.(e, this._getZoomableViewEventObject());\n\n const nextZoomStep = this._getNextZoomStep();\n if (nextZoomStep == null) return;\n\n const { originalPageX, originalPageY } = this.state;\n\n // define new zoom position coordinates\n const zoomPositionCoordinates = {\n x: e.nativeEvent.pageX - originalPageX,\n y: e.nativeEvent.pageY - originalPageY,\n };\n\n // if doubleTapZoomToCenter enabled -> always zoom to center instead\n if (doubleTapZoomToCenter) {\n zoomPositionCoordinates.x = 0;\n zoomPositionCoordinates.y = 0;\n }\n\n this.zoomTo(nextZoomStep, zoomPositionCoordinates);\n\n onDoubleTapAfter?.(\n e,\n this._getZoomableViewEventObject({ zoomLevel: nextZoomStep })\n );\n }\n\n /**\n * Returns the next zoom step based on current step and zoomStep property.\n * If we are zoomed all the way in -> return to initialzoom\n *\n * @returns {*}\n */\n _getNextZoomStep() {\n const { zoomStep, maxZoom, initialZoom } = this.props;\n const { zoomLevel } = this;\n\n if (maxZoom == null) return;\n\n if (zoomLevel.toFixed(2) === maxZoom.toFixed(2)) {\n return initialZoom;\n }\n\n if (zoomStep == null) return;\n\n const nextZoomStep = zoomLevel * (1 + zoomStep);\n if (nextZoomStep > maxZoom) {\n return maxZoom;\n }\n\n return nextZoomStep;\n }\n\n /**\n * Zooms to a specific level. A \"zoom center\" can be provided, which specifies\n * the point that will remain in the same position on the screen after the zoom.\n * The coordinates of the zoom center is relative to the zoom subject.\n * { x: 0, y: 0 } is the very center of the zoom subject.\n *\n * @param newZoomLevel\n * @param zoomCenter\n */\n zoomTo(newZoomLevel: number, zoomCenter?: Vec2D) {\n if (!this.props.zoomEnabled) return false;\n if (this.props.maxZoom && newZoomLevel > this.props.maxZoom) return false;\n if (this.props.minZoom && newZoomLevel < this.props.minZoom) return false;\n\n this.props.onZoomBefore?.(null, null, this._getZoomableViewEventObject());\n\n // == Perform Pan Animation to preserve the zoom center while zooming ==\n let listenerId: string | undefined;\n if (zoomCenter) {\n // Calculates panAnim values based on changes in zoomAnim.\n let prevScale = this.zoomLevel;\n // Since zoomAnim is calculated in native driver,\n // it will jitter panAnim once in a while,\n // because here panAnim is being calculated in js.\n // However the jittering should mostly occur in simulator.\n listenerId = this.zoomAnim.addListener(({ value: newScale }) => {\n this.panAnim.setValue({\n x: calcNewScaledOffsetForZoomCentering(\n this.offsetX,\n this.state.originalWidth,\n prevScale,\n newScale,\n zoomCenter.x\n ),\n y: calcNewScaledOffsetForZoomCentering(\n this.offsetY,\n this.state.originalHeight,\n prevScale,\n newScale,\n zoomCenter.y\n ),\n });\n prevScale = newScale;\n });\n }\n\n // == Perform Zoom Animation ==\n getZoomToAnimation(this.zoomAnim, newZoomLevel).start(() => {\n if (!listenerId) return;\n this.zoomAnim.removeListener(listenerId);\n });\n // == Zoom Animation Ends ==\n\n this.props.onZoomAfter?.(null, null, this._getZoomableViewEventObject());\n return true;\n }\n\n /**\n * Zooms in or out by a specified change level\n * Use a positive number for `zoomLevelChange` to zoom in\n * Use a negative number for `zoomLevelChange` to zoom out\n *\n * Returns a promise if everything was updated and a boolean, whether it could be updated or if it exceeded the min/max zoom limits.\n *\n * @param {number | null} zoomLevelChange\n *\n * @return {bool}\n */\n zoomBy(zoomLevelChange: number) {\n // if no zoom level Change given -> just use zoom step\n zoomLevelChange ||= this.props.zoomStep || 0;\n return this.zoomTo(this.zoomLevel + zoomLevelChange);\n }\n\n /**\n * Moves the zoomed view to a specified position\n * Returns a promise when finished\n *\n * @param {number} newOffsetX the new position we want to move it to (x-axis)\n * @param {number} newOffsetY the new position we want to move it to (y-axis)\n *\n * @return {bool}\n */\n moveTo(newOffsetX: number, newOffsetY: number) {\n const { originalWidth, originalHeight } = this.state;\n if (!originalWidth || !originalHeight) return;\n\n const offsetX = (newOffsetX - originalWidth / 2) / this.zoomLevel;\n const offsetY = (newOffsetY - originalHeight / 2) / this.zoomLevel;\n\n this._setNewOffsetPosition(-offsetX, -offsetY);\n }\n\n /**\n * Moves the zoomed view by a certain amount.\n *\n * Returns a promise when finished\n *\n * @param {number} offsetChangeX the amount we want to move the offset by (x-axis)\n * @param {number} offsetChangeY the amount we want to move the offset by (y-axis)\n *\n * @return {bool}\n */\n moveBy(offsetChangeX: number, offsetChangeY: number) {\n const offsetX =\n (this.offsetX * this.zoomLevel - offsetChangeX) / this.zoomLevel;\n const offsetY =\n (this.offsetY * this.zoomLevel - offsetChangeY) / this.zoomLevel;\n\n this._setNewOffsetPosition(offsetX, offsetY);\n }\n\n render() {\n const {\n staticPinIcon,\n children,\n visualTouchFeedbackEnabled,\n doubleTapDelay,\n staticPinPosition,\n onStaticPinLongPress,\n onStaticPinPress,\n pinProps,\n } = this.props;\n const { pinSize, touches, debugPoints = [] } = this.state;\n\n return (\n {\n this.props.onLayout?.(event);\n this.grabZoomSubjectOriginalMeasurements();\n }}\n >\n \n {children}\n \n\n {visualTouchFeedbackEnabled &&\n touches?.map(\n (touch) =>\n doubleTapDelay && (\n {\n this._removeTouch(touch);\n }}\n />\n )\n )}\n\n {/* For Debugging Only */}\n {debugPoints.map(({ x, y }, index) => {\n return ;\n })}\n\n {staticPinPosition && (\n {\n this.setState({ pinSize: size });\n }}\n pinProps={pinProps}\n />\n )}\n \n );\n }\n}\n\nconst styles = StyleSheet.create({\n container: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n overflow: 'hidden',\n position: 'relative',\n },\n zoomSubject: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n width: '100%',\n },\n});\n\nexport default ReactNativeZoomableView;\n\nexport { ReactNativeZoomableView };\n"]} \ No newline at end of file +{"version":3,"sources":["ReactNativeZoomableView.tsx"],"names":["initialState","originalWidth","originalHeight","originalPageX","originalPageY","pinSize","width","height","ReactNativeZoomableView","Component","gestureStarted","v","_gestureStarted","constructor","props","Animated","ValueXY","x","y","Value","value","boundaryCrossedAnimInEffect","position","onStaticPinPositionChange","requestAnimationFrame","setTimeout","zoomSubjectWrapperRef","current","measureInWindow","state","setState","e","gestureState","onStartShouldSetPanResponder","_getZoomableViewEventObject","onLongPress","longPressTimeout","longPressDuration","onPanResponderGrant","panAnim","stopAnimation","zoomAnim","raisePin","gestureType","_resolveAndHandleTap","debugPoints","lastGestureCenterPosition","disableMomentum","panEnabled","disablePanOnInitialZoom","zoomLevel","initialZoom","vx","vy","start","clearTimeout","onPanResponderEnd","onZoomEnd","onShiftingEnd","staticPinPosition","_updateStaticPin","dropPin","onPanResponderMove","numberActiveTouches","_handlePanResponderGrant","_handlePanResponderEnd","lastGestureTouchDistance","_handlePinching","Math","abs","dx","dy","isShiftGesture","_handleShifting","now","Date","doubleTapFirstTapReleaseTimestamp","doubleTapDelay","doubleTapFirstTap","_addTouch","id","toString","isSecondTap","singleTapTimeoutId","_handleDoubleTap","nativeEvent","pageX","pageY","persist","tapX","tapY","timing","toValue","offsetX","offsetY","useNativeDriver","duration","onSingleTap","contentWidth","contentHeight","pinX","pinY","setValue","viewportPosition","imageSize","zoomableEvent","_staticPinPosition","gestureHandlers","PanResponder","create","_handleStartShouldSetPanResponder","_handlePanResponderMove","onPanResponderRelease","onPanResponderTerminate","evt","onPanResponderTerminationRequest","onShouldBlockNativeResponder","onStartShouldSetPanResponderCapture","onMoveShouldSetPanResponderCapture","zoomAnimatedValue","panAnimatedValueXY","initialOffsetX","initialOffsetY","addListener","animatePin","pinAnim","easing","Easing","out","ease","__setOffset","__getOffset","axis","offset","offsetState","__offsets","bindToBorders","containerSize","contentSize","boundOffset","panBoundaryPadding","boundariesApplied","toFixed","componentDidUpdate","prevProps","prevState","zoomEnabled","onTransformInvocationInitialized","_invokeOnTransform","successful","currState","originalMeasurementsChanged","staticPinPositionChanged","componentDidMount","grabZoomSubjectOriginalMeasurements","measureZoomSubjectInterval","setInterval","componentWillUnmount","clearInterval","zoomableViewEvent","onTransform","onStaticPinPositionMove","debouncedOnStaticPinPositionChange","overwriteObj","maxZoom","minZoom","pinchToZoomInSensitivity","pinchToZoomOutSensitivity","distance","onZoomBefore","zoomGrowthFromLastGestureState","pinchToZoomSensitivity","deltaGrowth","deltaGrowthAdjustedBySensitivity","newZoomLevel","gestureCenterPoint","zoomCenter","debug","_setPinchDebugPoints","oldOffsetX","oldOffsetY","oldScale","newScale","offsetShift","_calcOffsetShiftSinceLastGestureState","onZoomAfter","gestureResponderEvent","points","touches","movementSensibility","shift","shiftX","shiftY","moveX","moveY","_setNewOffsetPosition","newOffsetX","newOffsetY","onShiftingBefore","onShiftingAfter","touch","push","_removeTouch","splice","indexOf","onDoubleTapBefore","onDoubleTapAfter","doubleTapZoomToCenter","nextZoomStep","_getNextZoomStep","zoomPositionCoordinates","zoomTo","zoomStep","listenerId","prevScale","removeListener","zoomBy","zoomLevelChange","moveTo","moveBy","offsetChangeX","offsetChangeY","render","staticPinIcon","children","visualTouchFeedbackEnabled","onStaticPinLongPress","onStaticPinPress","pinProps","styles","container","panHandlers","event","onLayout","zoomSubject","style","transform","scale","getTranslateTransform","map","index","size","undefined","StyleSheet","alignItems","flex","justifyContent","overflow"],"mappings":";;;;;;;AAAA;;AACA;;AAqBA;;AACA;;AACA;;AAKA;;AACA;;AACA;;AACA;;AACA;;;;;;;;;;AAMA,MAAMA,YAA0C,GAAG;AACjDC,EAAAA,aAAa,EAAE,CADkC;AAEjDC,EAAAA,cAAc,EAAE,CAFiC;AAGjDC,EAAAA,aAAa,EAAE,CAHkC;AAIjDC,EAAAA,aAAa,EAAE,CAJkC;AAKjDC,EAAAA,OAAO,EAAE;AAAEC,IAAAA,KAAK,EAAE,CAAT;AAAYC,IAAAA,MAAM,EAAE;AAApB;AALwC,CAAnD;;AAQA,MAAMC,uBAAN,SAAsCC,gBAAtC,CAGE;AAsD0B,MAAdC,cAAc,CAACC,CAAD,EAAa;AACrC,SAAKC,eAAL,GAAuBD,CAAvB;AACD;;AAEwB,MAAdD,cAAc,GAAG;AAC1B,WAAO,KAAKE,eAAZ;AACD;AAED;AACF;AACA;AACA;;;AAQEC,EAAAA,WAAW,CAACC,KAAD,EAAsC;AAC/C,UAAMA,KAAN,EAD+C,CAE/C;AACA;AACA;;AAJ+C;;AAAA;;AAAA;;AAAA,qCAxC/B,IAAIC,sBAASC,OAAb,CAAqB;AAAEC,MAAAA,CAAC,EAAE,CAAL;AAAQC,MAAAA,CAAC,EAAE;AAAX,KAArB,CAwC+B;;AAAA,sCAvC9B,IAAIH,sBAASI,KAAb,CAAmB,CAAnB,CAuC8B;;AAAA,qCAtC/B,IAAIJ,sBAASC,OAAb,CAAqB;AAAEC,MAAAA,CAAC,EAAE,CAAL;AAAQC,MAAAA,CAAC,EAAE;AAAX,KAArB,CAsC+B;;AAAA,uCApC7B;AAClBD,MAAAA,CAAC,EAAE;AACDG,QAAAA,KAAK,EAAE,CADN;AAEDC,QAAAA,2BAA2B,EAAE;AAF5B,OADe;AAKlBH,MAAAA,CAAC,EAAE;AACDE,QAAAA,KAAK,EAAE,CADN;AAEDC,QAAAA,2BAA2B,EAAE;AAF5B;AALe,KAoC6B;;AAAA,uCAzB7B,CAyB6B;;AAAA,uDAxBoB,IAwBpB;;AAAA,sDAvBC,IAuBD;;AAAA;;AAAA,6CApBvB,KAoBuB;;AAAA,8CAPC,IAOD;;AAAA;;AAAA;;AAAA,qCAJjB,EAIiB;;AAAA;;AAAA;;AAAA,gEAiNZ,sBAClCC,QAAD;AAAA;;AAAA,sCAAqB,oBAAKR,KAAL,EAAWS,yBAAhC,0DAAqB,wCAAuCD,QAAvC,CAArB;AAAA,KADmC,EAEnC,GAFmC,CAjNY;;AAAA,iEAoQH,MAAM;AAClD;AACAE,MAAAA,qBAAqB,CAAC,MAAM;AAC1B;AACA;AACA;AACAC,QAAAA,UAAU,CAAC,MAAM;AAAA;;AACf;AACA;AACA;AACA;AACA;AACA,gBAAMC,qBAAqB,GAAG,KAAKA,qBAAnC,CANe,CAOf;;AACA,mCAAAA,qBAAqB,CAACC,OAAtB,gFAA+BC,eAA/B,CACE,CAACX,CAAD,EAAIC,CAAJ,EAAOZ,KAAP,EAAcC,MAAd,KAAyB;AACvB;AACA;AACA;AACA,gBAAI,CAACU,CAAD,IAAM,CAACC,CAAP,IAAY,CAACZ,KAAb,IAAsB,CAACC,MAA3B,EAAmC,OAJZ,CAMvB;AACA;;AACA,gBACE,KAAKsB,KAAL,CAAW5B,aAAX,KAA6BK,KAA7B,IACA,KAAKuB,KAAL,CAAW3B,cAAX,KAA8BK,MAD9B,IAEA,KAAKsB,KAAL,CAAW1B,aAAX,KAA6Bc,CAF7B,IAGA,KAAKY,KAAL,CAAWzB,aAAX,KAA6Bc,CAJ/B,EAKE;AACA;AACD;;AAED,iBAAKY,QAAL,CAAc;AACZ7B,cAAAA,aAAa,EAAEK,KADH;AAEZJ,cAAAA,cAAc,EAAEK,MAFJ;AAGZJ,cAAAA,aAAa,EAAEc,CAHH;AAIZb,cAAAA,aAAa,EAAEc;AAJH,aAAd;AAMD,WAxBH;AA0BD,SAlCS,CAAV;AAmCD,OAvCoB,CAArB;AAwCD,KA9SgD;;AAAA,+DAyTb,CAClCa,CADkC,EAElCC,YAFkC,KAG/B;AACH,UAAI,KAAKlB,KAAL,CAAWmB,4BAAf,EAA6C;AAC3C,aAAKnB,KAAL,CAAWmB,4BAAX,CACEF,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF,EAIE,KAJF;AAMD,OARE,CAUH;AACA;AACA;AACA;;;AACA,aAAO,IAAP;AACD,KA3UgD;;AAAA,sDAsV7C,CAACH,CAAD,EAAIC,YAAJ,KAAqB;AAAA;;AACvB,UAAI,KAAKlB,KAAL,CAAWqB,WAAf,EAA4B;AAC1B,aAAKC,gBAAL,GAAwBX,UAAU,CAAC,MAAM;AAAA;;AACvC,wDAAKX,KAAL,EAAWqB,WAAX,mGACEJ,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF;AAKA,eAAKE,gBAAL,GAAwB,IAAxB;AACD,SAPiC,EAO/B,KAAKtB,KAAL,CAAWuB,iBAPoB,CAAlC;AAQD;;AAED,oDAAKvB,KAAL,EAAWwB,mBAAX,mGACEP,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF;AAMA,WAAKK,OAAL,CAAaC,aAAb;AACA,WAAKC,QAAL,CAAcD,aAAd;AACA,WAAK9B,cAAL,GAAsB,IAAtB;AAEA,WAAKgC,QAAL;AACD,KA7WgD;;AAAA,oDAyX7C,CAACX,CAAD,EAAIC,YAAJ,KAAqB;AAAA;;AACvB,UAAI,CAAC,KAAKW,WAAV,EAAuB;AACrB,aAAKC,oBAAL,CAA0Bb,CAA1B;AACD;;AAED,WAAKD,QAAL,CAAc;AAAEe,QAAAA,WAAW,EAAE;AAAf,OAAd;AAEA,WAAKC,yBAAL,GAAiC,IAAjC;AAEA,YAAMC,eAAe,GACnB,KAAKjC,KAAL,CAAWiC,eAAX,IACC,KAAKjC,KAAL,CAAWkC,UAAX,IACC,KAAKL,WAAL,KAAqB,OADtB,IAEC,KAAK7B,KAAL,CAAWmC,uBAFZ,IAGC,KAAKC,SAAL,KAAmB,KAAKpC,KAAL,CAAWqC,WALlC,CATuB,CAgBvB;AACA;;AACA,UAAI,CAACJ,eAAL,EAAsB;AACpB,iDAAwB,KAAKR,OAA7B,EAAsC;AACpCtB,UAAAA,CAAC,EAAEe,YAAY,CAACoB,EAAb,GAAkB,KAAKF,SADU;AAEpChC,UAAAA,CAAC,EAAEc,YAAY,CAACqB,EAAb,GAAkB,KAAKH;AAFU,SAAtC,EAGGI,KAHH;AAID;;AAED,UAAI,KAAKlB,gBAAT,EAA2B;AACzBmB,QAAAA,YAAY,CAAC,KAAKnB,gBAAN,CAAZ;AACA,aAAKA,gBAAL,GAAwB,IAAxB;AACD;;AAED,qDAAKtB,KAAL,EAAW0C,iBAAX,qGACEzB,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF;;AAMA,UAAI,KAAKS,WAAL,KAAqB,OAAzB,EAAkC;AAAA;;AAChC,sDAAK7B,KAAL,EAAW2C,SAAX,mGACE1B,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF;AAKD,OAND,MAMO,IAAI,KAAKS,WAAL,KAAqB,OAAzB,EAAkC;AAAA;;AACvC,sDAAK7B,KAAL,EAAW4C,aAAX,mGACE3B,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF;AAKD;;AAED,UAAI,KAAKpB,KAAL,CAAW6C,iBAAf,EAAkC;AAChC,aAAKC,gBAAL;AACD;;AAED,WAAKC,OAAL;AAEA,WAAKlB,WAAL,GAAmB,IAAnB;AACA,WAAKjC,cAAL,GAAsB,KAAtB;AACD,KAnbgD;;AAAA,qDA6bvB,CACxBqB,CADwB,EAExBC,YAFwB,KAGrB;AACH,UAAI,KAAKlB,KAAL,CAAWgD,kBAAf,EAAmC;AACjC,YACE,KAAKhD,KAAL,CAAWgD,kBAAX,CACE/B,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF,CADF,EAME;AACA,iBAAO,KAAP;AACD;AACF,OAXE,CAaH;AACA;;;AACA,UAAIF,YAAY,CAAC+B,mBAAb,IAAoC,CAAxC,EAA2C;AACzC,YAAI,CAAC,KAAKrD,cAAV,EAA0B;AACxB,eAAKsD,wBAAL,CAA8BjC,CAA9B,EAAiCC,YAAjC;AACD;AACF,OAJD,MAIO;AACL,YAAI,KAAKtB,cAAT,EAAyB;AACvB,eAAKuD,sBAAL,CAA4BlC,CAA5B,EAA+BC,YAA/B;AACD;;AACD,eAAO,IAAP;AACD;;AAED,UAAIA,YAAY,CAAC+B,mBAAb,KAAqC,CAAzC,EAA4C;AAC1C,YAAI,KAAK3B,gBAAT,EAA2B;AACzBmB,UAAAA,YAAY,CAAC,KAAKnB,gBAAN,CAAZ;AACA,eAAKA,gBAAL,GAAwB,IAAxB;AACD,SAJyC,CAM1C;;;AACA,YAAI,KAAKO,WAAL,KAAqB,OAAzB,EAAkC;AAChC,eAAKG,yBAAL,GAAiC,oCAC/Bf,CAD+B,EAE/BC,YAF+B,CAAjC;AAIA,eAAKkC,wBAAL,GAAgC,sCAC9BnC,CAD8B,EAE9BC,YAF8B,CAAhC;AAID;;AACD,aAAKW,WAAL,GAAmB,OAAnB;;AACA,aAAKwB,eAAL,CAAqBpC,CAArB,EAAwBC,YAAxB;AACD,OAnBD,MAmBO,IAAIA,YAAY,CAAC+B,mBAAb,KAAqC,CAAzC,EAA4C;AACjD,YACE,KAAK3B,gBAAL,KACCgC,IAAI,CAACC,GAAL,CAASrC,YAAY,CAACsC,EAAtB,IAA4B,CAA5B,IAAiCF,IAAI,CAACC,GAAL,CAASrC,YAAY,CAACuC,EAAtB,IAA4B,CAD9D,CADF,EAGE;AACAhB,UAAAA,YAAY,CAAC,KAAKnB,gBAAN,CAAZ;AACA,eAAKA,gBAAL,GAAwB,IAAxB;AACD,SAPgD,CAQjD;;;AACA,YAAI,KAAKO,WAAL,KAAqB,OAAzB,EAAkC;AAChC,eAAKG,yBAAL,GAAiC,oCAC/Bf,CAD+B,EAE/BC,YAF+B,CAAjC;AAID;;AAED,cAAM;AAAEsC,UAAAA,EAAF;AAAMC,UAAAA;AAAN,YAAavC,YAAnB;AACA,cAAMwC,cAAc,GAAGJ,IAAI,CAACC,GAAL,CAASC,EAAT,IAAe,CAAf,IAAoBF,IAAI,CAACC,GAAL,CAASE,EAAT,IAAe,CAA1D;;AACA,YAAIC,cAAJ,EAAoB;AAClB,eAAK7B,WAAL,GAAmB,OAAnB;;AACA,eAAK8B,eAAL,CAAqBzC,YAArB;AACD;AACF;AACF,KApgBgD;;AAAA,kDA4wBjBD,CAAD,IAA8B;AAC3D,YAAM2C,GAAG,GAAGC,IAAI,CAACD,GAAL,EAAZ;;AACA,UACE,KAAKE,iCAAL,IACA,KAAK9D,KAAL,CAAW+D,cADX,IAEAH,GAAG,GAAG,KAAKE,iCAAX,GAA+C,KAAK9D,KAAL,CAAW+D,cAH5D,EAIE;AACA,aAAKC,iBAAL,IACE,KAAKC,SAAL,CAAe,EACb,GAAG,KAAKD,iBADK;AAEbE,UAAAA,EAAE,EAAEN,GAAG,CAACO,QAAJ,EAFS;AAGbC,UAAAA,WAAW,EAAE;AAHA,SAAf,CADF;AAMA,aAAKC,kBAAL,IAA2B5B,YAAY,CAAC,KAAK4B,kBAAN,CAAvC;AACA,eAAO,KAAKP,iCAAZ;AACA,eAAO,KAAKO,kBAAZ;AACA,eAAO,KAAKL,iBAAZ;;AACA,aAAKM,gBAAL,CAAsBrD,CAAtB;AACD,OAhBD,MAgBO;AACL,aAAK6C,iCAAL,GAAyCF,GAAzC;AACA,aAAKI,iBAAL,GAAyB;AACvBE,UAAAA,EAAE,EAAEN,GAAG,CAACO,QAAJ,EADmB;AAEvBhE,UAAAA,CAAC,EAAEc,CAAC,CAACsD,WAAF,CAAcC,KAAd,GAAsB,KAAKzD,KAAL,CAAW1B,aAFb;AAGvBe,UAAAA,CAAC,EAAEa,CAAC,CAACsD,WAAF,CAAcE,KAAd,GAAsB,KAAK1D,KAAL,CAAWzB;AAHb,SAAzB;;AAKA,aAAK2E,SAAL,CAAe,KAAKD,iBAApB,EAPK,CASL;;;AACA/C,QAAAA,CAAC,CAACyD,OAAF;AACA,aAAKL,kBAAL,GAA0B1D,UAAU,CAAC,MAAM;AAAA;;AACzC,iBAAO,KAAKmD,iCAAZ;AACA,iBAAO,KAAKO,kBAAZ,CAFyC,CAIzC;;AACA,cAAI,KAAKrE,KAAL,CAAW6C,iBAAX,IAAgC,KAAKmB,iBAAzC,EAA4D;AAC1D,kBAAMW,IAAI,GACR,KAAK3E,KAAL,CAAW6C,iBAAX,CAA6B1C,CAA7B,GAAiC,KAAK6D,iBAAL,CAAuB7D,CAD1D;AAEA,kBAAMyE,IAAI,GACR,KAAK5E,KAAL,CAAW6C,iBAAX,CAA6BzC,CAA7B,GAAiC,KAAK4D,iBAAL,CAAuB5D,CAD1D;;AAGAH,kCAAS4E,MAAT,CAAgB,KAAKpD,OAArB,EAA8B;AAC5BqD,cAAAA,OAAO,EAAE;AACP3E,gBAAAA,CAAC,EAAE,KAAK4E,OAAL,GAAeJ,IAAI,GAAG,KAAKvC,SADvB;AAEPhC,gBAAAA,CAAC,EAAE,KAAK4E,OAAL,GAAeJ,IAAI,GAAG,KAAKxC;AAFvB,eADmB;AAK5B6C,cAAAA,eAAe,EAAE,IALW;AAM5BC,cAAAA,QAAQ,EAAE;AANkB,aAA9B,EAOG1C,KAPH,CAOS,MAAM;AACb,mBAAKM,gBAAL;AACD,aATD;AAUD;;AAED,wDAAK9C,KAAL,EAAWmF,WAAX,mGAAyBlE,CAAzB,EAA4B,KAAKG,2BAAL,EAA5B;AACD,SAxBmC,EAwBjC,KAAKpB,KAAL,CAAW+D,cAxBsB,CAApC;AAyBD;AACF,KAn0BgD;;AAAA,6CAq0B/B,CAACvD,QAAD,EAAkB0E,QAAlB,KAAwC;AACxD,YAAM;AAAE/F,QAAAA,aAAF;AAAiBC,QAAAA;AAAjB,UAAoC,KAAK2B,KAA/C;AACA,YAAM;AAAE8B,QAAAA,iBAAF;AAAqBuC,QAAAA,YAArB;AAAmCC,QAAAA;AAAnC,UAAqD,KAAKrF,KAAhE;AAEA,UAAI,CAAC6C,iBAAL,EAAwB;AACxB,UAAI,CAAC1D,aAAD,IAAkB,CAACC,cAAvB,EAAuC;AACvC,UAAI,CAACgG,YAAD,IAAiB,CAACC,aAAtB,EAAqC,OANmB,CAQxD;;AACA,YAAMC,IAAI,GAAGzC,iBAAiB,CAAC1C,CAAlB,GAAsBhB,aAAa,GAAG,CAAnD;AACA,YAAMoG,IAAI,GAAG1C,iBAAiB,CAACzC,CAAlB,GAAsBhB,cAAc,GAAG,CAApD;AAEA,WAAK2F,OAAL,GAAeK,YAAY,GAAG,CAAf,GAAmB5E,QAAQ,CAACL,CAA5B,GAAgCmF,IAAI,GAAG,KAAKlD,SAA3D;AACA,WAAK4C,OAAL,GAAeK,aAAa,GAAG,CAAhB,GAAoB7E,QAAQ,CAACJ,CAA7B,GAAiCmF,IAAI,GAAG,KAAKnD,SAA5D;;AAEA,UAAI8C,QAAJ,EAAc;AACZjF,8BAAS4E,MAAT,CAAgB,KAAKpD,OAArB,EAA8B;AAC5BqD,UAAAA,OAAO,EAAE;AAAE3E,YAAAA,CAAC,EAAE,KAAK4E,OAAV;AAAmB3E,YAAAA,CAAC,EAAE,KAAK4E;AAA3B,WADmB;AAE5BC,UAAAA,eAAe,EAAE,IAFW;AAG5BC,UAAAA;AAH4B,SAA9B,EAIG1C,KAJH;AAKD,OAND,MAMO;AACL,aAAKf,OAAL,CAAa+D,QAAb,CAAsB;AAAErF,UAAAA,CAAC,EAAE,KAAK4E,OAAV;AAAmB3E,UAAAA,CAAC,EAAE,KAAK4E;AAA3B,SAAtB;AACD;AACF,KA71BgD;;AAAA,gDA+1BpB,MAAM;AACjC,UAAI,CAAC,KAAKhF,KAAL,CAAW6C,iBAAhB,EAAmC;AACnC,UAAI,CAAC,KAAK7C,KAAL,CAAWoF,YAAZ,IAA4B,CAAC,KAAKpF,KAAL,CAAWqF,aAA5C,EAA2D;AAE3D,aAAO,2DAAgC;AACrCI,QAAAA,gBAAgB,EAAE;AAChBtF,UAAAA,CAAC,EAAE,KAAKH,KAAL,CAAW6C,iBAAX,CAA6B1C,CADhB;AAEhBC,UAAAA,CAAC,EAAE,KAAKJ,KAAL,CAAW6C,iBAAX,CAA6BzC;AAFhB,SADmB;AAKrCsF,QAAAA,SAAS,EAAE;AACTjG,UAAAA,MAAM,EAAE,KAAKO,KAAL,CAAWqF,aADV;AAET7F,UAAAA,KAAK,EAAE,KAAKQ,KAAL,CAAWoF;AAFT,SAL0B;AASrCO,QAAAA,aAAa,EAAE,EACb,GAAG,KAAKvE,2BAAL,EADU;AAEb2D,UAAAA,OAAO,EAAE,KAAKA,OAFD;AAGbC,UAAAA,OAAO,EAAE,KAAKA,OAHD;AAIb5C,UAAAA,SAAS,EAAE,KAAKA;AAJH;AATsB,OAAhC,CAAP;AAgBD,KAn3BgD;;AAAA,8CAq3BtB,MAAM;AAAA;;AAC/B,YAAM5B,QAAQ,GAAG,KAAKoF,kBAAL,EAAjB;;AACA,UAAI,CAACpF,QAAL,EAAe;AACf,qDAAKR,KAAL,EAAWS,yBAAX,qGAAuCD,QAAvC;AACD,KAz3BgD;;AAK/C,SAAKO,KAAL,GAAa,EAAE,GAAG7B;AAAL,KAAb;AAEA,SAAK2G,eAAL,GAAuBC,0BAAaC,MAAb,CAAoB;AACzC5E,MAAAA,4BAA4B,EAAE,KAAK6E,iCADM;AAEzCxE,MAAAA,mBAAmB,EAAE,KAAK0B,wBAFe;AAGzCF,MAAAA,kBAAkB,EAAE,KAAKiD,uBAHgB;AAIzCC,MAAAA,qBAAqB,EAAE,KAAK/C,sBAJa;AAKzCgD,MAAAA,uBAAuB,EAAE,CAACC,GAAD,EAAMlF,YAAN,KAAuB;AAAA;;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA,aAAKiC,sBAAL,CAA4BiD,GAA5B,EAAiClF,YAAjC;;AACA,uDAAKlB,KAAL,EAAWmG,uBAAX,qGACEC,GADF,EAEElF,YAFF,EAGE,KAAKE,2BAAL,EAHF;AAKD,OAlBwC;AAmBzCiF,MAAAA,gCAAgC,EAAE,CAACD,GAAD,EAAMlF,YAAN;AAAA;;AAAA,eAChC,CAAC,4BAAC,sBAAKlB,KAAL,EAAWqG,gCAAZ,mDAAC,2CACAD,GADA,EAEAlF,YAFA,EAGA,KAAKE,2BAAL,EAHA,CAAD,CAD+B;AAAA,OAnBO;AAyBzC;AACAkF,MAAAA,4BAA4B,EAAE,CAACF,GAAD,EAAMlF,YAAN;AAAA;;AAAA,kEAC5B,sBAAKlB,KAAL,EAAWsG,4BADiB,2DAC5B,2CACEF,GADF,EAEElF,YAFF,EAGE,KAAKE,2BAAL,EAHF,CAD4B,yEAKvB,IALuB;AAAA,OA1BW;AAgCzCmF,MAAAA,mCAAmC,EAAE,CAACH,GAAD,EAAMlF,YAAN;AAAA;;AAAA,eACnC,CAAC,2BAAC,sBAAKlB,KAAL,EAAWuG,mCAAZ,kDAAC,0CAAiDH,GAAjD,EAAsDlF,YAAtD,CAAD,CADkC;AAAA,OAhCI;AAkCzCsF,MAAAA,kCAAkC,EAAE,CAACJ,GAAD,EAAMlF,YAAN;AAAA;;AAAA,eAClC,CAAC,2BAAC,sBAAKlB,KAAL,EAAWwG,kCAAZ,kDAAC,0CAAgDJ,GAAhD,EAAqDlF,YAArD,CAAD,CADiC;AAAA;AAlCK,KAApB,CAAvB;AAsCA,SAAKN,qBAAL,gBAA6B,uBAA7B;AAEA,QAAI,KAAKZ,KAAL,CAAWyG,iBAAf,EACE,KAAK9E,QAAL,GAAgB,KAAK3B,KAAL,CAAWyG,iBAA3B;AACF,QAAI,KAAKzG,KAAL,CAAW0G,kBAAf,EACE,KAAKjF,OAAL,GAAe,KAAKzB,KAAL,CAAW0G,kBAA1B;AAEF,QAAI,KAAK1G,KAAL,CAAWqC,WAAf,EAA4B,KAAKD,SAAL,GAAiB,KAAKpC,KAAL,CAAWqC,WAA5B;AAC5B,QAAI,KAAKrC,KAAL,CAAW2G,cAAX,IAA6B,IAAjC,EACE,KAAK5B,OAAL,GAAe,KAAK/E,KAAL,CAAW2G,cAA1B;AACF,QAAI,KAAK3G,KAAL,CAAW4G,cAAX,IAA6B,IAAjC,EACE,KAAK5B,OAAL,GAAe,KAAKhF,KAAL,CAAW4G,cAA1B;AAEF,SAAKnF,OAAL,CAAa+D,QAAb,CAAsB;AAAErF,MAAAA,CAAC,EAAE,KAAK4E,OAAV;AAAmB3E,MAAAA,CAAC,EAAE,KAAK4E;AAA3B,KAAtB;AACA,SAAKrD,QAAL,CAAc6D,QAAd,CAAuB,KAAKpD,SAA5B;AACA,SAAKX,OAAL,CAAaoF,WAAb,CAAyB,CAAC;AAAE1G,MAAAA,CAAF;AAAKC,MAAAA;AAAL,KAAD,KAAc;AACrC,WAAK2E,OAAL,GAAe5E,CAAf;AACA,WAAK6E,OAAL,GAAe5E,CAAf;AACD,KAHD;AAIA,SAAKuB,QAAL,CAAckF,WAAd,CAA0B,CAAC;AAAEvG,MAAAA;AAAF,KAAD,KAAe;AACvC,WAAK8B,SAAL,GAAiB9B,KAAjB;AACD,KAFD;AAIA,SAAK8C,wBAAL,GAAgC,GAAhC;AAEA,SAAKvB,WAAL,GAAmB,IAAnB;AACD;;AAEOD,EAAAA,QAAQ,GAAG;AACjB,QAAI,CAAC,KAAK5B,KAAL,CAAW8G,UAAhB,EAA4B;;AAC5B7G,0BAAS4E,MAAT,CAAgB,KAAKkC,OAArB,EAA8B;AAC5BjC,MAAAA,OAAO,EAAE;AAAE3E,QAAAA,CAAC,EAAE,CAAL;AAAQC,QAAAA,CAAC,EAAE,CAAC;AAAZ,OADmB;AAE5B6E,MAAAA,eAAe,EAAE,IAFW;AAG5B+B,MAAAA,MAAM,EAAEC,oBAAOC,GAAP,CAAWD,oBAAOE,IAAlB,CAHoB;AAI5BjC,MAAAA,QAAQ,EAAE;AAJkB,KAA9B,EAKG1C,KALH;AAMD;;AAEOO,EAAAA,OAAO,GAAG;AAChB,QAAI,CAAC,KAAK/C,KAAL,CAAW8G,UAAhB,EAA4B;;AAC5B7G,0BAAS4E,MAAT,CAAgB,KAAKkC,OAArB,EAA8B;AAC5BjC,MAAAA,OAAO,EAAE;AAAE3E,QAAAA,CAAC,EAAE,CAAL;AAAQC,QAAAA,CAAC,EAAE;AAAX,OADmB;AAE5B6E,MAAAA,eAAe,EAAE,IAFW;AAG5B+B,MAAAA,MAAM,EAAEC,oBAAOC,GAAP,CAAWD,oBAAOE,IAAlB,CAHoB;AAI5BjC,MAAAA,QAAQ,EAAE;AAJkB,KAA9B,EAKG1C,KALH;AAMD;;AAEkB,MAAPuC,OAAO,CAAC5E,CAAD,EAAY;AAC7B,SAAKiH,WAAL,CAAiB,GAAjB,EAAsBjH,CAAtB;AACD;;AAEkB,MAAP6E,OAAO,CAAC5E,CAAD,EAAY;AAC7B,SAAKgH,WAAL,CAAiB,GAAjB,EAAsBhH,CAAtB;AACD;;AAEkB,MAAP2E,OAAO,GAAG;AACpB,WAAO,KAAKsC,WAAL,CAAiB,GAAjB,CAAP;AACD;;AAEkB,MAAPrC,OAAO,GAAG;AACpB,WAAO,KAAKqC,WAAL,CAAiB,GAAjB,CAAP;AACD;;AAEOD,EAAAA,WAAW,CAACE,IAAD,EAAkBC,MAAlB,EAAkC;AACnD,UAAMC,WAAW,GAAG,KAAKC,SAAL,CAAeH,IAAf,CAApB;;AAEA,QAAI,KAAKtH,KAAL,CAAW0H,aAAf,EAA8B;AAC5B,YAAMC,aAAa,GACjBL,IAAI,KAAK,GAAT,GAAe,KAAKvG,KAAL,CAAW5B,aAA1B,GAA0C,KAAK4B,KAAL,CAAW3B,cADvD;AAEA,YAAMwI,WAAW,GACfN,IAAI,KAAK,GAAT,GACI,KAAKtH,KAAL,CAAWoF,YAAX,IAA2B,KAAKrE,KAAL,CAAW5B,aAD1C,GAEI,KAAKa,KAAL,CAAWqF,aAAX,IAA4B,KAAKtE,KAAL,CAAW3B,cAH7C;AAKA,YAAMyI,WAAW,GACfD,WAAW,IAAID,aAAf,IAAgC,KAAK3H,KAAL,CAAW8H,kBAAX,IAAiC,IAAjE,GACI,4DACEP,MADF,EAEEI,aAFF,EAGEC,WAHF,EAIE,KAAKxF,SAJP,EAKE,KAAKpC,KAAL,CAAW8H,kBALb,CADJ,GAQIP,MATN;;AAWA,UAAI,CAAC,KAAK1F,WAAN,IAAqB,CAAC2F,WAAW,CAACjH,2BAAtC,EAAmE;AACjE,cAAMwH,iBAAiB,GACrBF,WAAW,KAAKN,MAAhB,IACAM,WAAW,CAACG,OAAZ,CAAoB,CAApB,MAA2BT,MAAM,CAACS,OAAP,CAAe,CAAf,CAF7B;;AAGA,YAAID,iBAAJ,EAAuB;AACrBP,UAAAA,WAAW,CAACjH,2BAAZ,GAA0C,IAA1C;AACA,kDAAuB,KAAKkB,OAAL,CAAa6F,IAAb,CAAvB,EAA2CO,WAA3C,EAAwDrF,KAAxD,CAA8D,MAAM;AAClEgF,YAAAA,WAAW,CAACjH,2BAAZ,GAA0C,KAA1C;AACD,WAFD;AAGA;AACD;AACF;AACF;;AAEDiH,IAAAA,WAAW,CAAClH,KAAZ,GAAoBiH,MAApB;AACD;;AAEOF,EAAAA,WAAW,CAACC,IAAD,EAAkB;AACnC,WAAO,KAAKG,SAAL,CAAeH,IAAf,EAAqBhH,KAA5B;AACD;;AAED2H,EAAAA,kBAAkB,CAChBC,SADgB,EAEhBC,SAFgB,EAGhB;AAAA;;AACA,UAAM;AAAEC,MAAAA,WAAF;AAAe/F,MAAAA;AAAf,QAA+B,KAAKrC,KAA1C;;AACA,QAAIkI,SAAS,CAACE,WAAV,IAAyB,CAACA,WAA1B,IAAyC/F,WAA7C,EAA0D;AACxD,WAAKD,SAAL,GAAiBC,WAAjB;AACA,WAAKV,QAAL,CAAc6D,QAAd,CAAuB,KAAKpD,SAA5B;AACD;;AACD,QACE,CAAC,KAAKiG,gCAAN,IACA,KAAKC,kBAAL,GAA0BC,UAF5B,EAGE;AACA,WAAK9G,OAAL,CAAaoF,WAAb,CAAyB,MAAM,KAAKyB,kBAAL,EAA/B;AACA,WAAK3G,QAAL,CAAckF,WAAd,CAA0B,MAAM,KAAKyB,kBAAL,EAAhC;AACA,WAAKD,gCAAL,GAAwC,IAAxC;AACD;;AAED,UAAMG,SAAS,GAAG,KAAKzH,KAAvB;AACA,UAAM0H,2BAA2B,GAC/BD,SAAS,CAACpJ,cAAV,KAA6B+I,SAAS,CAAC/I,cAAvC,IACAoJ,SAAS,CAACrJ,aAAV,KAA4BgJ,SAAS,CAAChJ,aADtC,IAEAqJ,SAAS,CAACnJ,aAAV,KAA4B8I,SAAS,CAAC9I,aAFtC,IAGAmJ,SAAS,CAAClJ,aAAV,KAA4B6I,SAAS,CAAC7I,aAJxC;AAMA,UAAMoJ,wBAAwB,GAC5B,0BAAAR,SAAS,CAACrF,iBAAV,gFAA6B1C,CAA7B,gCAAmC,KAAKH,KAAL,CAAW6C,iBAA9C,0DAAmC,sBAA8B1C,CAAjE,KACA,2BAAA+H,SAAS,CAACrF,iBAAV,kFAA6BzC,CAA7B,iCAAmC,KAAKJ,KAAL,CAAW6C,iBAA9C,2DAAmC,uBAA8BzC,CAAjE,CAFF;;AAIA,QACE,KAAKiI,gCAAL,KACCI,2BAA2B,IAAIC,wBADhC,CADF,EAGE;AACA,WAAKJ,kBAAL;AACD;AACF;;AAEDK,EAAAA,iBAAiB,GAAG;AAClB,SAAKC,mCAAL,GADkB,CAElB;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,SAAKC,0BAAL,GAAkCC,WAAW,CAC3C,KAAKF,mCADsC,EAE3C,GAF2C,CAA7C;AAID;;AAEDG,EAAAA,oBAAoB,GAAG;AACrB,SAAKF,0BAAL,IACEG,aAAa,CAAC,KAAKH,0BAAN,CADf;AAED;;AAOD;AACF;AACA;AACA;AACEP,EAAAA,kBAAkB,GAAG;AAAA;;AACnB,UAAMW,iBAAiB,GAAG,KAAK7H,2BAAL,EAA1B;;AACA,UAAMZ,QAAQ,GAAG,KAAKoF,kBAAL,EAAjB;;AAEA,QAAI,CAACqD,iBAAiB,CAAC9J,aAAnB,IAAoC,CAAC8J,iBAAiB,CAAC7J,cAA3D,EACE,OAAO;AAAEmJ,MAAAA,UAAU,EAAE;AAAd,KAAP;AAEF,mDAAKvI,KAAL,EAAWkJ,WAAX,oGAAyBD,iBAAzB;;AAEA,QAAIzI,QAAJ,EAAc;AAAA;;AACZ,sDAAKR,KAAL,EAAWmJ,uBAAX,sGAAqC3I,QAArC;AACA,WAAK4I,kCAAL,CAAwC5I,QAAxC;AACD;;AAED,WAAO;AAAE+H,MAAAA,UAAU,EAAE;AAAd,KAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;;;AACEnH,EAAAA,2BAA2B,CAACiI,YAAY,GAAG,EAAhB,EAAuC;AAChE,WAAO;AACLjH,MAAAA,SAAS,EAAE,KAAKA,SADX;AAEL2C,MAAAA,OAAO,EAAE,KAAKA,OAFT;AAGLC,MAAAA,OAAO,EAAE,KAAKA,OAHT;AAIL5F,MAAAA,cAAc,EAAE,KAAK2B,KAAL,CAAW3B,cAJtB;AAKLD,MAAAA,aAAa,EAAE,KAAK4B,KAAL,CAAW5B,aALrB;AAMLE,MAAAA,aAAa,EAAE,KAAK0B,KAAL,CAAW1B,aANrB;AAOLC,MAAAA,aAAa,EAAE,KAAKyB,KAAL,CAAWzB,aAPrB;AAQL,SAAG+J;AARE,KAAP;AAUD;AAED;AACF;AACA;AACA;AACA;AACA;;;AAmQE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACEhG,EAAAA,eAAe,CACbpC,CADa,EAEbC,YAFa,EAGb;AAAA;;AACA,QAAI,CAAC,KAAKlB,KAAL,CAAWoI,WAAhB,EAA6B;AAE7B,UAAM;AACJkB,MAAAA,OADI;AAEJC,MAAAA,OAFI;AAGJC,MAAAA,wBAHI;AAIJC,MAAAA;AAJI,QAKF,KAAKzJ,KALT;AAOA,UAAM0J,QAAQ,GAAG,sCAAyBzI,CAAzB,EAA4BC,YAA5B,CAAjB;;AAEA,QACE,KAAKlB,KAAL,CAAW2J,YAAX,IACA,KAAK3J,KAAL,CAAW2J,YAAX,CACE1I,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF,CAFF,EAOE;AACA;AACD;;AAED,QAAI,CAACsI,QAAL,EAAe;AACf,QAAI,CAAC,KAAKtG,wBAAV,EAAoC,OAxBpC,CA0BA;;AACA,UAAMwG,8BAA8B,GAClCF,QAAQ,GAAG,KAAKtG,wBADlB;AAEA,SAAKA,wBAAL,GAAgCsG,QAAhC;AAEA,UAAMG,sBAAsB,GAC1BD,8BAA8B,GAAG,CAAjC,GACIH,yBADJ,GAEID,wBAHN;AAKA,QAAIK,sBAAsB,IAAI,IAA9B,EAAoC;AACpC,UAAMC,WAAW,GAAGF,8BAA8B,GAAG,CAArD,CArCA,CAsCA;AACA;;AACA,UAAMG,gCAAgC,GACpCD,WAAW,IAAI,IAAKD,sBAAsB,GAAG,CAA1B,GAA+B,GAAvC,CADb;AAGA,QAAIG,YAAY,GAAG,KAAK5H,SAAL,IAAkB,IAAI2H,gCAAtB,CAAnB,CA3CA,CA6CA;;AACA,QAAIT,OAAO,IAAI,IAAX,IAAmBU,YAAY,GAAGV,OAAtC,EAA+C;AAC7CU,MAAAA,YAAY,GAAGV,OAAf;AACD;;AAED,QAAIC,OAAO,IAAI,IAAX,IAAmBS,YAAY,GAAGT,OAAtC,EAA+C;AAC7CS,MAAAA,YAAY,GAAGT,OAAf;AACD;;AAED,UAAMU,kBAAkB,GAAG,oCAAuBhJ,CAAvB,EAA0BC,YAA1B,CAA3B;AAEA,QAAI,CAAC+I,kBAAL,EAAyB;AAEzB,QAAIC,UAAU,GAAG;AACf/J,MAAAA,CAAC,EAAE8J,kBAAkB,CAAC9J,CAAnB,GAAuB,KAAKY,KAAL,CAAW1B,aADtB;AAEfe,MAAAA,CAAC,EAAE6J,kBAAkB,CAAC7J,CAAnB,GAAuB,KAAKW,KAAL,CAAWzB;AAFtB,KAAjB;;AAKA,QAAI,KAAKU,KAAL,CAAW6C,iBAAf,EAAkC;AAChC;AACA;AACAqH,MAAAA,UAAU,GAAG;AACX/J,QAAAA,CAAC,EAAE,KAAKH,KAAL,CAAW6C,iBAAX,CAA6B1C,CADrB;AAEXC,QAAAA,CAAC,EAAE,KAAKJ,KAAL,CAAW6C,iBAAX,CAA6BzC;AAFrB,OAAb;AAID,KAtED,CAwEA;;;AACA,SAAKJ,KAAL,CAAWmK,KAAX,IAAoB,KAAKC,oBAAL,CAA0BnJ,CAA1B,EAA6BiJ,UAA7B,CAApB;AAEA,UAAM;AAAE9K,MAAAA,cAAF;AAAkBD,MAAAA;AAAlB,QAAoC,KAAK4B,KAA/C;AAEA,UAAMsJ,UAAU,GAAG,KAAKtF,OAAxB;AACA,UAAMuF,UAAU,GAAG,KAAKtF,OAAxB;AACA,UAAMuF,QAAQ,GAAG,KAAKnI,SAAtB;AACA,UAAMoI,QAAQ,GAAGR,YAAjB;AAEA,QAAI,CAAC5K,cAAD,IAAmB,CAACD,aAAxB,EAAuC;AAEvC,QAAI6F,OAAO,GAAG,iDACZsF,UADY,EAEZlL,cAFY,EAGZmL,QAHY,EAIZC,QAJY,EAKZN,UAAU,CAAC9J,CALC,CAAd;AAOA,QAAI2E,OAAO,GAAG,iDACZsF,UADY,EAEZlL,aAFY,EAGZoL,QAHY,EAIZC,QAJY,EAKZN,UAAU,CAAC/J,CALC,CAAd;;AAQA,UAAMsK,WAAW,GACf,KAAKC,qCAAL,CAA2CT,kBAA3C,CADF;;AAEA,QAAIQ,WAAJ,EAAiB;AACf1F,MAAAA,OAAO,IAAI0F,WAAW,CAACtK,CAAvB;AACA6E,MAAAA,OAAO,IAAIyF,WAAW,CAACrK,CAAvB;AACD;;AAED,SAAK2E,OAAL,GAAeA,OAAf;AACA,SAAKC,OAAL,GAAeA,OAAf;AACA,SAAK5C,SAAL,GAAiBoI,QAAjB;AAEA,SAAK/I,OAAL,CAAa+D,QAAb,CAAsB;AAAErF,MAAAA,CAAC,EAAE,KAAK4E,OAAV;AAAmB3E,MAAAA,CAAC,EAAE,KAAK4E;AAA3B,KAAtB;AACA,SAAKrD,QAAL,CAAc6D,QAAd,CAAuB,KAAKpD,SAA5B;AAEA,mDAAKpC,KAAL,EAAW2K,WAAX,oGACE1J,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF;AAKD;AAED;AACF;AACA;AACA;AACA;AACA;;;AACEgJ,EAAAA,oBAAoB,CAClBQ,qBADkB,EAElBV,UAFkB,EAGlB,GAAGW,MAHe,EAIlB;AACA,UAAM;AAAEC,MAAAA;AAAF,QAAcF,qBAAqB,CAACrG,WAA1C;AACA,UAAM;AAAEjF,MAAAA,aAAF;AAAiBD,MAAAA;AAAjB,QAAmC,KAAK0B,KAA9C;AAEA,SAAKC,QAAL,CAAc;AACZe,MAAAA,WAAW,EAAE,CACX;AACE5B,QAAAA,CAAC,EAAE2K,OAAO,CAAC,CAAD,CAAP,CAAWtG,KAAX,GAAmBnF,aADxB;AAEEe,QAAAA,CAAC,EAAE0K,OAAO,CAAC,CAAD,CAAP,CAAWrG,KAAX,GAAmBnF;AAFxB,OADW,EAKX;AACEa,QAAAA,CAAC,EAAE2K,OAAO,CAAC,CAAD,CAAP,CAAWtG,KAAX,GAAmBnF,aADxB;AAEEe,QAAAA,CAAC,EAAE0K,OAAO,CAAC,CAAD,CAAP,CAAWrG,KAAX,GAAmBnF;AAFxB,OALW,EASX4K,UATW,EAUX,GAAGW,MAVQ;AADD,KAAd;AAcD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;;;AACEH,EAAAA,qCAAqC,CAACT,kBAAD,EAA4B;AAC/D,UAAM;AAAEc,MAAAA;AAAF,QAA0B,KAAK/K,KAArC;AAEA,QAAIgL,KAAK,GAAG,IAAZ;;AAEA,QAAI,KAAKhJ,yBAAL,IAAkC+I,mBAAtC,EAA2D;AACzD,YAAMvH,EAAE,GAAGyG,kBAAkB,CAAC9J,CAAnB,GAAuB,KAAK6B,yBAAL,CAA+B7B,CAAjE;AACA,YAAMsD,EAAE,GAAGwG,kBAAkB,CAAC7J,CAAnB,GAAuB,KAAK4B,yBAAL,CAA+B5B,CAAjE;AAEA,YAAM6K,MAAM,GAAGzH,EAAE,GAAG,KAAKpB,SAAV,GAAsB2I,mBAArC;AACA,YAAMG,MAAM,GAAGzH,EAAE,GAAG,KAAKrB,SAAV,GAAsB2I,mBAArC;AAEAC,MAAAA,KAAK,GAAG;AACN7K,QAAAA,CAAC,EAAE8K,MADG;AAEN7K,QAAAA,CAAC,EAAE8K;AAFG,OAAR;AAID;;AAED,SAAKlJ,yBAAL,GAAiCiI,kBAAjC;AAEA,WAAOe,KAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;;;AACErH,EAAAA,eAAe,CAACzC,YAAD,EAAyC;AACtD;AACA,QACE,CAAC,KAAKlB,KAAL,CAAWkC,UAAZ,IACC,KAAKlC,KAAL,CAAWmC,uBAAX,IACC,KAAKC,SAAL,KAAmB,KAAKpC,KAAL,CAAWqC,WAHlC,EAIE;AACA;AACD;;AACD,UAAM2I,KAAK,GAAG,KAAKN,qCAAL,CAA2C;AACvDvK,MAAAA,CAAC,EAAEe,YAAY,CAACiK,KADuC;AAEvD/K,MAAAA,CAAC,EAAEc,YAAY,CAACkK;AAFuC,KAA3C,CAAd;;AAIA,QAAI,CAACJ,KAAL,EAAY;AAEZ,UAAMjG,OAAO,GAAG,KAAKA,OAAL,GAAeiG,KAAK,CAAC7K,CAArC;AACA,UAAM6E,OAAO,GAAG,KAAKA,OAAL,GAAegG,KAAK,CAAC5K,CAArC;;AAEA,QACE,KAAKJ,KAAL,CAAWmK,KAAX,IACA,KAAKpJ,KAAL,CAAW1B,aADX,IAEA,KAAK0B,KAAL,CAAWzB,aAHb,EAIE;AACA,YAAMa,CAAC,GAAGe,YAAY,CAACiK,KAAb,GAAqB,KAAKpK,KAAL,CAAW1B,aAA1C;AACA,YAAMe,CAAC,GAAGc,YAAY,CAACkK,KAAb,GAAqB,KAAKrK,KAAL,CAAWzB,aAA1C;AACA,WAAK0B,QAAL,CAAc;AAAEe,QAAAA,WAAW,EAAE,CAAC;AAAE5B,UAAAA,CAAF;AAAKC,UAAAA;AAAL,SAAD;AAAf,OAAd;AACD;;AAED,SAAKiL,qBAAL,CAA2BtG,OAA3B,EAAoCC,OAApC;;AAEA,SAAKpD,QAAL;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;;;AACEyJ,EAAAA,qBAAqB,CAACC,UAAD,EAAqBC,UAArB,EAAyC;AAC5D,UAAM;AAAEC,MAAAA,gBAAF;AAAoBC,MAAAA;AAApB,QAAwC,KAAKzL,KAAnD;;AAEA,QAAIwL,gBAAJ,aAAIA,gBAAJ,eAAIA,gBAAgB,CAAG,IAAH,EAAS,IAAT,EAAe,KAAKpK,2BAAL,EAAf,CAApB,EAAwE;AACtE;AACD;;AAED,SAAK2D,OAAL,GAAeuG,UAAf;AACA,SAAKtG,OAAL,GAAeuG,UAAf;AAEA,SAAK9J,OAAL,CAAa+D,QAAb,CAAsB;AAAErF,MAAAA,CAAC,EAAE,KAAK4E,OAAV;AAAmB3E,MAAAA,CAAC,EAAE,KAAK4E;AAA3B,KAAtB;AACA,SAAKrD,QAAL,CAAc6D,QAAd,CAAuB,KAAKpD,SAA5B;AAEAqJ,IAAAA,eAAe,SAAf,IAAAA,eAAe,WAAf,YAAAA,eAAe,CAAG,IAAH,EAAS,IAAT,EAAe,KAAKrK,2BAAL,EAAf,CAAf;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;;;AAgHU6C,EAAAA,SAAS,CAACyH,KAAD,EAAoB;AACnC,SAAKZ,OAAL,CAAaa,IAAb,CAAkBD,KAAlB;AACA,SAAK1K,QAAL,CAAc;AAAE8J,MAAAA,OAAO,EAAE,CAAC,GAAG,KAAKA,OAAT;AAAX,KAAd;AACD;;AAEOc,EAAAA,YAAY,CAACF,KAAD,EAAoB;AACtC,SAAKZ,OAAL,CAAae,MAAb,CAAoB,KAAKf,OAAL,CAAagB,OAAb,CAAqBJ,KAArB,CAApB,EAAiD,CAAjD;AACA,SAAK1K,QAAL,CAAc;AAAE8J,MAAAA,OAAO,EAAE,CAAC,GAAG,KAAKA,OAAT;AAAX,KAAd;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;;;AACExG,EAAAA,gBAAgB,CAACrD,CAAD,EAA2B;AACzC,UAAM;AAAE8K,MAAAA,iBAAF;AAAqBC,MAAAA,gBAArB;AAAuCC,MAAAA;AAAvC,QACJ,KAAKjM,KADP;AAGA+L,IAAAA,iBAAiB,SAAjB,IAAAA,iBAAiB,WAAjB,YAAAA,iBAAiB,CAAG9K,CAAH,EAAM,KAAKG,2BAAL,EAAN,CAAjB;;AAEA,UAAM8K,YAAY,GAAG,KAAKC,gBAAL,EAArB;;AACA,QAAID,YAAY,IAAI,IAApB,EAA0B;AAE1B,UAAM;AAAE7M,MAAAA,aAAF;AAAiBC,MAAAA;AAAjB,QAAmC,KAAKyB,KAA9C,CATyC,CAWzC;;AACA,UAAMqL,uBAAuB,GAAG;AAC9BjM,MAAAA,CAAC,EAAEc,CAAC,CAACsD,WAAF,CAAcC,KAAd,GAAsBnF,aADK;AAE9Be,MAAAA,CAAC,EAAEa,CAAC,CAACsD,WAAF,CAAcE,KAAd,GAAsBnF;AAFK,KAAhC,CAZyC,CAiBzC;;AACA,QAAI2M,qBAAJ,EAA2B;AACzBG,MAAAA,uBAAuB,CAACjM,CAAxB,GAA4B,CAA5B;AACAiM,MAAAA,uBAAuB,CAAChM,CAAxB,GAA4B,CAA5B;AACD;;AAED,SAAKiM,MAAL,CAAYH,YAAZ,EAA0BE,uBAA1B;AAEAJ,IAAAA,gBAAgB,SAAhB,IAAAA,gBAAgB,WAAhB,YAAAA,gBAAgB,CACd/K,CADc,EAEd,KAAKG,2BAAL,CAAiC;AAAEgB,MAAAA,SAAS,EAAE8J;AAAb,KAAjC,CAFc,CAAhB;AAID;AAED;AACF;AACA;AACA;AACA;AACA;;;AACEC,EAAAA,gBAAgB,GAAG;AACjB,UAAM;AAAEG,MAAAA,QAAF;AAAYhD,MAAAA,OAAZ;AAAqBjH,MAAAA;AAArB,QAAqC,KAAKrC,KAAhD;AACA,UAAM;AAAEoC,MAAAA;AAAF,QAAgB,IAAtB;AAEA,QAAIkH,OAAO,IAAI,IAAf,EAAqB;;AAErB,QAAIlH,SAAS,CAAC4F,OAAV,CAAkB,CAAlB,MAAyBsB,OAAO,CAACtB,OAAR,CAAgB,CAAhB,CAA7B,EAAiD;AAC/C,aAAO3F,WAAP;AACD;;AAED,QAAIiK,QAAQ,IAAI,IAAhB,EAAsB;AAEtB,UAAMJ,YAAY,GAAG9J,SAAS,IAAI,IAAIkK,QAAR,CAA9B;;AACA,QAAIJ,YAAY,GAAG5C,OAAnB,EAA4B;AAC1B,aAAOA,OAAP;AACD;;AAED,WAAO4C,YAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACEG,EAAAA,MAAM,CAACrC,YAAD,EAAuBE,UAAvB,EAA2C;AAAA;;AAC/C,QAAI,CAAC,KAAKlK,KAAL,CAAWoI,WAAhB,EAA6B,OAAO,KAAP;AAC7B,QAAI,KAAKpI,KAAL,CAAWsJ,OAAX,IAAsBU,YAAY,GAAG,KAAKhK,KAAL,CAAWsJ,OAApD,EAA6D,OAAO,KAAP;AAC7D,QAAI,KAAKtJ,KAAL,CAAWuJ,OAAX,IAAsBS,YAAY,GAAG,KAAKhK,KAAL,CAAWuJ,OAApD,EAA6D,OAAO,KAAP;AAE7D,mDAAKvJ,KAAL,EAAW2J,YAAX,oGAA0B,IAA1B,EAAgC,IAAhC,EAAsC,KAAKvI,2BAAL,EAAtC,EAL+C,CAO/C;;AACA,QAAImL,UAAJ;;AACA,QAAIrC,UAAJ,EAAgB;AACd;AACA,UAAIsC,SAAS,GAAG,KAAKpK,SAArB,CAFc,CAGd;AACA;AACA;AACA;;AACAmK,MAAAA,UAAU,GAAG,KAAK5K,QAAL,CAAckF,WAAd,CAA0B,CAAC;AAAEvG,QAAAA,KAAK,EAAEkK;AAAT,OAAD,KAAyB;AAC9D,aAAK/I,OAAL,CAAa+D,QAAb,CAAsB;AACpBrF,UAAAA,CAAC,EAAE,iDACD,KAAK4E,OADJ,EAED,KAAKhE,KAAL,CAAW5B,aAFV,EAGDqN,SAHC,EAIDhC,QAJC,EAKDN,UAAU,CAAC/J,CALV,CADiB;AAQpBC,UAAAA,CAAC,EAAE,iDACD,KAAK4E,OADJ,EAED,KAAKjE,KAAL,CAAW3B,cAFV,EAGDoN,SAHC,EAIDhC,QAJC,EAKDN,UAAU,CAAC9J,CALV;AARiB,SAAtB;AAgBAoM,QAAAA,SAAS,GAAGhC,QAAZ;AACD,OAlBY,CAAb;AAmBD,KAnC8C,CAqC/C;;;AACA,wCAAmB,KAAK7I,QAAxB,EAAkCqI,YAAlC,EAAgDxH,KAAhD,CAAsD,MAAM;AAC1D,UAAI,CAAC+J,UAAL,EAAiB;AACjB,WAAK5K,QAAL,CAAc8K,cAAd,CAA6BF,UAA7B;AACD,KAHD,EAtC+C,CA0C/C;;AAEA,oDAAKvM,KAAL,EAAW2K,WAAX,sGAAyB,IAAzB,EAA+B,IAA/B,EAAqC,KAAKvJ,2BAAL,EAArC;AACA,WAAO,IAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACEsL,EAAAA,MAAM,CAACC,eAAD,EAA0B;AAC9B;AACAA,IAAAA,eAAe,KAAfA,eAAe,GAAK,KAAK3M,KAAL,CAAWsM,QAAX,IAAuB,CAA5B,CAAf;AACA,WAAO,KAAKD,MAAL,CAAY,KAAKjK,SAAL,GAAiBuK,eAA7B,CAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACEC,EAAAA,MAAM,CAACtB,UAAD,EAAqBC,UAArB,EAAyC;AAC7C,UAAM;AAAEpM,MAAAA,aAAF;AAAiBC,MAAAA;AAAjB,QAAoC,KAAK2B,KAA/C;AACA,QAAI,CAAC5B,aAAD,IAAkB,CAACC,cAAvB,EAAuC;AAEvC,UAAM2F,OAAO,GAAG,CAACuG,UAAU,GAAGnM,aAAa,GAAG,CAA9B,IAAmC,KAAKiD,SAAxD;AACA,UAAM4C,OAAO,GAAG,CAACuG,UAAU,GAAGnM,cAAc,GAAG,CAA/B,IAAoC,KAAKgD,SAAzD;;AAEA,SAAKiJ,qBAAL,CAA2B,CAACtG,OAA5B,EAAqC,CAACC,OAAtC;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACE6H,EAAAA,MAAM,CAACC,aAAD,EAAwBC,aAAxB,EAA+C;AACnD,UAAMhI,OAAO,GACX,CAAC,KAAKA,OAAL,GAAe,KAAK3C,SAApB,GAAgC0K,aAAjC,IAAkD,KAAK1K,SADzD;AAEA,UAAM4C,OAAO,GACX,CAAC,KAAKA,OAAL,GAAe,KAAK5C,SAApB,GAAgC2K,aAAjC,IAAkD,KAAK3K,SADzD;;AAGA,SAAKiJ,qBAAL,CAA2BtG,OAA3B,EAAoCC,OAApC;AACD;;AAEDgI,EAAAA,MAAM,GAAG;AACP,UAAM;AACJC,MAAAA,aADI;AAEJC,MAAAA,QAFI;AAGJC,MAAAA,0BAHI;AAIJpJ,MAAAA,cAJI;AAKJlB,MAAAA,iBALI;AAMJuK,MAAAA,oBANI;AAOJC,MAAAA,gBAPI;AAQJC,MAAAA;AARI,QASF,KAAKtN,KATT;AAUA,UAAM;AAAET,MAAAA,OAAF;AAAWuL,MAAAA,OAAX;AAAoB/I,MAAAA,WAAW,GAAG;AAAlC,QAAyC,KAAKhB,KAApD;AAEA,wBACE,6BAAC,iBAAD;AACE,MAAA,KAAK,EAAEwM,MAAM,CAACC;AADhB,OAEM,KAAK3H,eAAL,CAAqB4H,WAF3B;AAGE,MAAA,GAAG,EAAE,KAAK7M,qBAHZ;AAIE,MAAA,QAAQ,EAAG8M,KAAD,IAAW;AAAA;;AACnB,sDAAK1N,KAAL,EAAW2N,QAAX,kGAAsBD,KAAtB;AACA,aAAK9E,mCAAL;AACD;AAPH,qBASE,6BAAC,qBAAD,CAAU,IAAV;AACE,MAAA,KAAK,EAAE,CACL2E,MAAM,CAACK,WADF,EAEL,KAAK5N,KAAL,CAAW6N,KAFN,EAGL;AACEC,QAAAA,SAAS,EAAE,CACT;AAAEC,UAAAA,KAAK,EAAE,KAAKpM;AAAd,SADS,EAET,GAAG,KAAKF,OAAL,CAAauM,qBAAb,EAFM;AADb,OAHK;AADT,OAYGd,QAZH,CATF,EAwBGC,0BAA0B,KACzBrC,OADyB,aACzBA,OADyB,uBACzBA,OAAO,CAAEmD,GAAT,CACGvC,KAAD,IACE3H,cAAc,iBACZ,6BAAC,iCAAD;AACE,MAAA,CAAC,EAAE2H,KAAK,CAACvL,CADX;AAEE,MAAA,CAAC,EAAEuL,KAAK,CAACtL,CAFX;AAGE,MAAA,GAAG,EAAEsL,KAAK,CAACxH,EAHb;AAIE,MAAA,iBAAiB,EAAEH,cAJrB;AAKE,MAAA,eAAe,EAAE,MAAM;AACrB,aAAK6H,YAAL,CAAkBF,KAAlB;AACD;AAPH,MAHN,CADyB,CAxB7B,EAyCG3J,WAAW,CAACkM,GAAZ,CAAgB,CAAC;AAAE9N,MAAAA,CAAF;AAAKC,MAAAA;AAAL,KAAD,EAAW8N,KAAX,KAAqB;AACpC,0BAAO,6BAAC,4BAAD;AAAiB,QAAA,GAAG,EAAEA,KAAtB;AAA6B,QAAA,CAAC,EAAE/N,CAAhC;AAAmC,QAAA,CAAC,EAAEC;AAAtC,QAAP;AACD,KAFA,CAzCH,EA6CGyC,iBAAiB,iBAChB,6BAAC,oBAAD;AACE,MAAA,aAAa,EAAEoK,aADjB;AAEE,MAAA,iBAAiB,EAAEpK,iBAFrB;AAGE,MAAA,OAAO,EAAEtD,OAHX;AAIE,MAAA,OAAO,EAAE8N,gBAJX;AAKE,MAAA,WAAW,EAAED,oBALf;AAME,MAAA,YAAY,EAAE,KAAKnH,uBANrB;AAOE,MAAA,OAAO,EAAE,KAAKc,OAPhB;AAQE,MAAA,UAAU,EAAGoH,IAAD,IAAkB;AAC5B,aAAKnN,QAAL,CAAc;AAAEzB,UAAAA,OAAO,EAAE4O;AAAX,SAAd;AACD,OAVH;AAWE,MAAA,QAAQ,EAAEb;AAXZ,MA9CJ,CADF;AA+DD;;AA1sCD;;;;gBAHI5N,uB,kBAQkB;AACpB0I,EAAAA,WAAW,EAAE,IADO;AAEpBlG,EAAAA,UAAU,EAAE,IAFQ;AAGpBG,EAAAA,WAAW,EAAE,CAHO;AAIpBsE,EAAAA,cAAc,EAAE,CAJI;AAKpBC,EAAAA,cAAc,EAAE,CALI;AAMpB0C,EAAAA,OAAO,EAAE,GANW;AAOpBC,EAAAA,OAAO,EAAE,GAPW;AAQpBC,EAAAA,wBAAwB,EAAE,CARN;AASpBC,EAAAA,yBAAyB,EAAE,CATP;AAUpBsB,EAAAA,mBAAmB,EAAE,CAVD;AAWpBhH,EAAAA,cAAc,EAAE,GAXI;AAYpB2D,EAAAA,aAAa,EAAE,IAZK;AAapB4E,EAAAA,QAAQ,EAAE,GAbU;AAcpBjL,EAAAA,WAAW,EAAE,IAdO;AAepBE,EAAAA,iBAAiB,EAAE,GAfC;AAgBpB6D,EAAAA,YAAY,EAAEgJ,SAhBM;AAiBpB/I,EAAAA,aAAa,EAAE+I,SAjBK;AAkBpBtG,EAAAA,kBAAkB,EAAE,CAlBA;AAmBpBqF,EAAAA,0BAA0B,EAAE,IAnBR;AAoBpBtK,EAAAA,iBAAiB,EAAEuL,SApBC;AAqBpBnB,EAAAA,aAAa,EAAEmB,SArBK;AAsBpB3N,EAAAA,yBAAyB,EAAE2N,SAtBP;AAuBpBjF,EAAAA,uBAAuB,EAAEiF,SAvBL;AAwBpBtH,EAAAA,UAAU,EAAE,IAxBQ;AAyBpB3E,EAAAA,uBAAuB,EAAE;AAzBL,C;;AAwsCxB,MAAMoL,MAAM,GAAGc,wBAAWtI,MAAX,CAAkB;AAC/ByH,EAAAA,SAAS,EAAE;AACTc,IAAAA,UAAU,EAAE,QADH;AAETC,IAAAA,IAAI,EAAE,CAFG;AAGTC,IAAAA,cAAc,EAAE,QAHP;AAITC,IAAAA,QAAQ,EAAE,QAJD;AAKTjO,IAAAA,QAAQ,EAAE;AALD,GADoB;AAQ/BoN,EAAAA,WAAW,EAAE;AACXU,IAAAA,UAAU,EAAE,QADD;AAEXC,IAAAA,IAAI,EAAE,CAFK;AAGXC,IAAAA,cAAc,EAAE,QAHL;AAIXhP,IAAAA,KAAK,EAAE;AAJI;AARkB,CAAlB,CAAf;;eAgBeE,uB","sourcesContent":["import React, { Component, createRef, RefObject } from 'react';\nimport {\n Animated,\n Easing,\n GestureResponderEvent,\n PanResponder,\n PanResponderCallbacks,\n PanResponderGestureState,\n PanResponderInstance,\n StyleSheet,\n View,\n} from 'react-native';\n\nimport {\n Vec2D,\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState,\n TouchPoint,\n ZoomableViewEvent,\n Size2D,\n} from './typings';\n\nimport { AnimatedTouchFeedback } from './components';\nimport { DebugTouchPoint } from './debugHelper';\nimport {\n calcGestureCenterPoint,\n calcGestureTouchDistance,\n calcNewScaledOffsetForZoomCentering,\n} from './helper';\nimport { applyPanBoundariesToOffset } from './helper/applyPanBoundariesToOffset';\nimport { viewportPositionToImagePosition } from './helper/coordinateConversion';\nimport { StaticPin } from './components/StaticPin';\nimport { debounce } from 'lodash';\nimport {\n getBoundaryCrossedAnim,\n getPanMomentumDecayAnim,\n getZoomToAnimation,\n} from './animations';\n\nconst initialState: ReactNativeZoomableViewState = {\n originalWidth: 0,\n originalHeight: 0,\n originalPageX: 0,\n originalPageY: 0,\n pinSize: { width: 0, height: 0 },\n};\n\nclass ReactNativeZoomableView extends Component<\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState\n> {\n zoomSubjectWrapperRef: RefObject;\n gestureHandlers: PanResponderInstance;\n doubleTapFirstTapReleaseTimestamp: number | undefined;\n\n static defaultProps = {\n zoomEnabled: true,\n panEnabled: true,\n initialZoom: 1,\n initialOffsetX: 0,\n initialOffsetY: 0,\n maxZoom: 1.5,\n minZoom: 0.5,\n pinchToZoomInSensitivity: 1,\n pinchToZoomOutSensitivity: 1,\n movementSensibility: 1,\n doubleTapDelay: 300,\n bindToBorders: true,\n zoomStep: 0.5,\n onLongPress: null,\n longPressDuration: 700,\n contentWidth: undefined,\n contentHeight: undefined,\n panBoundaryPadding: 0,\n visualTouchFeedbackEnabled: true,\n staticPinPosition: undefined,\n staticPinIcon: undefined,\n onStaticPinPositionChange: undefined,\n onStaticPinPositionMove: undefined,\n animatePin: true,\n disablePanOnInitialZoom: false,\n };\n\n private panAnim = new Animated.ValueXY({ x: 0, y: 0 });\n private zoomAnim = new Animated.Value(1);\n private pinAnim = new Animated.ValueXY({ x: 0, y: 0 });\n\n private __offsets = {\n x: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n y: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n };\n\n private zoomLevel = 1;\n private lastGestureCenterPosition: { x: number; y: number } | null = null;\n private lastGestureTouchDistance: number | null = null;\n private gestureType: 'pinch' | 'shift' | null;\n\n private _gestureStarted = false;\n private set gestureStarted(v: boolean) {\n this._gestureStarted = v;\n }\n\n public get gestureStarted() {\n return this._gestureStarted;\n }\n\n /**\n * Last press time (used to evaluate whether user double tapped)\n * @type {number}\n */\n private longPressTimeout: NodeJS.Timeout | null = null;\n private onTransformInvocationInitialized: boolean | undefined;\n private singleTapTimeoutId: NodeJS.Timeout | undefined;\n private touches: TouchPoint[] = [];\n private doubleTapFirstTap: TouchPoint | undefined;\n private measureZoomSubjectInterval: NodeJS.Timer | undefined;\n\n constructor(props: ReactNativeZoomableViewProps) {\n super(props);\n // This needs to be done before anything else to initialize the state.\n // Otherwise, the logic below may reference the state when it's undefined,\n // causing runtime errors.\n this.state = { ...initialState };\n\n this.gestureHandlers = PanResponder.create({\n onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,\n onPanResponderGrant: this._handlePanResponderGrant,\n onPanResponderMove: this._handlePanResponderMove,\n onPanResponderRelease: this._handlePanResponderEnd,\n onPanResponderTerminate: (evt, gestureState) => {\n // We should also call _handlePanResponderEnd\n // to properly perform cleanups when the gesture is terminated\n // (aka gesture handling responsibility is taken over by another component).\n // This also fixes a weird issue where\n // on real device, sometimes onPanResponderRelease is not called when you lift 2 fingers up,\n // but onPanResponderTerminate is called instead for no apparent reason.\n this._handlePanResponderEnd(evt, gestureState);\n this.props.onPanResponderTerminate?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n );\n },\n onPanResponderTerminationRequest: (evt, gestureState) =>\n !!this.props.onPanResponderTerminationRequest?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ),\n // Defaults to true to prevent parent components, such as React Navigation's tab view, from taking over as responder.\n onShouldBlockNativeResponder: (evt, gestureState) =>\n this.props.onShouldBlockNativeResponder?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ) ?? true,\n onStartShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onStartShouldSetPanResponderCapture?.(evt, gestureState),\n onMoveShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onMoveShouldSetPanResponderCapture?.(evt, gestureState),\n });\n\n this.zoomSubjectWrapperRef = createRef();\n\n if (this.props.zoomAnimatedValue)\n this.zoomAnim = this.props.zoomAnimatedValue;\n if (this.props.panAnimatedValueXY)\n this.panAnim = this.props.panAnimatedValueXY;\n\n if (this.props.initialZoom) this.zoomLevel = this.props.initialZoom;\n if (this.props.initialOffsetX != null)\n this.offsetX = this.props.initialOffsetX;\n if (this.props.initialOffsetY != null)\n this.offsetY = this.props.initialOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n this.panAnim.addListener(({ x, y }) => {\n this.offsetX = x;\n this.offsetY = y;\n });\n this.zoomAnim.addListener(({ value }) => {\n this.zoomLevel = value;\n });\n\n this.lastGestureTouchDistance = 150;\n\n this.gestureType = null;\n }\n\n private raisePin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: -10 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private dropPin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: 0 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private set offsetX(x: number) {\n this.__setOffset('x', x);\n }\n\n private set offsetY(y: number) {\n this.__setOffset('y', y);\n }\n\n private get offsetX() {\n return this.__getOffset('x');\n }\n\n private get offsetY() {\n return this.__getOffset('y');\n }\n\n private __setOffset(axis: 'x' | 'y', offset: number) {\n const offsetState = this.__offsets[axis];\n\n if (this.props.bindToBorders) {\n const containerSize =\n axis === 'x' ? this.state.originalWidth : this.state.originalHeight;\n const contentSize =\n axis === 'x'\n ? this.props.contentWidth || this.state.originalWidth\n : this.props.contentHeight || this.state.originalHeight;\n\n const boundOffset =\n contentSize && containerSize && this.props.panBoundaryPadding != null\n ? applyPanBoundariesToOffset(\n offset,\n containerSize,\n contentSize,\n this.zoomLevel,\n this.props.panBoundaryPadding\n )\n : offset;\n\n if (!this.gestureType && !offsetState.boundaryCrossedAnimInEffect) {\n const boundariesApplied =\n boundOffset !== offset &&\n boundOffset.toFixed(3) !== offset.toFixed(3);\n if (boundariesApplied) {\n offsetState.boundaryCrossedAnimInEffect = true;\n getBoundaryCrossedAnim(this.panAnim[axis], boundOffset).start(() => {\n offsetState.boundaryCrossedAnimInEffect = false;\n });\n return;\n }\n }\n }\n\n offsetState.value = offset;\n }\n\n private __getOffset(axis: 'x' | 'y') {\n return this.__offsets[axis].value;\n }\n\n componentDidUpdate(\n prevProps: ReactNativeZoomableViewProps,\n prevState: ReactNativeZoomableViewState\n ) {\n const { zoomEnabled, initialZoom } = this.props;\n if (prevProps.zoomEnabled && !zoomEnabled && initialZoom) {\n this.zoomLevel = initialZoom;\n this.zoomAnim.setValue(this.zoomLevel);\n }\n if (\n !this.onTransformInvocationInitialized &&\n this._invokeOnTransform().successful\n ) {\n this.panAnim.addListener(() => this._invokeOnTransform());\n this.zoomAnim.addListener(() => this._invokeOnTransform());\n this.onTransformInvocationInitialized = true;\n }\n\n const currState = this.state;\n const originalMeasurementsChanged =\n currState.originalHeight !== prevState.originalHeight ||\n currState.originalWidth !== prevState.originalWidth ||\n currState.originalPageX !== prevState.originalPageX ||\n currState.originalPageY !== prevState.originalPageY;\n\n const staticPinPositionChanged =\n prevProps.staticPinPosition?.x !== this.props.staticPinPosition?.x ||\n prevProps.staticPinPosition?.y !== this.props.staticPinPosition?.y;\n\n if (\n this.onTransformInvocationInitialized &&\n (originalMeasurementsChanged || staticPinPositionChanged)\n ) {\n this._invokeOnTransform();\n }\n }\n\n componentDidMount() {\n this.grabZoomSubjectOriginalMeasurements();\n // We've already run `grabZoomSubjectOriginalMeasurements` at various events\n // to make sure the measurements are promptly updated.\n // However, there might be cases we haven't accounted for, especially when\n // native processes are involved. To account for those cases,\n // we'll use an interval here to ensure we're always up-to-date.\n // The `setState` in `grabZoomSubjectOriginalMeasurements` won't trigger a rerender\n // if the values given haven't changed, so we're not running performance risk here.\n this.measureZoomSubjectInterval = setInterval(\n this.grabZoomSubjectOriginalMeasurements,\n 1e3\n );\n }\n\n componentWillUnmount() {\n this.measureZoomSubjectInterval &&\n clearInterval(this.measureZoomSubjectInterval);\n }\n\n debouncedOnStaticPinPositionChange = debounce(\n (position: Vec2D) => this.props.onStaticPinPositionChange?.(position),\n 100\n );\n\n /**\n * try to invoke onTransform\n * @private\n */\n _invokeOnTransform() {\n const zoomableViewEvent = this._getZoomableViewEventObject();\n const position = this._staticPinPosition();\n\n if (!zoomableViewEvent.originalWidth || !zoomableViewEvent.originalHeight)\n return { successful: false };\n\n this.props.onTransform?.(zoomableViewEvent);\n\n if (position) {\n this.props.onStaticPinPositionMove?.(position);\n this.debouncedOnStaticPinPositionChange(position);\n }\n\n return { successful: true };\n }\n\n /**\n * Returns additional information about components current state for external event hooks\n *\n * @returns {{}}\n * @private\n */\n _getZoomableViewEventObject(overwriteObj = {}): ZoomableViewEvent {\n return {\n zoomLevel: this.zoomLevel,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n originalHeight: this.state.originalHeight,\n originalWidth: this.state.originalWidth,\n originalPageX: this.state.originalPageX,\n originalPageY: this.state.originalPageY,\n ...overwriteObj,\n } as ZoomableViewEvent;\n }\n\n /**\n * Get the original box dimensions and save them for later use.\n * (They will be used to calculate boxBorders)\n *\n * @private\n */\n private grabZoomSubjectOriginalMeasurements = () => {\n // make sure we measure after animations are complete\n requestAnimationFrame(() => {\n // this setTimeout is here to fix a weird issue on iOS where the measurements are all `0`\n // when navigating back (react-navigation stack) from another view\n // while closing the keyboard at the same time\n setTimeout(() => {\n // In normal conditions, we're supposed to measure zoomSubject instead of its wrapper.\n // However, our zoomSubject may have been transformed by an initial zoomLevel or offset,\n // in which case these measurements will not represent the true \"original\" measurements.\n // We just need to make sure the zoomSubjectWrapper perfectly aligns with the zoomSubject\n // (no border, space, or anything between them)\n const zoomSubjectWrapperRef = this.zoomSubjectWrapperRef;\n // we don't wanna measure when zoomSubjectWrapperRef is not yet available or has been unmounted\n zoomSubjectWrapperRef.current?.measureInWindow(\n (x, y, width, height) => {\n // When the component is off-screen, these become all 0s, so we don't set them\n // to avoid messing up calculations, especially ones that are done right after\n // the component transitions from hidden to visible.\n if (!x && !y && !width && !height) return;\n\n // If these values are all the same, don't re-set them in state\n // this way we don't re-render\n if (\n this.state.originalWidth === width &&\n this.state.originalHeight === height &&\n this.state.originalPageX === x &&\n this.state.originalPageY === y\n ) {\n return;\n }\n\n this.setState({\n originalWidth: width,\n originalHeight: height,\n originalPageX: x,\n originalPageY: y,\n });\n }\n );\n });\n });\n };\n\n /**\n * Handles the start of touch events and checks for taps\n *\n * @param e\n * @param gestureState\n * @returns {boolean}\n *\n * @private\n */\n _handleStartShouldSetPanResponder = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onStartShouldSetPanResponder) {\n this.props.onStartShouldSetPanResponder(\n e,\n gestureState,\n this._getZoomableViewEventObject(),\n false\n );\n }\n\n // Always set pan responder on start\n // of gesture so we can handle tap.\n // \"Pan threshold validation\" will be handled\n // in `onPanResponderMove` instead of in `onMoveShouldSetPanResponder`\n return true;\n };\n\n /**\n * Calculates pinch distance\n *\n * @param e\n * @param gestureState\n * @private\n */\n _handlePanResponderGrant: NonNullable<\n PanResponderCallbacks['onPanResponderGrant']\n > = (e, gestureState) => {\n if (this.props.onLongPress) {\n this.longPressTimeout = setTimeout(() => {\n this.props.onLongPress?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n this.longPressTimeout = null;\n }, this.props.longPressDuration);\n }\n\n this.props.onPanResponderGrant?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n this.panAnim.stopAnimation();\n this.zoomAnim.stopAnimation();\n this.gestureStarted = true;\n\n this.raisePin();\n };\n\n /**\n * Handles the end of touch events\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderEnd: NonNullable<\n PanResponderCallbacks['onPanResponderEnd']\n > = (e, gestureState) => {\n if (!this.gestureType) {\n this._resolveAndHandleTap(e);\n }\n\n this.setState({ debugPoints: [] });\n\n this.lastGestureCenterPosition = null;\n\n const disableMomentum =\n this.props.disableMomentum ||\n (this.props.panEnabled &&\n this.gestureType === 'shift' &&\n this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom);\n\n // Trigger final shift animation unless disablePanOnInitialZoom is set and we're on the initial zoom level\n // or disableMomentum\n if (!disableMomentum) {\n getPanMomentumDecayAnim(this.panAnim, {\n x: gestureState.vx / this.zoomLevel,\n y: gestureState.vy / this.zoomLevel,\n }).start();\n }\n\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n this.props.onPanResponderEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n if (this.gestureType === 'pinch') {\n this.props.onZoomEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n } else if (this.gestureType === 'shift') {\n this.props.onShiftingEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n if (this.props.staticPinPosition) {\n this._updateStaticPin();\n }\n\n this.dropPin();\n\n this.gestureType = null;\n this.gestureStarted = false;\n };\n\n /**\n * Handles the actual movement of our pan responder\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderMove = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onPanResponderMove) {\n if (\n this.props.onPanResponderMove(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return false;\n }\n }\n\n // Only supports 2 touches and below,\n // any invalid number will cause the gesture to end.\n if (gestureState.numberActiveTouches <= 2) {\n if (!this.gestureStarted) {\n this._handlePanResponderGrant(e, gestureState);\n }\n } else {\n if (this.gestureStarted) {\n this._handlePanResponderEnd(e, gestureState);\n }\n return true;\n }\n\n if (gestureState.numberActiveTouches === 2) {\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'pinch') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n this.lastGestureTouchDistance = calcGestureTouchDistance(\n e,\n gestureState\n );\n }\n this.gestureType = 'pinch';\n this._handlePinching(e, gestureState);\n } else if (gestureState.numberActiveTouches === 1) {\n if (\n this.longPressTimeout &&\n (Math.abs(gestureState.dx) > 5 || Math.abs(gestureState.dy) > 5)\n ) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'shift') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n }\n\n const { dx, dy } = gestureState;\n const isShiftGesture = Math.abs(dx) > 2 || Math.abs(dy) > 2;\n if (isShiftGesture) {\n this.gestureType = 'shift';\n this._handleShifting(gestureState);\n }\n }\n };\n\n /**\n * Handles the pinch movement and zooming\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePinching(\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) {\n if (!this.props.zoomEnabled) return;\n\n const {\n maxZoom,\n minZoom,\n pinchToZoomInSensitivity,\n pinchToZoomOutSensitivity,\n } = this.props;\n\n const distance = calcGestureTouchDistance(e, gestureState);\n\n if (\n this.props.onZoomBefore &&\n this.props.onZoomBefore(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return;\n }\n\n if (!distance) return;\n if (!this.lastGestureTouchDistance) return;\n\n // define the new zoom level and take zoom level sensitivity into consideration\n const zoomGrowthFromLastGestureState =\n distance / this.lastGestureTouchDistance;\n this.lastGestureTouchDistance = distance;\n\n const pinchToZoomSensitivity =\n zoomGrowthFromLastGestureState < 1\n ? pinchToZoomOutSensitivity\n : pinchToZoomInSensitivity;\n\n if (pinchToZoomSensitivity == null) return;\n const deltaGrowth = zoomGrowthFromLastGestureState - 1;\n // 0 - no resistance\n // 10 - 90% resistance\n const deltaGrowthAdjustedBySensitivity =\n deltaGrowth * (1 - (pinchToZoomSensitivity * 9) / 100);\n\n let newZoomLevel = this.zoomLevel * (1 + deltaGrowthAdjustedBySensitivity);\n\n // make sure max and min zoom levels are respected\n if (maxZoom != null && newZoomLevel > maxZoom) {\n newZoomLevel = maxZoom;\n }\n\n if (minZoom != null && newZoomLevel < minZoom) {\n newZoomLevel = minZoom;\n }\n\n const gestureCenterPoint = calcGestureCenterPoint(e, gestureState);\n\n if (!gestureCenterPoint) return;\n\n let zoomCenter = {\n x: gestureCenterPoint.x - this.state.originalPageX,\n y: gestureCenterPoint.y - this.state.originalPageY,\n };\n\n if (this.props.staticPinPosition) {\n // When we use a static pin position, the zoom centre is the same as that position,\n // otherwise the pin moves around way too much while zooming.\n zoomCenter = {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n };\n }\n\n // Uncomment to debug\n this.props.debug && this._setPinchDebugPoints(e, zoomCenter);\n\n const { originalHeight, originalWidth } = this.state;\n\n const oldOffsetX = this.offsetX;\n const oldOffsetY = this.offsetY;\n const oldScale = this.zoomLevel;\n const newScale = newZoomLevel;\n\n if (!originalHeight || !originalWidth) return;\n\n let offsetY = calcNewScaledOffsetForZoomCentering(\n oldOffsetY,\n originalHeight,\n oldScale,\n newScale,\n zoomCenter.y\n );\n let offsetX = calcNewScaledOffsetForZoomCentering(\n oldOffsetX,\n originalWidth,\n oldScale,\n newScale,\n zoomCenter.x\n );\n\n const offsetShift =\n this._calcOffsetShiftSinceLastGestureState(gestureCenterPoint);\n if (offsetShift) {\n offsetX += offsetShift.x;\n offsetY += offsetShift.y;\n }\n\n this.offsetX = offsetX;\n this.offsetY = offsetY;\n this.zoomLevel = newScale;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n this.props.onZoomAfter?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n /**\n * Used to debug pinch events\n * @param gestureResponderEvent\n * @param zoomCenter\n * @param points\n */\n _setPinchDebugPoints(\n gestureResponderEvent: GestureResponderEvent,\n zoomCenter: Vec2D,\n ...points: Vec2D[]\n ) {\n const { touches } = gestureResponderEvent.nativeEvent;\n const { originalPageY, originalPageX } = this.state;\n\n this.setState({\n debugPoints: [\n {\n x: touches[0].pageX - originalPageX,\n y: touches[0].pageY - originalPageY,\n },\n {\n x: touches[1].pageX - originalPageX,\n y: touches[1].pageY - originalPageY,\n },\n zoomCenter,\n ...points,\n ],\n });\n }\n\n /**\n * Calculates the amount the offset should shift since the last position during panning\n *\n * @param {Vec2D} gestureCenterPoint\n *\n * @private\n */\n _calcOffsetShiftSinceLastGestureState(gestureCenterPoint: Vec2D) {\n const { movementSensibility } = this.props;\n\n let shift = null;\n\n if (this.lastGestureCenterPosition && movementSensibility) {\n const dx = gestureCenterPoint.x - this.lastGestureCenterPosition.x;\n const dy = gestureCenterPoint.y - this.lastGestureCenterPosition.y;\n\n const shiftX = dx / this.zoomLevel / movementSensibility;\n const shiftY = dy / this.zoomLevel / movementSensibility;\n\n shift = {\n x: shiftX,\n y: shiftY,\n };\n }\n\n this.lastGestureCenterPosition = gestureCenterPoint;\n\n return shift;\n }\n\n /**\n * Handles movement by tap and move\n *\n * @param gestureState\n *\n * @private\n */\n _handleShifting(gestureState: PanResponderGestureState) {\n // Skips shifting if panEnabled is false or disablePanOnInitialZoom is true and we're on the initial zoom level\n if (\n !this.props.panEnabled ||\n (this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom)\n ) {\n return;\n }\n const shift = this._calcOffsetShiftSinceLastGestureState({\n x: gestureState.moveX,\n y: gestureState.moveY,\n });\n if (!shift) return;\n\n const offsetX = this.offsetX + shift.x;\n const offsetY = this.offsetY + shift.y;\n\n if (\n this.props.debug &&\n this.state.originalPageX &&\n this.state.originalPageY\n ) {\n const x = gestureState.moveX - this.state.originalPageX;\n const y = gestureState.moveY - this.state.originalPageY;\n this.setState({ debugPoints: [{ x, y }] });\n }\n\n this._setNewOffsetPosition(offsetX, offsetY);\n\n this.raisePin();\n }\n\n /**\n * Set the state to offset moved\n *\n * @param {number} newOffsetX\n * @param {number} newOffsetY\n * @returns\n */\n _setNewOffsetPosition(newOffsetX: number, newOffsetY: number) {\n const { onShiftingBefore, onShiftingAfter } = this.props;\n\n if (onShiftingBefore?.(null, null, this._getZoomableViewEventObject())) {\n return;\n }\n\n this.offsetX = newOffsetX;\n this.offsetY = newOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n onShiftingAfter?.(null, null, this._getZoomableViewEventObject());\n }\n\n /**\n * Check whether the press event is double tap\n * or single tap and handle the event accordingly\n *\n * @param e\n *\n * @private\n */\n private _resolveAndHandleTap = (e: GestureResponderEvent) => {\n const now = Date.now();\n if (\n this.doubleTapFirstTapReleaseTimestamp &&\n this.props.doubleTapDelay &&\n now - this.doubleTapFirstTapReleaseTimestamp < this.props.doubleTapDelay\n ) {\n this.doubleTapFirstTap &&\n this._addTouch({\n ...this.doubleTapFirstTap,\n id: now.toString(),\n isSecondTap: true,\n });\n this.singleTapTimeoutId && clearTimeout(this.singleTapTimeoutId);\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n delete this.doubleTapFirstTap;\n this._handleDoubleTap(e);\n } else {\n this.doubleTapFirstTapReleaseTimestamp = now;\n this.doubleTapFirstTap = {\n id: now.toString(),\n x: e.nativeEvent.pageX - this.state.originalPageX,\n y: e.nativeEvent.pageY - this.state.originalPageY,\n };\n this._addTouch(this.doubleTapFirstTap);\n\n // persist event so e.nativeEvent is preserved after a timeout delay\n e.persist();\n this.singleTapTimeoutId = setTimeout(() => {\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n\n // Pan to the tapped location\n if (this.props.staticPinPosition && this.doubleTapFirstTap) {\n const tapX =\n this.props.staticPinPosition.x - this.doubleTapFirstTap.x;\n const tapY =\n this.props.staticPinPosition.y - this.doubleTapFirstTap.y;\n\n Animated.timing(this.panAnim, {\n toValue: {\n x: this.offsetX + tapX / this.zoomLevel,\n y: this.offsetY + tapY / this.zoomLevel,\n },\n useNativeDriver: true,\n duration: 200,\n }).start(() => {\n this._updateStaticPin();\n });\n }\n\n this.props.onSingleTap?.(e, this._getZoomableViewEventObject());\n }, this.props.doubleTapDelay);\n }\n };\n\n moveStaticPinTo = (position: Vec2D, duration?: number) => {\n const { originalWidth, originalHeight } = this.state;\n const { staticPinPosition, contentWidth, contentHeight } = this.props;\n\n if (!staticPinPosition) return;\n if (!originalWidth || !originalHeight) return;\n if (!contentWidth || !contentHeight) return;\n\n // Offset for the static pin\n const pinX = staticPinPosition.x - originalWidth / 2;\n const pinY = staticPinPosition.y - originalHeight / 2;\n\n this.offsetX = contentWidth / 2 - position.x + pinX / this.zoomLevel;\n this.offsetY = contentHeight / 2 - position.y + pinY / this.zoomLevel;\n\n if (duration) {\n Animated.timing(this.panAnim, {\n toValue: { x: this.offsetX, y: this.offsetY },\n useNativeDriver: true,\n duration,\n }).start();\n } else {\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n }\n };\n\n private _staticPinPosition = () => {\n if (!this.props.staticPinPosition) return;\n if (!this.props.contentWidth || !this.props.contentHeight) return;\n\n return viewportPositionToImagePosition({\n viewportPosition: {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n },\n imageSize: {\n height: this.props.contentHeight,\n width: this.props.contentWidth,\n },\n zoomableEvent: {\n ...this._getZoomableViewEventObject(),\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n zoomLevel: this.zoomLevel,\n },\n });\n };\n\n private _updateStaticPin = () => {\n const position = this._staticPinPosition();\n if (!position) return;\n this.props.onStaticPinPositionChange?.(position);\n };\n\n private _addTouch(touch: TouchPoint) {\n this.touches.push(touch);\n this.setState({ touches: [...this.touches] });\n }\n\n private _removeTouch(touch: TouchPoint) {\n this.touches.splice(this.touches.indexOf(touch), 1);\n this.setState({ touches: [...this.touches] });\n }\n\n /**\n * Handles the double tap event\n *\n * @param e\n *\n * @private\n */\n _handleDoubleTap(e: GestureResponderEvent) {\n const { onDoubleTapBefore, onDoubleTapAfter, doubleTapZoomToCenter } =\n this.props;\n\n onDoubleTapBefore?.(e, this._getZoomableViewEventObject());\n\n const nextZoomStep = this._getNextZoomStep();\n if (nextZoomStep == null) return;\n\n const { originalPageX, originalPageY } = this.state;\n\n // define new zoom position coordinates\n const zoomPositionCoordinates = {\n x: e.nativeEvent.pageX - originalPageX,\n y: e.nativeEvent.pageY - originalPageY,\n };\n\n // if doubleTapZoomToCenter enabled -> always zoom to center instead\n if (doubleTapZoomToCenter) {\n zoomPositionCoordinates.x = 0;\n zoomPositionCoordinates.y = 0;\n }\n\n this.zoomTo(nextZoomStep, zoomPositionCoordinates);\n\n onDoubleTapAfter?.(\n e,\n this._getZoomableViewEventObject({ zoomLevel: nextZoomStep })\n );\n }\n\n /**\n * Returns the next zoom step based on current step and zoomStep property.\n * If we are zoomed all the way in -> return to initialzoom\n *\n * @returns {*}\n */\n _getNextZoomStep() {\n const { zoomStep, maxZoom, initialZoom } = this.props;\n const { zoomLevel } = this;\n\n if (maxZoom == null) return;\n\n if (zoomLevel.toFixed(2) === maxZoom.toFixed(2)) {\n return initialZoom;\n }\n\n if (zoomStep == null) return;\n\n const nextZoomStep = zoomLevel * (1 + zoomStep);\n if (nextZoomStep > maxZoom) {\n return maxZoom;\n }\n\n return nextZoomStep;\n }\n\n /**\n * Zooms to a specific level. A \"zoom center\" can be provided, which specifies\n * the point that will remain in the same position on the screen after the zoom.\n * The coordinates of the zoom center is relative to the zoom subject.\n * { x: 0, y: 0 } is the very center of the zoom subject.\n *\n * @param newZoomLevel\n * @param zoomCenter - If not supplied, the container's center is the zoom center\n */\n zoomTo(newZoomLevel: number, zoomCenter?: Vec2D) {\n if (!this.props.zoomEnabled) return false;\n if (this.props.maxZoom && newZoomLevel > this.props.maxZoom) return false;\n if (this.props.minZoom && newZoomLevel < this.props.minZoom) return false;\n\n this.props.onZoomBefore?.(null, null, this._getZoomableViewEventObject());\n\n // == Perform Pan Animation to preserve the zoom center while zooming ==\n let listenerId: string | undefined;\n if (zoomCenter) {\n // Calculates panAnim values based on changes in zoomAnim.\n let prevScale = this.zoomLevel;\n // Since zoomAnim is calculated in native driver,\n // it will jitter panAnim once in a while,\n // because here panAnim is being calculated in js.\n // However the jittering should mostly occur in simulator.\n listenerId = this.zoomAnim.addListener(({ value: newScale }) => {\n this.panAnim.setValue({\n x: calcNewScaledOffsetForZoomCentering(\n this.offsetX,\n this.state.originalWidth,\n prevScale,\n newScale,\n zoomCenter.x\n ),\n y: calcNewScaledOffsetForZoomCentering(\n this.offsetY,\n this.state.originalHeight,\n prevScale,\n newScale,\n zoomCenter.y\n ),\n });\n prevScale = newScale;\n });\n }\n\n // == Perform Zoom Animation ==\n getZoomToAnimation(this.zoomAnim, newZoomLevel).start(() => {\n if (!listenerId) return;\n this.zoomAnim.removeListener(listenerId);\n });\n // == Zoom Animation Ends ==\n\n this.props.onZoomAfter?.(null, null, this._getZoomableViewEventObject());\n return true;\n }\n\n /**\n * Zooms in or out by a specified change level\n * Use a positive number for `zoomLevelChange` to zoom in\n * Use a negative number for `zoomLevelChange` to zoom out\n *\n * Returns a promise if everything was updated and a boolean, whether it could be updated or if it exceeded the min/max zoom limits.\n *\n * @param {number | null} zoomLevelChange\n *\n * @return {bool}\n */\n zoomBy(zoomLevelChange: number) {\n // if no zoom level Change given -> just use zoom step\n zoomLevelChange ||= this.props.zoomStep || 0;\n return this.zoomTo(this.zoomLevel + zoomLevelChange);\n }\n\n /**\n * Moves the zoomed view to a specified position\n * Returns a promise when finished\n *\n * @param {number} newOffsetX the new position we want to move it to (x-axis)\n * @param {number} newOffsetY the new position we want to move it to (y-axis)\n *\n * @return {bool}\n */\n moveTo(newOffsetX: number, newOffsetY: number) {\n const { originalWidth, originalHeight } = this.state;\n if (!originalWidth || !originalHeight) return;\n\n const offsetX = (newOffsetX - originalWidth / 2) / this.zoomLevel;\n const offsetY = (newOffsetY - originalHeight / 2) / this.zoomLevel;\n\n this._setNewOffsetPosition(-offsetX, -offsetY);\n }\n\n /**\n * Moves the zoomed view by a certain amount.\n *\n * Returns a promise when finished\n *\n * @param {number} offsetChangeX the amount we want to move the offset by (x-axis)\n * @param {number} offsetChangeY the amount we want to move the offset by (y-axis)\n *\n * @return {bool}\n */\n moveBy(offsetChangeX: number, offsetChangeY: number) {\n const offsetX =\n (this.offsetX * this.zoomLevel - offsetChangeX) / this.zoomLevel;\n const offsetY =\n (this.offsetY * this.zoomLevel - offsetChangeY) / this.zoomLevel;\n\n this._setNewOffsetPosition(offsetX, offsetY);\n }\n\n render() {\n const {\n staticPinIcon,\n children,\n visualTouchFeedbackEnabled,\n doubleTapDelay,\n staticPinPosition,\n onStaticPinLongPress,\n onStaticPinPress,\n pinProps,\n } = this.props;\n const { pinSize, touches, debugPoints = [] } = this.state;\n\n return (\n {\n this.props.onLayout?.(event);\n this.grabZoomSubjectOriginalMeasurements();\n }}\n >\n \n {children}\n \n\n {visualTouchFeedbackEnabled &&\n touches?.map(\n (touch) =>\n doubleTapDelay && (\n {\n this._removeTouch(touch);\n }}\n />\n )\n )}\n\n {/* For Debugging Only */}\n {debugPoints.map(({ x, y }, index) => {\n return ;\n })}\n\n {staticPinPosition && (\n {\n this.setState({ pinSize: size });\n }}\n pinProps={pinProps}\n />\n )}\n \n );\n }\n}\n\nconst styles = StyleSheet.create({\n container: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n overflow: 'hidden',\n position: 'relative',\n },\n zoomSubject: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n width: '100%',\n },\n});\n\nexport default ReactNativeZoomableView;\n\nexport { ReactNativeZoomableView };\n"]} \ No newline at end of file diff --git a/lib/module/ReactNativeZoomableView.js b/lib/module/ReactNativeZoomableView.js index af2e1bf..d6b7d44 100644 --- a/lib/module/ReactNativeZoomableView.js +++ b/lib/module/ReactNativeZoomableView.js @@ -947,7 +947,7 @@ class ReactNativeZoomableView extends Component { * { x: 0, y: 0 } is the very center of the zoom subject. * * @param newZoomLevel - * @param zoomCenter + * @param zoomCenter - If not supplied, the container's center is the zoom center */ diff --git a/lib/module/ReactNativeZoomableView.js.map b/lib/module/ReactNativeZoomableView.js.map index 2aba8ff..c9d79a8 100644 --- a/lib/module/ReactNativeZoomableView.js.map +++ b/lib/module/ReactNativeZoomableView.js.map @@ -1 +1 @@ -{"version":3,"sources":["ReactNativeZoomableView.tsx"],"names":["React","Component","createRef","Animated","Easing","PanResponder","StyleSheet","View","AnimatedTouchFeedback","DebugTouchPoint","calcGestureCenterPoint","calcGestureTouchDistance","calcNewScaledOffsetForZoomCentering","applyPanBoundariesToOffset","viewportPositionToImagePosition","StaticPin","debounce","getBoundaryCrossedAnim","getPanMomentumDecayAnim","getZoomToAnimation","initialState","originalWidth","originalHeight","originalPageX","originalPageY","pinSize","width","height","ReactNativeZoomableView","gestureStarted","v","_gestureStarted","constructor","props","ValueXY","x","y","Value","value","boundaryCrossedAnimInEffect","position","onStaticPinPositionChange","requestAnimationFrame","setTimeout","zoomSubjectWrapperRef","current","measureInWindow","state","setState","e","gestureState","onStartShouldSetPanResponder","_getZoomableViewEventObject","onLongPress","longPressTimeout","longPressDuration","onPanResponderGrant","panAnim","stopAnimation","zoomAnim","raisePin","gestureType","_resolveAndHandleTap","debugPoints","lastGestureCenterPosition","disableMomentum","panEnabled","disablePanOnInitialZoom","zoomLevel","initialZoom","vx","vy","start","clearTimeout","onPanResponderEnd","onZoomEnd","onShiftingEnd","staticPinPosition","_updateStaticPin","dropPin","onPanResponderMove","numberActiveTouches","_handlePanResponderGrant","_handlePanResponderEnd","lastGestureTouchDistance","_handlePinching","Math","abs","dx","dy","isShiftGesture","_handleShifting","now","Date","doubleTapFirstTapReleaseTimestamp","doubleTapDelay","doubleTapFirstTap","_addTouch","id","toString","isSecondTap","singleTapTimeoutId","_handleDoubleTap","nativeEvent","pageX","pageY","persist","tapX","tapY","timing","toValue","offsetX","offsetY","useNativeDriver","duration","onSingleTap","contentWidth","contentHeight","pinX","pinY","setValue","viewportPosition","imageSize","zoomableEvent","_staticPinPosition","gestureHandlers","create","_handleStartShouldSetPanResponder","_handlePanResponderMove","onPanResponderRelease","onPanResponderTerminate","evt","onPanResponderTerminationRequest","onShouldBlockNativeResponder","onStartShouldSetPanResponderCapture","onMoveShouldSetPanResponderCapture","zoomAnimatedValue","panAnimatedValueXY","initialOffsetX","initialOffsetY","addListener","animatePin","pinAnim","easing","out","ease","__setOffset","__getOffset","axis","offset","offsetState","__offsets","bindToBorders","containerSize","contentSize","boundOffset","panBoundaryPadding","boundariesApplied","toFixed","componentDidUpdate","prevProps","prevState","zoomEnabled","onTransformInvocationInitialized","_invokeOnTransform","successful","currState","originalMeasurementsChanged","staticPinPositionChanged","componentDidMount","grabZoomSubjectOriginalMeasurements","measureZoomSubjectInterval","setInterval","componentWillUnmount","clearInterval","zoomableViewEvent","onTransform","onStaticPinPositionMove","debouncedOnStaticPinPositionChange","overwriteObj","maxZoom","minZoom","pinchToZoomInSensitivity","pinchToZoomOutSensitivity","distance","onZoomBefore","zoomGrowthFromLastGestureState","pinchToZoomSensitivity","deltaGrowth","deltaGrowthAdjustedBySensitivity","newZoomLevel","gestureCenterPoint","zoomCenter","debug","_setPinchDebugPoints","oldOffsetX","oldOffsetY","oldScale","newScale","offsetShift","_calcOffsetShiftSinceLastGestureState","onZoomAfter","gestureResponderEvent","points","touches","movementSensibility","shift","shiftX","shiftY","moveX","moveY","_setNewOffsetPosition","newOffsetX","newOffsetY","onShiftingBefore","onShiftingAfter","touch","push","_removeTouch","splice","indexOf","onDoubleTapBefore","onDoubleTapAfter","doubleTapZoomToCenter","nextZoomStep","_getNextZoomStep","zoomPositionCoordinates","zoomTo","zoomStep","listenerId","prevScale","removeListener","zoomBy","zoomLevelChange","moveTo","moveBy","offsetChangeX","offsetChangeY","render","staticPinIcon","children","visualTouchFeedbackEnabled","onStaticPinLongPress","onStaticPinPress","pinProps","styles","container","panHandlers","event","onLayout","zoomSubject","style","transform","scale","getTranslateTransform","map","index","size","undefined","alignItems","flex","justifyContent","overflow"],"mappings":"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","sourcesContent":["import React, { Component, createRef, RefObject } from 'react';\nimport {\n Animated,\n Easing,\n GestureResponderEvent,\n PanResponder,\n PanResponderCallbacks,\n PanResponderGestureState,\n PanResponderInstance,\n StyleSheet,\n View,\n} from 'react-native';\n\nimport {\n Vec2D,\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState,\n TouchPoint,\n ZoomableViewEvent,\n Size2D,\n} from './typings';\n\nimport { AnimatedTouchFeedback } from './components';\nimport { DebugTouchPoint } from './debugHelper';\nimport {\n calcGestureCenterPoint,\n calcGestureTouchDistance,\n calcNewScaledOffsetForZoomCentering,\n} from './helper';\nimport { applyPanBoundariesToOffset } from './helper/applyPanBoundariesToOffset';\nimport { viewportPositionToImagePosition } from './helper/coordinateConversion';\nimport { StaticPin } from './components/StaticPin';\nimport { debounce } from 'lodash';\nimport {\n getBoundaryCrossedAnim,\n getPanMomentumDecayAnim,\n getZoomToAnimation,\n} from './animations';\n\nconst initialState: ReactNativeZoomableViewState = {\n originalWidth: 0,\n originalHeight: 0,\n originalPageX: 0,\n originalPageY: 0,\n pinSize: { width: 0, height: 0 },\n};\n\nclass ReactNativeZoomableView extends Component<\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState\n> {\n zoomSubjectWrapperRef: RefObject;\n gestureHandlers: PanResponderInstance;\n doubleTapFirstTapReleaseTimestamp: number | undefined;\n\n static defaultProps = {\n zoomEnabled: true,\n panEnabled: true,\n initialZoom: 1,\n initialOffsetX: 0,\n initialOffsetY: 0,\n maxZoom: 1.5,\n minZoom: 0.5,\n pinchToZoomInSensitivity: 1,\n pinchToZoomOutSensitivity: 1,\n movementSensibility: 1,\n doubleTapDelay: 300,\n bindToBorders: true,\n zoomStep: 0.5,\n onLongPress: null,\n longPressDuration: 700,\n contentWidth: undefined,\n contentHeight: undefined,\n panBoundaryPadding: 0,\n visualTouchFeedbackEnabled: true,\n staticPinPosition: undefined,\n staticPinIcon: undefined,\n onStaticPinPositionChange: undefined,\n onStaticPinPositionMove: undefined,\n animatePin: true,\n disablePanOnInitialZoom: false,\n };\n\n private panAnim = new Animated.ValueXY({ x: 0, y: 0 });\n private zoomAnim = new Animated.Value(1);\n private pinAnim = new Animated.ValueXY({ x: 0, y: 0 });\n\n private __offsets = {\n x: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n y: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n };\n\n private zoomLevel = 1;\n private lastGestureCenterPosition: { x: number; y: number } | null = null;\n private lastGestureTouchDistance: number | null = null;\n private gestureType: 'pinch' | 'shift' | null;\n\n private _gestureStarted = false;\n private set gestureStarted(v: boolean) {\n this._gestureStarted = v;\n }\n\n public get gestureStarted() {\n return this._gestureStarted;\n }\n\n /**\n * Last press time (used to evaluate whether user double tapped)\n * @type {number}\n */\n private longPressTimeout: NodeJS.Timeout | null = null;\n private onTransformInvocationInitialized: boolean | undefined;\n private singleTapTimeoutId: NodeJS.Timeout | undefined;\n private touches: TouchPoint[] = [];\n private doubleTapFirstTap: TouchPoint | undefined;\n private measureZoomSubjectInterval: NodeJS.Timer | undefined;\n\n constructor(props: ReactNativeZoomableViewProps) {\n super(props);\n // This needs to be done before anything else to initialize the state.\n // Otherwise, the logic below may reference the state when it's undefined,\n // causing runtime errors.\n this.state = { ...initialState };\n\n this.gestureHandlers = PanResponder.create({\n onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,\n onPanResponderGrant: this._handlePanResponderGrant,\n onPanResponderMove: this._handlePanResponderMove,\n onPanResponderRelease: this._handlePanResponderEnd,\n onPanResponderTerminate: (evt, gestureState) => {\n // We should also call _handlePanResponderEnd\n // to properly perform cleanups when the gesture is terminated\n // (aka gesture handling responsibility is taken over by another component).\n // This also fixes a weird issue where\n // on real device, sometimes onPanResponderRelease is not called when you lift 2 fingers up,\n // but onPanResponderTerminate is called instead for no apparent reason.\n this._handlePanResponderEnd(evt, gestureState);\n this.props.onPanResponderTerminate?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n );\n },\n onPanResponderTerminationRequest: (evt, gestureState) =>\n !!this.props.onPanResponderTerminationRequest?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ),\n // Defaults to true to prevent parent components, such as React Navigation's tab view, from taking over as responder.\n onShouldBlockNativeResponder: (evt, gestureState) =>\n this.props.onShouldBlockNativeResponder?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ) ?? true,\n onStartShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onStartShouldSetPanResponderCapture?.(evt, gestureState),\n onMoveShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onMoveShouldSetPanResponderCapture?.(evt, gestureState),\n });\n\n this.zoomSubjectWrapperRef = createRef();\n\n if (this.props.zoomAnimatedValue)\n this.zoomAnim = this.props.zoomAnimatedValue;\n if (this.props.panAnimatedValueXY)\n this.panAnim = this.props.panAnimatedValueXY;\n\n if (this.props.initialZoom) this.zoomLevel = this.props.initialZoom;\n if (this.props.initialOffsetX != null)\n this.offsetX = this.props.initialOffsetX;\n if (this.props.initialOffsetY != null)\n this.offsetY = this.props.initialOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n this.panAnim.addListener(({ x, y }) => {\n this.offsetX = x;\n this.offsetY = y;\n });\n this.zoomAnim.addListener(({ value }) => {\n this.zoomLevel = value;\n });\n\n this.lastGestureTouchDistance = 150;\n\n this.gestureType = null;\n }\n\n private raisePin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: -10 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private dropPin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: 0 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private set offsetX(x: number) {\n this.__setOffset('x', x);\n }\n\n private set offsetY(y: number) {\n this.__setOffset('y', y);\n }\n\n private get offsetX() {\n return this.__getOffset('x');\n }\n\n private get offsetY() {\n return this.__getOffset('y');\n }\n\n private __setOffset(axis: 'x' | 'y', offset: number) {\n const offsetState = this.__offsets[axis];\n\n if (this.props.bindToBorders) {\n const containerSize =\n axis === 'x' ? this.state.originalWidth : this.state.originalHeight;\n const contentSize =\n axis === 'x'\n ? this.props.contentWidth || this.state.originalWidth\n : this.props.contentHeight || this.state.originalHeight;\n\n const boundOffset =\n contentSize && containerSize && this.props.panBoundaryPadding != null\n ? applyPanBoundariesToOffset(\n offset,\n containerSize,\n contentSize,\n this.zoomLevel,\n this.props.panBoundaryPadding\n )\n : offset;\n\n if (!this.gestureType && !offsetState.boundaryCrossedAnimInEffect) {\n const boundariesApplied =\n boundOffset !== offset &&\n boundOffset.toFixed(3) !== offset.toFixed(3);\n if (boundariesApplied) {\n offsetState.boundaryCrossedAnimInEffect = true;\n getBoundaryCrossedAnim(this.panAnim[axis], boundOffset).start(() => {\n offsetState.boundaryCrossedAnimInEffect = false;\n });\n return;\n }\n }\n }\n\n offsetState.value = offset;\n }\n\n private __getOffset(axis: 'x' | 'y') {\n return this.__offsets[axis].value;\n }\n\n componentDidUpdate(\n prevProps: ReactNativeZoomableViewProps,\n prevState: ReactNativeZoomableViewState\n ) {\n const { zoomEnabled, initialZoom } = this.props;\n if (prevProps.zoomEnabled && !zoomEnabled && initialZoom) {\n this.zoomLevel = initialZoom;\n this.zoomAnim.setValue(this.zoomLevel);\n }\n if (\n !this.onTransformInvocationInitialized &&\n this._invokeOnTransform().successful\n ) {\n this.panAnim.addListener(() => this._invokeOnTransform());\n this.zoomAnim.addListener(() => this._invokeOnTransform());\n this.onTransformInvocationInitialized = true;\n }\n\n const currState = this.state;\n const originalMeasurementsChanged =\n currState.originalHeight !== prevState.originalHeight ||\n currState.originalWidth !== prevState.originalWidth ||\n currState.originalPageX !== prevState.originalPageX ||\n currState.originalPageY !== prevState.originalPageY;\n\n const staticPinPositionChanged =\n prevProps.staticPinPosition?.x !== this.props.staticPinPosition?.x ||\n prevProps.staticPinPosition?.y !== this.props.staticPinPosition?.y;\n\n if (\n this.onTransformInvocationInitialized &&\n (originalMeasurementsChanged || staticPinPositionChanged)\n ) {\n this._invokeOnTransform();\n }\n }\n\n componentDidMount() {\n this.grabZoomSubjectOriginalMeasurements();\n // We've already run `grabZoomSubjectOriginalMeasurements` at various events\n // to make sure the measurements are promptly updated.\n // However, there might be cases we haven't accounted for, especially when\n // native processes are involved. To account for those cases,\n // we'll use an interval here to ensure we're always up-to-date.\n // The `setState` in `grabZoomSubjectOriginalMeasurements` won't trigger a rerender\n // if the values given haven't changed, so we're not running performance risk here.\n this.measureZoomSubjectInterval = setInterval(\n this.grabZoomSubjectOriginalMeasurements,\n 1e3\n );\n }\n\n componentWillUnmount() {\n this.measureZoomSubjectInterval &&\n clearInterval(this.measureZoomSubjectInterval);\n }\n\n debouncedOnStaticPinPositionChange = debounce(\n (position: Vec2D) => this.props.onStaticPinPositionChange?.(position),\n 100\n );\n\n /**\n * try to invoke onTransform\n * @private\n */\n _invokeOnTransform() {\n const zoomableViewEvent = this._getZoomableViewEventObject();\n const position = this._staticPinPosition();\n\n if (!zoomableViewEvent.originalWidth || !zoomableViewEvent.originalHeight)\n return { successful: false };\n\n this.props.onTransform?.(zoomableViewEvent);\n\n if (position) {\n this.props.onStaticPinPositionMove?.(position);\n this.debouncedOnStaticPinPositionChange(position);\n }\n\n return { successful: true };\n }\n\n /**\n * Returns additional information about components current state for external event hooks\n *\n * @returns {{}}\n * @private\n */\n _getZoomableViewEventObject(overwriteObj = {}): ZoomableViewEvent {\n return {\n zoomLevel: this.zoomLevel,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n originalHeight: this.state.originalHeight,\n originalWidth: this.state.originalWidth,\n originalPageX: this.state.originalPageX,\n originalPageY: this.state.originalPageY,\n ...overwriteObj,\n } as ZoomableViewEvent;\n }\n\n /**\n * Get the original box dimensions and save them for later use.\n * (They will be used to calculate boxBorders)\n *\n * @private\n */\n private grabZoomSubjectOriginalMeasurements = () => {\n // make sure we measure after animations are complete\n requestAnimationFrame(() => {\n // this setTimeout is here to fix a weird issue on iOS where the measurements are all `0`\n // when navigating back (react-navigation stack) from another view\n // while closing the keyboard at the same time\n setTimeout(() => {\n // In normal conditions, we're supposed to measure zoomSubject instead of its wrapper.\n // However, our zoomSubject may have been transformed by an initial zoomLevel or offset,\n // in which case these measurements will not represent the true \"original\" measurements.\n // We just need to make sure the zoomSubjectWrapper perfectly aligns with the zoomSubject\n // (no border, space, or anything between them)\n const zoomSubjectWrapperRef = this.zoomSubjectWrapperRef;\n // we don't wanna measure when zoomSubjectWrapperRef is not yet available or has been unmounted\n zoomSubjectWrapperRef.current?.measureInWindow(\n (x, y, width, height) => {\n // When the component is off-screen, these become all 0s, so we don't set them\n // to avoid messing up calculations, especially ones that are done right after\n // the component transitions from hidden to visible.\n if (!x && !y && !width && !height) return;\n\n // If these values are all the same, don't re-set them in state\n // this way we don't re-render\n if (\n this.state.originalWidth === width &&\n this.state.originalHeight === height &&\n this.state.originalPageX === x &&\n this.state.originalPageY === y\n ) {\n return;\n }\n\n this.setState({\n originalWidth: width,\n originalHeight: height,\n originalPageX: x,\n originalPageY: y,\n });\n }\n );\n });\n });\n };\n\n /**\n * Handles the start of touch events and checks for taps\n *\n * @param e\n * @param gestureState\n * @returns {boolean}\n *\n * @private\n */\n _handleStartShouldSetPanResponder = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onStartShouldSetPanResponder) {\n this.props.onStartShouldSetPanResponder(\n e,\n gestureState,\n this._getZoomableViewEventObject(),\n false\n );\n }\n\n // Always set pan responder on start\n // of gesture so we can handle tap.\n // \"Pan threshold validation\" will be handled\n // in `onPanResponderMove` instead of in `onMoveShouldSetPanResponder`\n return true;\n };\n\n /**\n * Calculates pinch distance\n *\n * @param e\n * @param gestureState\n * @private\n */\n _handlePanResponderGrant: NonNullable<\n PanResponderCallbacks['onPanResponderGrant']\n > = (e, gestureState) => {\n if (this.props.onLongPress) {\n this.longPressTimeout = setTimeout(() => {\n this.props.onLongPress?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n this.longPressTimeout = null;\n }, this.props.longPressDuration);\n }\n\n this.props.onPanResponderGrant?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n this.panAnim.stopAnimation();\n this.zoomAnim.stopAnimation();\n this.gestureStarted = true;\n\n this.raisePin();\n };\n\n /**\n * Handles the end of touch events\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderEnd: NonNullable<\n PanResponderCallbacks['onPanResponderEnd']\n > = (e, gestureState) => {\n if (!this.gestureType) {\n this._resolveAndHandleTap(e);\n }\n\n this.setState({ debugPoints: [] });\n\n this.lastGestureCenterPosition = null;\n\n const disableMomentum =\n this.props.disableMomentum ||\n (this.props.panEnabled &&\n this.gestureType === 'shift' &&\n this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom);\n\n // Trigger final shift animation unless disablePanOnInitialZoom is set and we're on the initial zoom level\n // or disableMomentum\n if (!disableMomentum) {\n getPanMomentumDecayAnim(this.panAnim, {\n x: gestureState.vx / this.zoomLevel,\n y: gestureState.vy / this.zoomLevel,\n }).start();\n }\n\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n this.props.onPanResponderEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n if (this.gestureType === 'pinch') {\n this.props.onZoomEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n } else if (this.gestureType === 'shift') {\n this.props.onShiftingEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n if (this.props.staticPinPosition) {\n this._updateStaticPin();\n }\n\n this.dropPin();\n\n this.gestureType = null;\n this.gestureStarted = false;\n };\n\n /**\n * Handles the actual movement of our pan responder\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderMove = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onPanResponderMove) {\n if (\n this.props.onPanResponderMove(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return false;\n }\n }\n\n // Only supports 2 touches and below,\n // any invalid number will cause the gesture to end.\n if (gestureState.numberActiveTouches <= 2) {\n if (!this.gestureStarted) {\n this._handlePanResponderGrant(e, gestureState);\n }\n } else {\n if (this.gestureStarted) {\n this._handlePanResponderEnd(e, gestureState);\n }\n return true;\n }\n\n if (gestureState.numberActiveTouches === 2) {\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'pinch') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n this.lastGestureTouchDistance = calcGestureTouchDistance(\n e,\n gestureState\n );\n }\n this.gestureType = 'pinch';\n this._handlePinching(e, gestureState);\n } else if (gestureState.numberActiveTouches === 1) {\n if (\n this.longPressTimeout &&\n (Math.abs(gestureState.dx) > 5 || Math.abs(gestureState.dy) > 5)\n ) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'shift') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n }\n\n const { dx, dy } = gestureState;\n const isShiftGesture = Math.abs(dx) > 2 || Math.abs(dy) > 2;\n if (isShiftGesture) {\n this.gestureType = 'shift';\n this._handleShifting(gestureState);\n }\n }\n };\n\n /**\n * Handles the pinch movement and zooming\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePinching(\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) {\n if (!this.props.zoomEnabled) return;\n\n const {\n maxZoom,\n minZoom,\n pinchToZoomInSensitivity,\n pinchToZoomOutSensitivity,\n } = this.props;\n\n const distance = calcGestureTouchDistance(e, gestureState);\n\n if (\n this.props.onZoomBefore &&\n this.props.onZoomBefore(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return;\n }\n\n if (!distance) return;\n if (!this.lastGestureTouchDistance) return;\n\n // define the new zoom level and take zoom level sensitivity into consideration\n const zoomGrowthFromLastGestureState =\n distance / this.lastGestureTouchDistance;\n this.lastGestureTouchDistance = distance;\n\n const pinchToZoomSensitivity =\n zoomGrowthFromLastGestureState < 1\n ? pinchToZoomOutSensitivity\n : pinchToZoomInSensitivity;\n\n if (pinchToZoomSensitivity == null) return;\n const deltaGrowth = zoomGrowthFromLastGestureState - 1;\n // 0 - no resistance\n // 10 - 90% resistance\n const deltaGrowthAdjustedBySensitivity =\n deltaGrowth * (1 - (pinchToZoomSensitivity * 9) / 100);\n\n let newZoomLevel = this.zoomLevel * (1 + deltaGrowthAdjustedBySensitivity);\n\n // make sure max and min zoom levels are respected\n if (maxZoom != null && newZoomLevel > maxZoom) {\n newZoomLevel = maxZoom;\n }\n\n if (minZoom != null && newZoomLevel < minZoom) {\n newZoomLevel = minZoom;\n }\n\n const gestureCenterPoint = calcGestureCenterPoint(e, gestureState);\n\n if (!gestureCenterPoint) return;\n\n let zoomCenter = {\n x: gestureCenterPoint.x - this.state.originalPageX,\n y: gestureCenterPoint.y - this.state.originalPageY,\n };\n\n if (this.props.staticPinPosition) {\n // When we use a static pin position, the zoom centre is the same as that position,\n // otherwise the pin moves around way too much while zooming.\n zoomCenter = {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n };\n }\n\n // Uncomment to debug\n this.props.debug && this._setPinchDebugPoints(e, zoomCenter);\n\n const { originalHeight, originalWidth } = this.state;\n\n const oldOffsetX = this.offsetX;\n const oldOffsetY = this.offsetY;\n const oldScale = this.zoomLevel;\n const newScale = newZoomLevel;\n\n if (!originalHeight || !originalWidth) return;\n\n let offsetY = calcNewScaledOffsetForZoomCentering(\n oldOffsetY,\n originalHeight,\n oldScale,\n newScale,\n zoomCenter.y\n );\n let offsetX = calcNewScaledOffsetForZoomCentering(\n oldOffsetX,\n originalWidth,\n oldScale,\n newScale,\n zoomCenter.x\n );\n\n const offsetShift =\n this._calcOffsetShiftSinceLastGestureState(gestureCenterPoint);\n if (offsetShift) {\n offsetX += offsetShift.x;\n offsetY += offsetShift.y;\n }\n\n this.offsetX = offsetX;\n this.offsetY = offsetY;\n this.zoomLevel = newScale;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n this.props.onZoomAfter?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n /**\n * Used to debug pinch events\n * @param gestureResponderEvent\n * @param zoomCenter\n * @param points\n */\n _setPinchDebugPoints(\n gestureResponderEvent: GestureResponderEvent,\n zoomCenter: Vec2D,\n ...points: Vec2D[]\n ) {\n const { touches } = gestureResponderEvent.nativeEvent;\n const { originalPageY, originalPageX } = this.state;\n\n this.setState({\n debugPoints: [\n {\n x: touches[0].pageX - originalPageX,\n y: touches[0].pageY - originalPageY,\n },\n {\n x: touches[1].pageX - originalPageX,\n y: touches[1].pageY - originalPageY,\n },\n zoomCenter,\n ...points,\n ],\n });\n }\n\n /**\n * Calculates the amount the offset should shift since the last position during panning\n *\n * @param {Vec2D} gestureCenterPoint\n *\n * @private\n */\n _calcOffsetShiftSinceLastGestureState(gestureCenterPoint: Vec2D) {\n const { movementSensibility } = this.props;\n\n let shift = null;\n\n if (this.lastGestureCenterPosition && movementSensibility) {\n const dx = gestureCenterPoint.x - this.lastGestureCenterPosition.x;\n const dy = gestureCenterPoint.y - this.lastGestureCenterPosition.y;\n\n const shiftX = dx / this.zoomLevel / movementSensibility;\n const shiftY = dy / this.zoomLevel / movementSensibility;\n\n shift = {\n x: shiftX,\n y: shiftY,\n };\n }\n\n this.lastGestureCenterPosition = gestureCenterPoint;\n\n return shift;\n }\n\n /**\n * Handles movement by tap and move\n *\n * @param gestureState\n *\n * @private\n */\n _handleShifting(gestureState: PanResponderGestureState) {\n // Skips shifting if panEnabled is false or disablePanOnInitialZoom is true and we're on the initial zoom level\n if (\n !this.props.panEnabled ||\n (this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom)\n ) {\n return;\n }\n const shift = this._calcOffsetShiftSinceLastGestureState({\n x: gestureState.moveX,\n y: gestureState.moveY,\n });\n if (!shift) return;\n\n const offsetX = this.offsetX + shift.x;\n const offsetY = this.offsetY + shift.y;\n\n if (\n this.props.debug &&\n this.state.originalPageX &&\n this.state.originalPageY\n ) {\n const x = gestureState.moveX - this.state.originalPageX;\n const y = gestureState.moveY - this.state.originalPageY;\n this.setState({ debugPoints: [{ x, y }] });\n }\n\n this._setNewOffsetPosition(offsetX, offsetY);\n\n this.raisePin();\n }\n\n /**\n * Set the state to offset moved\n *\n * @param {number} newOffsetX\n * @param {number} newOffsetY\n * @returns\n */\n _setNewOffsetPosition(newOffsetX: number, newOffsetY: number) {\n const { onShiftingBefore, onShiftingAfter } = this.props;\n\n if (onShiftingBefore?.(null, null, this._getZoomableViewEventObject())) {\n return;\n }\n\n this.offsetX = newOffsetX;\n this.offsetY = newOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n onShiftingAfter?.(null, null, this._getZoomableViewEventObject());\n }\n\n /**\n * Check whether the press event is double tap\n * or single tap and handle the event accordingly\n *\n * @param e\n *\n * @private\n */\n private _resolveAndHandleTap = (e: GestureResponderEvent) => {\n const now = Date.now();\n if (\n this.doubleTapFirstTapReleaseTimestamp &&\n this.props.doubleTapDelay &&\n now - this.doubleTapFirstTapReleaseTimestamp < this.props.doubleTapDelay\n ) {\n this.doubleTapFirstTap &&\n this._addTouch({\n ...this.doubleTapFirstTap,\n id: now.toString(),\n isSecondTap: true,\n });\n this.singleTapTimeoutId && clearTimeout(this.singleTapTimeoutId);\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n delete this.doubleTapFirstTap;\n this._handleDoubleTap(e);\n } else {\n this.doubleTapFirstTapReleaseTimestamp = now;\n this.doubleTapFirstTap = {\n id: now.toString(),\n x: e.nativeEvent.pageX - this.state.originalPageX,\n y: e.nativeEvent.pageY - this.state.originalPageY,\n };\n this._addTouch(this.doubleTapFirstTap);\n\n // persist event so e.nativeEvent is preserved after a timeout delay\n e.persist();\n this.singleTapTimeoutId = setTimeout(() => {\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n\n // Pan to the tapped location\n if (this.props.staticPinPosition && this.doubleTapFirstTap) {\n const tapX =\n this.props.staticPinPosition.x - this.doubleTapFirstTap.x;\n const tapY =\n this.props.staticPinPosition.y - this.doubleTapFirstTap.y;\n\n Animated.timing(this.panAnim, {\n toValue: {\n x: this.offsetX + tapX / this.zoomLevel,\n y: this.offsetY + tapY / this.zoomLevel,\n },\n useNativeDriver: true,\n duration: 200,\n }).start(() => {\n this._updateStaticPin();\n });\n }\n\n this.props.onSingleTap?.(e, this._getZoomableViewEventObject());\n }, this.props.doubleTapDelay);\n }\n };\n\n moveStaticPinTo = (position: Vec2D, duration?: number) => {\n const { originalWidth, originalHeight } = this.state;\n const { staticPinPosition, contentWidth, contentHeight } = this.props;\n\n if (!staticPinPosition) return;\n if (!originalWidth || !originalHeight) return;\n if (!contentWidth || !contentHeight) return;\n\n // Offset for the static pin\n const pinX = staticPinPosition.x - originalWidth / 2;\n const pinY = staticPinPosition.y - originalHeight / 2;\n\n this.offsetX = contentWidth / 2 - position.x + pinX / this.zoomLevel;\n this.offsetY = contentHeight / 2 - position.y + pinY / this.zoomLevel;\n\n if (duration) {\n Animated.timing(this.panAnim, {\n toValue: { x: this.offsetX, y: this.offsetY },\n useNativeDriver: true,\n duration,\n }).start();\n } else {\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n }\n };\n\n private _staticPinPosition = () => {\n if (!this.props.staticPinPosition) return;\n if (!this.props.contentWidth || !this.props.contentHeight) return;\n\n return viewportPositionToImagePosition({\n viewportPosition: {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n },\n imageSize: {\n height: this.props.contentHeight,\n width: this.props.contentWidth,\n },\n zoomableEvent: {\n ...this._getZoomableViewEventObject(),\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n zoomLevel: this.zoomLevel,\n },\n });\n };\n\n private _updateStaticPin = () => {\n const position = this._staticPinPosition();\n if (!position) return;\n this.props.onStaticPinPositionChange?.(position);\n };\n\n private _addTouch(touch: TouchPoint) {\n this.touches.push(touch);\n this.setState({ touches: [...this.touches] });\n }\n\n private _removeTouch(touch: TouchPoint) {\n this.touches.splice(this.touches.indexOf(touch), 1);\n this.setState({ touches: [...this.touches] });\n }\n\n /**\n * Handles the double tap event\n *\n * @param e\n *\n * @private\n */\n _handleDoubleTap(e: GestureResponderEvent) {\n const { onDoubleTapBefore, onDoubleTapAfter, doubleTapZoomToCenter } =\n this.props;\n\n onDoubleTapBefore?.(e, this._getZoomableViewEventObject());\n\n const nextZoomStep = this._getNextZoomStep();\n if (nextZoomStep == null) return;\n\n const { originalPageX, originalPageY } = this.state;\n\n // define new zoom position coordinates\n const zoomPositionCoordinates = {\n x: e.nativeEvent.pageX - originalPageX,\n y: e.nativeEvent.pageY - originalPageY,\n };\n\n // if doubleTapZoomToCenter enabled -> always zoom to center instead\n if (doubleTapZoomToCenter) {\n zoomPositionCoordinates.x = 0;\n zoomPositionCoordinates.y = 0;\n }\n\n this.zoomTo(nextZoomStep, zoomPositionCoordinates);\n\n onDoubleTapAfter?.(\n e,\n this._getZoomableViewEventObject({ zoomLevel: nextZoomStep })\n );\n }\n\n /**\n * Returns the next zoom step based on current step and zoomStep property.\n * If we are zoomed all the way in -> return to initialzoom\n *\n * @returns {*}\n */\n _getNextZoomStep() {\n const { zoomStep, maxZoom, initialZoom } = this.props;\n const { zoomLevel } = this;\n\n if (maxZoom == null) return;\n\n if (zoomLevel.toFixed(2) === maxZoom.toFixed(2)) {\n return initialZoom;\n }\n\n if (zoomStep == null) return;\n\n const nextZoomStep = zoomLevel * (1 + zoomStep);\n if (nextZoomStep > maxZoom) {\n return maxZoom;\n }\n\n return nextZoomStep;\n }\n\n /**\n * Zooms to a specific level. A \"zoom center\" can be provided, which specifies\n * the point that will remain in the same position on the screen after the zoom.\n * The coordinates of the zoom center is relative to the zoom subject.\n * { x: 0, y: 0 } is the very center of the zoom subject.\n *\n * @param newZoomLevel\n * @param zoomCenter\n */\n zoomTo(newZoomLevel: number, zoomCenter?: Vec2D) {\n if (!this.props.zoomEnabled) return false;\n if (this.props.maxZoom && newZoomLevel > this.props.maxZoom) return false;\n if (this.props.minZoom && newZoomLevel < this.props.minZoom) return false;\n\n this.props.onZoomBefore?.(null, null, this._getZoomableViewEventObject());\n\n // == Perform Pan Animation to preserve the zoom center while zooming ==\n let listenerId: string | undefined;\n if (zoomCenter) {\n // Calculates panAnim values based on changes in zoomAnim.\n let prevScale = this.zoomLevel;\n // Since zoomAnim is calculated in native driver,\n // it will jitter panAnim once in a while,\n // because here panAnim is being calculated in js.\n // However the jittering should mostly occur in simulator.\n listenerId = this.zoomAnim.addListener(({ value: newScale }) => {\n this.panAnim.setValue({\n x: calcNewScaledOffsetForZoomCentering(\n this.offsetX,\n this.state.originalWidth,\n prevScale,\n newScale,\n zoomCenter.x\n ),\n y: calcNewScaledOffsetForZoomCentering(\n this.offsetY,\n this.state.originalHeight,\n prevScale,\n newScale,\n zoomCenter.y\n ),\n });\n prevScale = newScale;\n });\n }\n\n // == Perform Zoom Animation ==\n getZoomToAnimation(this.zoomAnim, newZoomLevel).start(() => {\n if (!listenerId) return;\n this.zoomAnim.removeListener(listenerId);\n });\n // == Zoom Animation Ends ==\n\n this.props.onZoomAfter?.(null, null, this._getZoomableViewEventObject());\n return true;\n }\n\n /**\n * Zooms in or out by a specified change level\n * Use a positive number for `zoomLevelChange` to zoom in\n * Use a negative number for `zoomLevelChange` to zoom out\n *\n * Returns a promise if everything was updated and a boolean, whether it could be updated or if it exceeded the min/max zoom limits.\n *\n * @param {number | null} zoomLevelChange\n *\n * @return {bool}\n */\n zoomBy(zoomLevelChange: number) {\n // if no zoom level Change given -> just use zoom step\n zoomLevelChange ||= this.props.zoomStep || 0;\n return this.zoomTo(this.zoomLevel + zoomLevelChange);\n }\n\n /**\n * Moves the zoomed view to a specified position\n * Returns a promise when finished\n *\n * @param {number} newOffsetX the new position we want to move it to (x-axis)\n * @param {number} newOffsetY the new position we want to move it to (y-axis)\n *\n * @return {bool}\n */\n moveTo(newOffsetX: number, newOffsetY: number) {\n const { originalWidth, originalHeight } = this.state;\n if (!originalWidth || !originalHeight) return;\n\n const offsetX = (newOffsetX - originalWidth / 2) / this.zoomLevel;\n const offsetY = (newOffsetY - originalHeight / 2) / this.zoomLevel;\n\n this._setNewOffsetPosition(-offsetX, -offsetY);\n }\n\n /**\n * Moves the zoomed view by a certain amount.\n *\n * Returns a promise when finished\n *\n * @param {number} offsetChangeX the amount we want to move the offset by (x-axis)\n * @param {number} offsetChangeY the amount we want to move the offset by (y-axis)\n *\n * @return {bool}\n */\n moveBy(offsetChangeX: number, offsetChangeY: number) {\n const offsetX =\n (this.offsetX * this.zoomLevel - offsetChangeX) / this.zoomLevel;\n const offsetY =\n (this.offsetY * this.zoomLevel - offsetChangeY) / this.zoomLevel;\n\n this._setNewOffsetPosition(offsetX, offsetY);\n }\n\n render() {\n const {\n staticPinIcon,\n children,\n visualTouchFeedbackEnabled,\n doubleTapDelay,\n staticPinPosition,\n onStaticPinLongPress,\n onStaticPinPress,\n pinProps,\n } = this.props;\n const { pinSize, touches, debugPoints = [] } = this.state;\n\n return (\n {\n this.props.onLayout?.(event);\n this.grabZoomSubjectOriginalMeasurements();\n }}\n >\n \n {children}\n \n\n {visualTouchFeedbackEnabled &&\n touches?.map(\n (touch) =>\n doubleTapDelay && (\n {\n this._removeTouch(touch);\n }}\n />\n )\n )}\n\n {/* For Debugging Only */}\n {debugPoints.map(({ x, y }, index) => {\n return ;\n })}\n\n {staticPinPosition && (\n {\n this.setState({ pinSize: size });\n }}\n pinProps={pinProps}\n />\n )}\n \n );\n }\n}\n\nconst styles = StyleSheet.create({\n container: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n overflow: 'hidden',\n position: 'relative',\n },\n zoomSubject: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n width: '100%',\n },\n});\n\nexport default ReactNativeZoomableView;\n\nexport { ReactNativeZoomableView };\n"]} \ No newline at end of file +{"version":3,"sources":["ReactNativeZoomableView.tsx"],"names":["React","Component","createRef","Animated","Easing","PanResponder","StyleSheet","View","AnimatedTouchFeedback","DebugTouchPoint","calcGestureCenterPoint","calcGestureTouchDistance","calcNewScaledOffsetForZoomCentering","applyPanBoundariesToOffset","viewportPositionToImagePosition","StaticPin","debounce","getBoundaryCrossedAnim","getPanMomentumDecayAnim","getZoomToAnimation","initialState","originalWidth","originalHeight","originalPageX","originalPageY","pinSize","width","height","ReactNativeZoomableView","gestureStarted","v","_gestureStarted","constructor","props","ValueXY","x","y","Value","value","boundaryCrossedAnimInEffect","position","onStaticPinPositionChange","requestAnimationFrame","setTimeout","zoomSubjectWrapperRef","current","measureInWindow","state","setState","e","gestureState","onStartShouldSetPanResponder","_getZoomableViewEventObject","onLongPress","longPressTimeout","longPressDuration","onPanResponderGrant","panAnim","stopAnimation","zoomAnim","raisePin","gestureType","_resolveAndHandleTap","debugPoints","lastGestureCenterPosition","disableMomentum","panEnabled","disablePanOnInitialZoom","zoomLevel","initialZoom","vx","vy","start","clearTimeout","onPanResponderEnd","onZoomEnd","onShiftingEnd","staticPinPosition","_updateStaticPin","dropPin","onPanResponderMove","numberActiveTouches","_handlePanResponderGrant","_handlePanResponderEnd","lastGestureTouchDistance","_handlePinching","Math","abs","dx","dy","isShiftGesture","_handleShifting","now","Date","doubleTapFirstTapReleaseTimestamp","doubleTapDelay","doubleTapFirstTap","_addTouch","id","toString","isSecondTap","singleTapTimeoutId","_handleDoubleTap","nativeEvent","pageX","pageY","persist","tapX","tapY","timing","toValue","offsetX","offsetY","useNativeDriver","duration","onSingleTap","contentWidth","contentHeight","pinX","pinY","setValue","viewportPosition","imageSize","zoomableEvent","_staticPinPosition","gestureHandlers","create","_handleStartShouldSetPanResponder","_handlePanResponderMove","onPanResponderRelease","onPanResponderTerminate","evt","onPanResponderTerminationRequest","onShouldBlockNativeResponder","onStartShouldSetPanResponderCapture","onMoveShouldSetPanResponderCapture","zoomAnimatedValue","panAnimatedValueXY","initialOffsetX","initialOffsetY","addListener","animatePin","pinAnim","easing","out","ease","__setOffset","__getOffset","axis","offset","offsetState","__offsets","bindToBorders","containerSize","contentSize","boundOffset","panBoundaryPadding","boundariesApplied","toFixed","componentDidUpdate","prevProps","prevState","zoomEnabled","onTransformInvocationInitialized","_invokeOnTransform","successful","currState","originalMeasurementsChanged","staticPinPositionChanged","componentDidMount","grabZoomSubjectOriginalMeasurements","measureZoomSubjectInterval","setInterval","componentWillUnmount","clearInterval","zoomableViewEvent","onTransform","onStaticPinPositionMove","debouncedOnStaticPinPositionChange","overwriteObj","maxZoom","minZoom","pinchToZoomInSensitivity","pinchToZoomOutSensitivity","distance","onZoomBefore","zoomGrowthFromLastGestureState","pinchToZoomSensitivity","deltaGrowth","deltaGrowthAdjustedBySensitivity","newZoomLevel","gestureCenterPoint","zoomCenter","debug","_setPinchDebugPoints","oldOffsetX","oldOffsetY","oldScale","newScale","offsetShift","_calcOffsetShiftSinceLastGestureState","onZoomAfter","gestureResponderEvent","points","touches","movementSensibility","shift","shiftX","shiftY","moveX","moveY","_setNewOffsetPosition","newOffsetX","newOffsetY","onShiftingBefore","onShiftingAfter","touch","push","_removeTouch","splice","indexOf","onDoubleTapBefore","onDoubleTapAfter","doubleTapZoomToCenter","nextZoomStep","_getNextZoomStep","zoomPositionCoordinates","zoomTo","zoomStep","listenerId","prevScale","removeListener","zoomBy","zoomLevelChange","moveTo","moveBy","offsetChangeX","offsetChangeY","render","staticPinIcon","children","visualTouchFeedbackEnabled","onStaticPinLongPress","onStaticPinPress","pinProps","styles","container","panHandlers","event","onLayout","zoomSubject","style","transform","scale","getTranslateTransform","map","index","size","undefined","alignItems","flex","justifyContent","overflow"],"mappings":";;;;AAAA,OAAOA,KAAP,IAAgBC,SAAhB,EAA2BC,SAA3B,QAAuD,OAAvD;AACA,SACEC,QADF,EAEEC,MAFF,EAIEC,YAJF,EAQEC,UARF,EASEC,IATF,QAUO,cAVP;AAqBA,SAASC,qBAAT,QAAsC,cAAtC;AACA,SAASC,eAAT,QAAgC,eAAhC;AACA,SACEC,sBADF,EAEEC,wBAFF,EAGEC,mCAHF,QAIO,UAJP;AAKA,SAASC,0BAAT,QAA2C,qCAA3C;AACA,SAASC,+BAAT,QAAgD,+BAAhD;AACA,SAASC,SAAT,QAA0B,wBAA1B;AACA,SAASC,QAAT,QAAyB,QAAzB;AACA,SACEC,sBADF,EAEEC,uBAFF,EAGEC,kBAHF,QAIO,cAJP;AAMA,MAAMC,YAA0C,GAAG;AACjDC,EAAAA,aAAa,EAAE,CADkC;AAEjDC,EAAAA,cAAc,EAAE,CAFiC;AAGjDC,EAAAA,aAAa,EAAE,CAHkC;AAIjDC,EAAAA,aAAa,EAAE,CAJkC;AAKjDC,EAAAA,OAAO,EAAE;AAAEC,IAAAA,KAAK,EAAE,CAAT;AAAYC,IAAAA,MAAM,EAAE;AAApB;AALwC,CAAnD;;AAQA,MAAMC,uBAAN,SAAsC3B,SAAtC,CAGE;AAsD0B,MAAd4B,cAAc,CAACC,CAAD,EAAa;AACrC,SAAKC,eAAL,GAAuBD,CAAvB;AACD;;AAEwB,MAAdD,cAAc,GAAG;AAC1B,WAAO,KAAKE,eAAZ;AACD;AAED;AACF;AACA;AACA;;;AAQEC,EAAAA,WAAW,CAACC,KAAD,EAAsC;AAC/C,UAAMA,KAAN,EAD+C,CAE/C;AACA;AACA;;AAJ+C;;AAAA;;AAAA;;AAAA,qCAxC/B,IAAI9B,QAAQ,CAAC+B,OAAb,CAAqB;AAAEC,MAAAA,CAAC,EAAE,CAAL;AAAQC,MAAAA,CAAC,EAAE;AAAX,KAArB,CAwC+B;;AAAA,sCAvC9B,IAAIjC,QAAQ,CAACkC,KAAb,CAAmB,CAAnB,CAuC8B;;AAAA,qCAtC/B,IAAIlC,QAAQ,CAAC+B,OAAb,CAAqB;AAAEC,MAAAA,CAAC,EAAE,CAAL;AAAQC,MAAAA,CAAC,EAAE;AAAX,KAArB,CAsC+B;;AAAA,uCApC7B;AAClBD,MAAAA,CAAC,EAAE;AACDG,QAAAA,KAAK,EAAE,CADN;AAEDC,QAAAA,2BAA2B,EAAE;AAF5B,OADe;AAKlBH,MAAAA,CAAC,EAAE;AACDE,QAAAA,KAAK,EAAE,CADN;AAEDC,QAAAA,2BAA2B,EAAE;AAF5B;AALe,KAoC6B;;AAAA,uCAzB7B,CAyB6B;;AAAA,uDAxBoB,IAwBpB;;AAAA,sDAvBC,IAuBD;;AAAA;;AAAA,6CApBvB,KAoBuB;;AAAA,8CAPC,IAOD;;AAAA;;AAAA;;AAAA,qCAJjB,EAIiB;;AAAA;;AAAA;;AAAA,gEAiNZvB,QAAQ,CAC1CwB,QAAD;AAAA;;AAAA,sCAAqB,oBAAKP,KAAL,EAAWQ,yBAAhC,0DAAqB,wCAAuCD,QAAvC,CAArB;AAAA,KAD2C,EAE3C,GAF2C,CAjNI;;AAAA,iEAoQH,MAAM;AAClD;AACAE,MAAAA,qBAAqB,CAAC,MAAM;AAC1B;AACA;AACA;AACAC,QAAAA,UAAU,CAAC,MAAM;AAAA;;AACf;AACA;AACA;AACA;AACA;AACA,gBAAMC,qBAAqB,GAAG,KAAKA,qBAAnC,CANe,CAOf;;AACA,mCAAAA,qBAAqB,CAACC,OAAtB,gFAA+BC,eAA/B,CACE,CAACX,CAAD,EAAIC,CAAJ,EAAOV,KAAP,EAAcC,MAAd,KAAyB;AACvB;AACA;AACA;AACA,gBAAI,CAACQ,CAAD,IAAM,CAACC,CAAP,IAAY,CAACV,KAAb,IAAsB,CAACC,MAA3B,EAAmC,OAJZ,CAMvB;AACA;;AACA,gBACE,KAAKoB,KAAL,CAAW1B,aAAX,KAA6BK,KAA7B,IACA,KAAKqB,KAAL,CAAWzB,cAAX,KAA8BK,MAD9B,IAEA,KAAKoB,KAAL,CAAWxB,aAAX,KAA6BY,CAF7B,IAGA,KAAKY,KAAL,CAAWvB,aAAX,KAA6BY,CAJ/B,EAKE;AACA;AACD;;AAED,iBAAKY,QAAL,CAAc;AACZ3B,cAAAA,aAAa,EAAEK,KADH;AAEZJ,cAAAA,cAAc,EAAEK,MAFJ;AAGZJ,cAAAA,aAAa,EAAEY,CAHH;AAIZX,cAAAA,aAAa,EAAEY;AAJH,aAAd;AAMD,WAxBH;AA0BD,SAlCS,CAAV;AAmCD,OAvCoB,CAArB;AAwCD,KA9SgD;;AAAA,+DAyTb,CAClCa,CADkC,EAElCC,YAFkC,KAG/B;AACH,UAAI,KAAKjB,KAAL,CAAWkB,4BAAf,EAA6C;AAC3C,aAAKlB,KAAL,CAAWkB,4BAAX,CACEF,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF,EAIE,KAJF;AAMD,OARE,CAUH;AACA;AACA;AACA;;;AACA,aAAO,IAAP;AACD,KA3UgD;;AAAA,sDAsV7C,CAACH,CAAD,EAAIC,YAAJ,KAAqB;AAAA;;AACvB,UAAI,KAAKjB,KAAL,CAAWoB,WAAf,EAA4B;AAC1B,aAAKC,gBAAL,GAAwBX,UAAU,CAAC,MAAM;AAAA;;AACvC,wDAAKV,KAAL,EAAWoB,WAAX,mGACEJ,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF;AAKA,eAAKE,gBAAL,GAAwB,IAAxB;AACD,SAPiC,EAO/B,KAAKrB,KAAL,CAAWsB,iBAPoB,CAAlC;AAQD;;AAED,oDAAKtB,KAAL,EAAWuB,mBAAX,mGACEP,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF;AAMA,WAAKK,OAAL,CAAaC,aAAb;AACA,WAAKC,QAAL,CAAcD,aAAd;AACA,WAAK7B,cAAL,GAAsB,IAAtB;AAEA,WAAK+B,QAAL;AACD,KA7WgD;;AAAA,oDAyX7C,CAACX,CAAD,EAAIC,YAAJ,KAAqB;AAAA;;AACvB,UAAI,CAAC,KAAKW,WAAV,EAAuB;AACrB,aAAKC,oBAAL,CAA0Bb,CAA1B;AACD;;AAED,WAAKD,QAAL,CAAc;AAAEe,QAAAA,WAAW,EAAE;AAAf,OAAd;AAEA,WAAKC,yBAAL,GAAiC,IAAjC;AAEA,YAAMC,eAAe,GACnB,KAAKhC,KAAL,CAAWgC,eAAX,IACC,KAAKhC,KAAL,CAAWiC,UAAX,IACC,KAAKL,WAAL,KAAqB,OADtB,IAEC,KAAK5B,KAAL,CAAWkC,uBAFZ,IAGC,KAAKC,SAAL,KAAmB,KAAKnC,KAAL,CAAWoC,WALlC,CATuB,CAgBvB;AACA;;AACA,UAAI,CAACJ,eAAL,EAAsB;AACpB/C,QAAAA,uBAAuB,CAAC,KAAKuC,OAAN,EAAe;AACpCtB,UAAAA,CAAC,EAAEe,YAAY,CAACoB,EAAb,GAAkB,KAAKF,SADU;AAEpChC,UAAAA,CAAC,EAAEc,YAAY,CAACqB,EAAb,GAAkB,KAAKH;AAFU,SAAf,CAAvB,CAGGI,KAHH;AAID;;AAED,UAAI,KAAKlB,gBAAT,EAA2B;AACzBmB,QAAAA,YAAY,CAAC,KAAKnB,gBAAN,CAAZ;AACA,aAAKA,gBAAL,GAAwB,IAAxB;AACD;;AAED,qDAAKrB,KAAL,EAAWyC,iBAAX,qGACEzB,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF;;AAMA,UAAI,KAAKS,WAAL,KAAqB,OAAzB,EAAkC;AAAA;;AAChC,sDAAK5B,KAAL,EAAW0C,SAAX,mGACE1B,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF;AAKD,OAND,MAMO,IAAI,KAAKS,WAAL,KAAqB,OAAzB,EAAkC;AAAA;;AACvC,sDAAK5B,KAAL,EAAW2C,aAAX,mGACE3B,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF;AAKD;;AAED,UAAI,KAAKnB,KAAL,CAAW4C,iBAAf,EAAkC;AAChC,aAAKC,gBAAL;AACD;;AAED,WAAKC,OAAL;AAEA,WAAKlB,WAAL,GAAmB,IAAnB;AACA,WAAKhC,cAAL,GAAsB,KAAtB;AACD,KAnbgD;;AAAA,qDA6bvB,CACxBoB,CADwB,EAExBC,YAFwB,KAGrB;AACH,UAAI,KAAKjB,KAAL,CAAW+C,kBAAf,EAAmC;AACjC,YACE,KAAK/C,KAAL,CAAW+C,kBAAX,CACE/B,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF,CADF,EAME;AACA,iBAAO,KAAP;AACD;AACF,OAXE,CAaH;AACA;;;AACA,UAAIF,YAAY,CAAC+B,mBAAb,IAAoC,CAAxC,EAA2C;AACzC,YAAI,CAAC,KAAKpD,cAAV,EAA0B;AACxB,eAAKqD,wBAAL,CAA8BjC,CAA9B,EAAiCC,YAAjC;AACD;AACF,OAJD,MAIO;AACL,YAAI,KAAKrB,cAAT,EAAyB;AACvB,eAAKsD,sBAAL,CAA4BlC,CAA5B,EAA+BC,YAA/B;AACD;;AACD,eAAO,IAAP;AACD;;AAED,UAAIA,YAAY,CAAC+B,mBAAb,KAAqC,CAAzC,EAA4C;AAC1C,YAAI,KAAK3B,gBAAT,EAA2B;AACzBmB,UAAAA,YAAY,CAAC,KAAKnB,gBAAN,CAAZ;AACA,eAAKA,gBAAL,GAAwB,IAAxB;AACD,SAJyC,CAM1C;;;AACA,YAAI,KAAKO,WAAL,KAAqB,OAAzB,EAAkC;AAChC,eAAKG,yBAAL,GAAiCtD,sBAAsB,CACrDuC,CADqD,EAErDC,YAFqD,CAAvD;AAIA,eAAKkC,wBAAL,GAAgCzE,wBAAwB,CACtDsC,CADsD,EAEtDC,YAFsD,CAAxD;AAID;;AACD,aAAKW,WAAL,GAAmB,OAAnB;;AACA,aAAKwB,eAAL,CAAqBpC,CAArB,EAAwBC,YAAxB;AACD,OAnBD,MAmBO,IAAIA,YAAY,CAAC+B,mBAAb,KAAqC,CAAzC,EAA4C;AACjD,YACE,KAAK3B,gBAAL,KACCgC,IAAI,CAACC,GAAL,CAASrC,YAAY,CAACsC,EAAtB,IAA4B,CAA5B,IAAiCF,IAAI,CAACC,GAAL,CAASrC,YAAY,CAACuC,EAAtB,IAA4B,CAD9D,CADF,EAGE;AACAhB,UAAAA,YAAY,CAAC,KAAKnB,gBAAN,CAAZ;AACA,eAAKA,gBAAL,GAAwB,IAAxB;AACD,SAPgD,CAQjD;;;AACA,YAAI,KAAKO,WAAL,KAAqB,OAAzB,EAAkC;AAChC,eAAKG,yBAAL,GAAiCtD,sBAAsB,CACrDuC,CADqD,EAErDC,YAFqD,CAAvD;AAID;;AAED,cAAM;AAAEsC,UAAAA,EAAF;AAAMC,UAAAA;AAAN,YAAavC,YAAnB;AACA,cAAMwC,cAAc,GAAGJ,IAAI,CAACC,GAAL,CAASC,EAAT,IAAe,CAAf,IAAoBF,IAAI,CAACC,GAAL,CAASE,EAAT,IAAe,CAA1D;;AACA,YAAIC,cAAJ,EAAoB;AAClB,eAAK7B,WAAL,GAAmB,OAAnB;;AACA,eAAK8B,eAAL,CAAqBzC,YAArB;AACD;AACF;AACF,KApgBgD;;AAAA,kDA4wBjBD,CAAD,IAA8B;AAC3D,YAAM2C,GAAG,GAAGC,IAAI,CAACD,GAAL,EAAZ;;AACA,UACE,KAAKE,iCAAL,IACA,KAAK7D,KAAL,CAAW8D,cADX,IAEAH,GAAG,GAAG,KAAKE,iCAAX,GAA+C,KAAK7D,KAAL,CAAW8D,cAH5D,EAIE;AACA,aAAKC,iBAAL,IACE,KAAKC,SAAL,CAAe,EACb,GAAG,KAAKD,iBADK;AAEbE,UAAAA,EAAE,EAAEN,GAAG,CAACO,QAAJ,EAFS;AAGbC,UAAAA,WAAW,EAAE;AAHA,SAAf,CADF;AAMA,aAAKC,kBAAL,IAA2B5B,YAAY,CAAC,KAAK4B,kBAAN,CAAvC;AACA,eAAO,KAAKP,iCAAZ;AACA,eAAO,KAAKO,kBAAZ;AACA,eAAO,KAAKL,iBAAZ;;AACA,aAAKM,gBAAL,CAAsBrD,CAAtB;AACD,OAhBD,MAgBO;AACL,aAAK6C,iCAAL,GAAyCF,GAAzC;AACA,aAAKI,iBAAL,GAAyB;AACvBE,UAAAA,EAAE,EAAEN,GAAG,CAACO,QAAJ,EADmB;AAEvBhE,UAAAA,CAAC,EAAEc,CAAC,CAACsD,WAAF,CAAcC,KAAd,GAAsB,KAAKzD,KAAL,CAAWxB,aAFb;AAGvBa,UAAAA,CAAC,EAAEa,CAAC,CAACsD,WAAF,CAAcE,KAAd,GAAsB,KAAK1D,KAAL,CAAWvB;AAHb,SAAzB;;AAKA,aAAKyE,SAAL,CAAe,KAAKD,iBAApB,EAPK,CASL;;;AACA/C,QAAAA,CAAC,CAACyD,OAAF;AACA,aAAKL,kBAAL,GAA0B1D,UAAU,CAAC,MAAM;AAAA;;AACzC,iBAAO,KAAKmD,iCAAZ;AACA,iBAAO,KAAKO,kBAAZ,CAFyC,CAIzC;;AACA,cAAI,KAAKpE,KAAL,CAAW4C,iBAAX,IAAgC,KAAKmB,iBAAzC,EAA4D;AAC1D,kBAAMW,IAAI,GACR,KAAK1E,KAAL,CAAW4C,iBAAX,CAA6B1C,CAA7B,GAAiC,KAAK6D,iBAAL,CAAuB7D,CAD1D;AAEA,kBAAMyE,IAAI,GACR,KAAK3E,KAAL,CAAW4C,iBAAX,CAA6BzC,CAA7B,GAAiC,KAAK4D,iBAAL,CAAuB5D,CAD1D;AAGAjC,YAAAA,QAAQ,CAAC0G,MAAT,CAAgB,KAAKpD,OAArB,EAA8B;AAC5BqD,cAAAA,OAAO,EAAE;AACP3E,gBAAAA,CAAC,EAAE,KAAK4E,OAAL,GAAeJ,IAAI,GAAG,KAAKvC,SADvB;AAEPhC,gBAAAA,CAAC,EAAE,KAAK4E,OAAL,GAAeJ,IAAI,GAAG,KAAKxC;AAFvB,eADmB;AAK5B6C,cAAAA,eAAe,EAAE,IALW;AAM5BC,cAAAA,QAAQ,EAAE;AANkB,aAA9B,EAOG1C,KAPH,CAOS,MAAM;AACb,mBAAKM,gBAAL;AACD,aATD;AAUD;;AAED,wDAAK7C,KAAL,EAAWkF,WAAX,mGAAyBlE,CAAzB,EAA4B,KAAKG,2BAAL,EAA5B;AACD,SAxBmC,EAwBjC,KAAKnB,KAAL,CAAW8D,cAxBsB,CAApC;AAyBD;AACF,KAn0BgD;;AAAA,6CAq0B/B,CAACvD,QAAD,EAAkB0E,QAAlB,KAAwC;AACxD,YAAM;AAAE7F,QAAAA,aAAF;AAAiBC,QAAAA;AAAjB,UAAoC,KAAKyB,KAA/C;AACA,YAAM;AAAE8B,QAAAA,iBAAF;AAAqBuC,QAAAA,YAArB;AAAmCC,QAAAA;AAAnC,UAAqD,KAAKpF,KAAhE;AAEA,UAAI,CAAC4C,iBAAL,EAAwB;AACxB,UAAI,CAACxD,aAAD,IAAkB,CAACC,cAAvB,EAAuC;AACvC,UAAI,CAAC8F,YAAD,IAAiB,CAACC,aAAtB,EAAqC,OANmB,CAQxD;;AACA,YAAMC,IAAI,GAAGzC,iBAAiB,CAAC1C,CAAlB,GAAsBd,aAAa,GAAG,CAAnD;AACA,YAAMkG,IAAI,GAAG1C,iBAAiB,CAACzC,CAAlB,GAAsBd,cAAc,GAAG,CAApD;AAEA,WAAKyF,OAAL,GAAeK,YAAY,GAAG,CAAf,GAAmB5E,QAAQ,CAACL,CAA5B,GAAgCmF,IAAI,GAAG,KAAKlD,SAA3D;AACA,WAAK4C,OAAL,GAAeK,aAAa,GAAG,CAAhB,GAAoB7E,QAAQ,CAACJ,CAA7B,GAAiCmF,IAAI,GAAG,KAAKnD,SAA5D;;AAEA,UAAI8C,QAAJ,EAAc;AACZ/G,QAAAA,QAAQ,CAAC0G,MAAT,CAAgB,KAAKpD,OAArB,EAA8B;AAC5BqD,UAAAA,OAAO,EAAE;AAAE3E,YAAAA,CAAC,EAAE,KAAK4E,OAAV;AAAmB3E,YAAAA,CAAC,EAAE,KAAK4E;AAA3B,WADmB;AAE5BC,UAAAA,eAAe,EAAE,IAFW;AAG5BC,UAAAA;AAH4B,SAA9B,EAIG1C,KAJH;AAKD,OAND,MAMO;AACL,aAAKf,OAAL,CAAa+D,QAAb,CAAsB;AAAErF,UAAAA,CAAC,EAAE,KAAK4E,OAAV;AAAmB3E,UAAAA,CAAC,EAAE,KAAK4E;AAA3B,SAAtB;AACD;AACF,KA71BgD;;AAAA,gDA+1BpB,MAAM;AACjC,UAAI,CAAC,KAAK/E,KAAL,CAAW4C,iBAAhB,EAAmC;AACnC,UAAI,CAAC,KAAK5C,KAAL,CAAWmF,YAAZ,IAA4B,CAAC,KAAKnF,KAAL,CAAWoF,aAA5C,EAA2D;AAE3D,aAAOvG,+BAA+B,CAAC;AACrC2G,QAAAA,gBAAgB,EAAE;AAChBtF,UAAAA,CAAC,EAAE,KAAKF,KAAL,CAAW4C,iBAAX,CAA6B1C,CADhB;AAEhBC,UAAAA,CAAC,EAAE,KAAKH,KAAL,CAAW4C,iBAAX,CAA6BzC;AAFhB,SADmB;AAKrCsF,QAAAA,SAAS,EAAE;AACT/F,UAAAA,MAAM,EAAE,KAAKM,KAAL,CAAWoF,aADV;AAET3F,UAAAA,KAAK,EAAE,KAAKO,KAAL,CAAWmF;AAFT,SAL0B;AASrCO,QAAAA,aAAa,EAAE,EACb,GAAG,KAAKvE,2BAAL,EADU;AAEb2D,UAAAA,OAAO,EAAE,KAAKA,OAFD;AAGbC,UAAAA,OAAO,EAAE,KAAKA,OAHD;AAIb5C,UAAAA,SAAS,EAAE,KAAKA;AAJH;AATsB,OAAD,CAAtC;AAgBD,KAn3BgD;;AAAA,8CAq3BtB,MAAM;AAAA;;AAC/B,YAAM5B,QAAQ,GAAG,KAAKoF,kBAAL,EAAjB;;AACA,UAAI,CAACpF,QAAL,EAAe;AACf,qDAAKP,KAAL,EAAWQ,yBAAX,qGAAuCD,QAAvC;AACD,KAz3BgD;;AAK/C,SAAKO,KAAL,GAAa,EAAE,GAAG3B;AAAL,KAAb;AAEA,SAAKyG,eAAL,GAAuBxH,YAAY,CAACyH,MAAb,CAAoB;AACzC3E,MAAAA,4BAA4B,EAAE,KAAK4E,iCADM;AAEzCvE,MAAAA,mBAAmB,EAAE,KAAK0B,wBAFe;AAGzCF,MAAAA,kBAAkB,EAAE,KAAKgD,uBAHgB;AAIzCC,MAAAA,qBAAqB,EAAE,KAAK9C,sBAJa;AAKzC+C,MAAAA,uBAAuB,EAAE,CAACC,GAAD,EAAMjF,YAAN,KAAuB;AAAA;;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA,aAAKiC,sBAAL,CAA4BgD,GAA5B,EAAiCjF,YAAjC;;AACA,uDAAKjB,KAAL,EAAWiG,uBAAX,qGACEC,GADF,EAEEjF,YAFF,EAGE,KAAKE,2BAAL,EAHF;AAKD,OAlBwC;AAmBzCgF,MAAAA,gCAAgC,EAAE,CAACD,GAAD,EAAMjF,YAAN;AAAA;;AAAA,eAChC,CAAC,4BAAC,sBAAKjB,KAAL,EAAWmG,gCAAZ,mDAAC,2CACAD,GADA,EAEAjF,YAFA,EAGA,KAAKE,2BAAL,EAHA,CAAD,CAD+B;AAAA,OAnBO;AAyBzC;AACAiF,MAAAA,4BAA4B,EAAE,CAACF,GAAD,EAAMjF,YAAN;AAAA;;AAAA,kEAC5B,sBAAKjB,KAAL,EAAWoG,4BADiB,2DAC5B,2CACEF,GADF,EAEEjF,YAFF,EAGE,KAAKE,2BAAL,EAHF,CAD4B,yEAKvB,IALuB;AAAA,OA1BW;AAgCzCkF,MAAAA,mCAAmC,EAAE,CAACH,GAAD,EAAMjF,YAAN;AAAA;;AAAA,eACnC,CAAC,2BAAC,sBAAKjB,KAAL,EAAWqG,mCAAZ,kDAAC,0CAAiDH,GAAjD,EAAsDjF,YAAtD,CAAD,CADkC;AAAA,OAhCI;AAkCzCqF,MAAAA,kCAAkC,EAAE,CAACJ,GAAD,EAAMjF,YAAN;AAAA;;AAAA,eAClC,CAAC,2BAAC,sBAAKjB,KAAL,EAAWsG,kCAAZ,kDAAC,0CAAgDJ,GAAhD,EAAqDjF,YAArD,CAAD,CADiC;AAAA;AAlCK,KAApB,CAAvB;AAsCA,SAAKN,qBAAL,gBAA6B1C,SAAS,EAAtC;AAEA,QAAI,KAAK+B,KAAL,CAAWuG,iBAAf,EACE,KAAK7E,QAAL,GAAgB,KAAK1B,KAAL,CAAWuG,iBAA3B;AACF,QAAI,KAAKvG,KAAL,CAAWwG,kBAAf,EACE,KAAKhF,OAAL,GAAe,KAAKxB,KAAL,CAAWwG,kBAA1B;AAEF,QAAI,KAAKxG,KAAL,CAAWoC,WAAf,EAA4B,KAAKD,SAAL,GAAiB,KAAKnC,KAAL,CAAWoC,WAA5B;AAC5B,QAAI,KAAKpC,KAAL,CAAWyG,cAAX,IAA6B,IAAjC,EACE,KAAK3B,OAAL,GAAe,KAAK9E,KAAL,CAAWyG,cAA1B;AACF,QAAI,KAAKzG,KAAL,CAAW0G,cAAX,IAA6B,IAAjC,EACE,KAAK3B,OAAL,GAAe,KAAK/E,KAAL,CAAW0G,cAA1B;AAEF,SAAKlF,OAAL,CAAa+D,QAAb,CAAsB;AAAErF,MAAAA,CAAC,EAAE,KAAK4E,OAAV;AAAmB3E,MAAAA,CAAC,EAAE,KAAK4E;AAA3B,KAAtB;AACA,SAAKrD,QAAL,CAAc6D,QAAd,CAAuB,KAAKpD,SAA5B;AACA,SAAKX,OAAL,CAAamF,WAAb,CAAyB,CAAC;AAAEzG,MAAAA,CAAF;AAAKC,MAAAA;AAAL,KAAD,KAAc;AACrC,WAAK2E,OAAL,GAAe5E,CAAf;AACA,WAAK6E,OAAL,GAAe5E,CAAf;AACD,KAHD;AAIA,SAAKuB,QAAL,CAAciF,WAAd,CAA0B,CAAC;AAAEtG,MAAAA;AAAF,KAAD,KAAe;AACvC,WAAK8B,SAAL,GAAiB9B,KAAjB;AACD,KAFD;AAIA,SAAK8C,wBAAL,GAAgC,GAAhC;AAEA,SAAKvB,WAAL,GAAmB,IAAnB;AACD;;AAEOD,EAAAA,QAAQ,GAAG;AACjB,QAAI,CAAC,KAAK3B,KAAL,CAAW4G,UAAhB,EAA4B;AAC5B1I,IAAAA,QAAQ,CAAC0G,MAAT,CAAgB,KAAKiC,OAArB,EAA8B;AAC5BhC,MAAAA,OAAO,EAAE;AAAE3E,QAAAA,CAAC,EAAE,CAAL;AAAQC,QAAAA,CAAC,EAAE,CAAC;AAAZ,OADmB;AAE5B6E,MAAAA,eAAe,EAAE,IAFW;AAG5B8B,MAAAA,MAAM,EAAE3I,MAAM,CAAC4I,GAAP,CAAW5I,MAAM,CAAC6I,IAAlB,CAHoB;AAI5B/B,MAAAA,QAAQ,EAAE;AAJkB,KAA9B,EAKG1C,KALH;AAMD;;AAEOO,EAAAA,OAAO,GAAG;AAChB,QAAI,CAAC,KAAK9C,KAAL,CAAW4G,UAAhB,EAA4B;AAC5B1I,IAAAA,QAAQ,CAAC0G,MAAT,CAAgB,KAAKiC,OAArB,EAA8B;AAC5BhC,MAAAA,OAAO,EAAE;AAAE3E,QAAAA,CAAC,EAAE,CAAL;AAAQC,QAAAA,CAAC,EAAE;AAAX,OADmB;AAE5B6E,MAAAA,eAAe,EAAE,IAFW;AAG5B8B,MAAAA,MAAM,EAAE3I,MAAM,CAAC4I,GAAP,CAAW5I,MAAM,CAAC6I,IAAlB,CAHoB;AAI5B/B,MAAAA,QAAQ,EAAE;AAJkB,KAA9B,EAKG1C,KALH;AAMD;;AAEkB,MAAPuC,OAAO,CAAC5E,CAAD,EAAY;AAC7B,SAAK+G,WAAL,CAAiB,GAAjB,EAAsB/G,CAAtB;AACD;;AAEkB,MAAP6E,OAAO,CAAC5E,CAAD,EAAY;AAC7B,SAAK8G,WAAL,CAAiB,GAAjB,EAAsB9G,CAAtB;AACD;;AAEkB,MAAP2E,OAAO,GAAG;AACpB,WAAO,KAAKoC,WAAL,CAAiB,GAAjB,CAAP;AACD;;AAEkB,MAAPnC,OAAO,GAAG;AACpB,WAAO,KAAKmC,WAAL,CAAiB,GAAjB,CAAP;AACD;;AAEOD,EAAAA,WAAW,CAACE,IAAD,EAAkBC,MAAlB,EAAkC;AACnD,UAAMC,WAAW,GAAG,KAAKC,SAAL,CAAeH,IAAf,CAApB;;AAEA,QAAI,KAAKnH,KAAL,CAAWuH,aAAf,EAA8B;AAC5B,YAAMC,aAAa,GACjBL,IAAI,KAAK,GAAT,GAAe,KAAKrG,KAAL,CAAW1B,aAA1B,GAA0C,KAAK0B,KAAL,CAAWzB,cADvD;AAEA,YAAMoI,WAAW,GACfN,IAAI,KAAK,GAAT,GACI,KAAKnH,KAAL,CAAWmF,YAAX,IAA2B,KAAKrE,KAAL,CAAW1B,aAD1C,GAEI,KAAKY,KAAL,CAAWoF,aAAX,IAA4B,KAAKtE,KAAL,CAAWzB,cAH7C;AAKA,YAAMqI,WAAW,GACfD,WAAW,IAAID,aAAf,IAAgC,KAAKxH,KAAL,CAAW2H,kBAAX,IAAiC,IAAjE,GACI/I,0BAA0B,CACxBwI,MADwB,EAExBI,aAFwB,EAGxBC,WAHwB,EAIxB,KAAKtF,SAJmB,EAKxB,KAAKnC,KAAL,CAAW2H,kBALa,CAD9B,GAQIP,MATN;;AAWA,UAAI,CAAC,KAAKxF,WAAN,IAAqB,CAACyF,WAAW,CAAC/G,2BAAtC,EAAmE;AACjE,cAAMsH,iBAAiB,GACrBF,WAAW,KAAKN,MAAhB,IACAM,WAAW,CAACG,OAAZ,CAAoB,CAApB,MAA2BT,MAAM,CAACS,OAAP,CAAe,CAAf,CAF7B;;AAGA,YAAID,iBAAJ,EAAuB;AACrBP,UAAAA,WAAW,CAAC/G,2BAAZ,GAA0C,IAA1C;AACAtB,UAAAA,sBAAsB,CAAC,KAAKwC,OAAL,CAAa2F,IAAb,CAAD,EAAqBO,WAArB,CAAtB,CAAwDnF,KAAxD,CAA8D,MAAM;AAClE8E,YAAAA,WAAW,CAAC/G,2BAAZ,GAA0C,KAA1C;AACD,WAFD;AAGA;AACD;AACF;AACF;;AAED+G,IAAAA,WAAW,CAAChH,KAAZ,GAAoB+G,MAApB;AACD;;AAEOF,EAAAA,WAAW,CAACC,IAAD,EAAkB;AACnC,WAAO,KAAKG,SAAL,CAAeH,IAAf,EAAqB9G,KAA5B;AACD;;AAEDyH,EAAAA,kBAAkB,CAChBC,SADgB,EAEhBC,SAFgB,EAGhB;AAAA;;AACA,UAAM;AAAEC,MAAAA,WAAF;AAAe7F,MAAAA;AAAf,QAA+B,KAAKpC,KAA1C;;AACA,QAAI+H,SAAS,CAACE,WAAV,IAAyB,CAACA,WAA1B,IAAyC7F,WAA7C,EAA0D;AACxD,WAAKD,SAAL,GAAiBC,WAAjB;AACA,WAAKV,QAAL,CAAc6D,QAAd,CAAuB,KAAKpD,SAA5B;AACD;;AACD,QACE,CAAC,KAAK+F,gCAAN,IACA,KAAKC,kBAAL,GAA0BC,UAF5B,EAGE;AACA,WAAK5G,OAAL,CAAamF,WAAb,CAAyB,MAAM,KAAKwB,kBAAL,EAA/B;AACA,WAAKzG,QAAL,CAAciF,WAAd,CAA0B,MAAM,KAAKwB,kBAAL,EAAhC;AACA,WAAKD,gCAAL,GAAwC,IAAxC;AACD;;AAED,UAAMG,SAAS,GAAG,KAAKvH,KAAvB;AACA,UAAMwH,2BAA2B,GAC/BD,SAAS,CAAChJ,cAAV,KAA6B2I,SAAS,CAAC3I,cAAvC,IACAgJ,SAAS,CAACjJ,aAAV,KAA4B4I,SAAS,CAAC5I,aADtC,IAEAiJ,SAAS,CAAC/I,aAAV,KAA4B0I,SAAS,CAAC1I,aAFtC,IAGA+I,SAAS,CAAC9I,aAAV,KAA4ByI,SAAS,CAACzI,aAJxC;AAMA,UAAMgJ,wBAAwB,GAC5B,0BAAAR,SAAS,CAACnF,iBAAV,gFAA6B1C,CAA7B,gCAAmC,KAAKF,KAAL,CAAW4C,iBAA9C,0DAAmC,sBAA8B1C,CAAjE,KACA,2BAAA6H,SAAS,CAACnF,iBAAV,kFAA6BzC,CAA7B,iCAAmC,KAAKH,KAAL,CAAW4C,iBAA9C,2DAAmC,uBAA8BzC,CAAjE,CAFF;;AAIA,QACE,KAAK+H,gCAAL,KACCI,2BAA2B,IAAIC,wBADhC,CADF,EAGE;AACA,WAAKJ,kBAAL;AACD;AACF;;AAEDK,EAAAA,iBAAiB,GAAG;AAClB,SAAKC,mCAAL,GADkB,CAElB;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,SAAKC,0BAAL,GAAkCC,WAAW,CAC3C,KAAKF,mCADsC,EAE3C,GAF2C,CAA7C;AAID;;AAEDG,EAAAA,oBAAoB,GAAG;AACrB,SAAKF,0BAAL,IACEG,aAAa,CAAC,KAAKH,0BAAN,CADf;AAED;;AAOD;AACF;AACA;AACA;AACEP,EAAAA,kBAAkB,GAAG;AAAA;;AACnB,UAAMW,iBAAiB,GAAG,KAAK3H,2BAAL,EAA1B;;AACA,UAAMZ,QAAQ,GAAG,KAAKoF,kBAAL,EAAjB;;AAEA,QAAI,CAACmD,iBAAiB,CAAC1J,aAAnB,IAAoC,CAAC0J,iBAAiB,CAACzJ,cAA3D,EACE,OAAO;AAAE+I,MAAAA,UAAU,EAAE;AAAd,KAAP;AAEF,mDAAKpI,KAAL,EAAW+I,WAAX,oGAAyBD,iBAAzB;;AAEA,QAAIvI,QAAJ,EAAc;AAAA;;AACZ,sDAAKP,KAAL,EAAWgJ,uBAAX,sGAAqCzI,QAArC;AACA,WAAK0I,kCAAL,CAAwC1I,QAAxC;AACD;;AAED,WAAO;AAAE6H,MAAAA,UAAU,EAAE;AAAd,KAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;;;AACEjH,EAAAA,2BAA2B,CAAC+H,YAAY,GAAG,EAAhB,EAAuC;AAChE,WAAO;AACL/G,MAAAA,SAAS,EAAE,KAAKA,SADX;AAEL2C,MAAAA,OAAO,EAAE,KAAKA,OAFT;AAGLC,MAAAA,OAAO,EAAE,KAAKA,OAHT;AAIL1F,MAAAA,cAAc,EAAE,KAAKyB,KAAL,CAAWzB,cAJtB;AAKLD,MAAAA,aAAa,EAAE,KAAK0B,KAAL,CAAW1B,aALrB;AAMLE,MAAAA,aAAa,EAAE,KAAKwB,KAAL,CAAWxB,aANrB;AAOLC,MAAAA,aAAa,EAAE,KAAKuB,KAAL,CAAWvB,aAPrB;AAQL,SAAG2J;AARE,KAAP;AAUD;AAED;AACF;AACA;AACA;AACA;AACA;;;AAmQE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACE9F,EAAAA,eAAe,CACbpC,CADa,EAEbC,YAFa,EAGb;AAAA;;AACA,QAAI,CAAC,KAAKjB,KAAL,CAAWiI,WAAhB,EAA6B;AAE7B,UAAM;AACJkB,MAAAA,OADI;AAEJC,MAAAA,OAFI;AAGJC,MAAAA,wBAHI;AAIJC,MAAAA;AAJI,QAKF,KAAKtJ,KALT;AAOA,UAAMuJ,QAAQ,GAAG7K,wBAAwB,CAACsC,CAAD,EAAIC,YAAJ,CAAzC;;AAEA,QACE,KAAKjB,KAAL,CAAWwJ,YAAX,IACA,KAAKxJ,KAAL,CAAWwJ,YAAX,CACExI,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF,CAFF,EAOE;AACA;AACD;;AAED,QAAI,CAACoI,QAAL,EAAe;AACf,QAAI,CAAC,KAAKpG,wBAAV,EAAoC,OAxBpC,CA0BA;;AACA,UAAMsG,8BAA8B,GAClCF,QAAQ,GAAG,KAAKpG,wBADlB;AAEA,SAAKA,wBAAL,GAAgCoG,QAAhC;AAEA,UAAMG,sBAAsB,GAC1BD,8BAA8B,GAAG,CAAjC,GACIH,yBADJ,GAEID,wBAHN;AAKA,QAAIK,sBAAsB,IAAI,IAA9B,EAAoC;AACpC,UAAMC,WAAW,GAAGF,8BAA8B,GAAG,CAArD,CArCA,CAsCA;AACA;;AACA,UAAMG,gCAAgC,GACpCD,WAAW,IAAI,IAAKD,sBAAsB,GAAG,CAA1B,GAA+B,GAAvC,CADb;AAGA,QAAIG,YAAY,GAAG,KAAK1H,SAAL,IAAkB,IAAIyH,gCAAtB,CAAnB,CA3CA,CA6CA;;AACA,QAAIT,OAAO,IAAI,IAAX,IAAmBU,YAAY,GAAGV,OAAtC,EAA+C;AAC7CU,MAAAA,YAAY,GAAGV,OAAf;AACD;;AAED,QAAIC,OAAO,IAAI,IAAX,IAAmBS,YAAY,GAAGT,OAAtC,EAA+C;AAC7CS,MAAAA,YAAY,GAAGT,OAAf;AACD;;AAED,UAAMU,kBAAkB,GAAGrL,sBAAsB,CAACuC,CAAD,EAAIC,YAAJ,CAAjD;AAEA,QAAI,CAAC6I,kBAAL,EAAyB;AAEzB,QAAIC,UAAU,GAAG;AACf7J,MAAAA,CAAC,EAAE4J,kBAAkB,CAAC5J,CAAnB,GAAuB,KAAKY,KAAL,CAAWxB,aADtB;AAEfa,MAAAA,CAAC,EAAE2J,kBAAkB,CAAC3J,CAAnB,GAAuB,KAAKW,KAAL,CAAWvB;AAFtB,KAAjB;;AAKA,QAAI,KAAKS,KAAL,CAAW4C,iBAAf,EAAkC;AAChC;AACA;AACAmH,MAAAA,UAAU,GAAG;AACX7J,QAAAA,CAAC,EAAE,KAAKF,KAAL,CAAW4C,iBAAX,CAA6B1C,CADrB;AAEXC,QAAAA,CAAC,EAAE,KAAKH,KAAL,CAAW4C,iBAAX,CAA6BzC;AAFrB,OAAb;AAID,KAtED,CAwEA;;;AACA,SAAKH,KAAL,CAAWgK,KAAX,IAAoB,KAAKC,oBAAL,CAA0BjJ,CAA1B,EAA6B+I,UAA7B,CAApB;AAEA,UAAM;AAAE1K,MAAAA,cAAF;AAAkBD,MAAAA;AAAlB,QAAoC,KAAK0B,KAA/C;AAEA,UAAMoJ,UAAU,GAAG,KAAKpF,OAAxB;AACA,UAAMqF,UAAU,GAAG,KAAKpF,OAAxB;AACA,UAAMqF,QAAQ,GAAG,KAAKjI,SAAtB;AACA,UAAMkI,QAAQ,GAAGR,YAAjB;AAEA,QAAI,CAACxK,cAAD,IAAmB,CAACD,aAAxB,EAAuC;AAEvC,QAAI2F,OAAO,GAAGpG,mCAAmC,CAC/CwL,UAD+C,EAE/C9K,cAF+C,EAG/C+K,QAH+C,EAI/CC,QAJ+C,EAK/CN,UAAU,CAAC5J,CALoC,CAAjD;AAOA,QAAI2E,OAAO,GAAGnG,mCAAmC,CAC/CuL,UAD+C,EAE/C9K,aAF+C,EAG/CgL,QAH+C,EAI/CC,QAJ+C,EAK/CN,UAAU,CAAC7J,CALoC,CAAjD;;AAQA,UAAMoK,WAAW,GACf,KAAKC,qCAAL,CAA2CT,kBAA3C,CADF;;AAEA,QAAIQ,WAAJ,EAAiB;AACfxF,MAAAA,OAAO,IAAIwF,WAAW,CAACpK,CAAvB;AACA6E,MAAAA,OAAO,IAAIuF,WAAW,CAACnK,CAAvB;AACD;;AAED,SAAK2E,OAAL,GAAeA,OAAf;AACA,SAAKC,OAAL,GAAeA,OAAf;AACA,SAAK5C,SAAL,GAAiBkI,QAAjB;AAEA,SAAK7I,OAAL,CAAa+D,QAAb,CAAsB;AAAErF,MAAAA,CAAC,EAAE,KAAK4E,OAAV;AAAmB3E,MAAAA,CAAC,EAAE,KAAK4E;AAA3B,KAAtB;AACA,SAAKrD,QAAL,CAAc6D,QAAd,CAAuB,KAAKpD,SAA5B;AAEA,mDAAKnC,KAAL,EAAWwK,WAAX,oGACExJ,CADF,EAEEC,YAFF,EAGE,KAAKE,2BAAL,EAHF;AAKD;AAED;AACF;AACA;AACA;AACA;AACA;;;AACE8I,EAAAA,oBAAoB,CAClBQ,qBADkB,EAElBV,UAFkB,EAGlB,GAAGW,MAHe,EAIlB;AACA,UAAM;AAAEC,MAAAA;AAAF,QAAcF,qBAAqB,CAACnG,WAA1C;AACA,UAAM;AAAE/E,MAAAA,aAAF;AAAiBD,MAAAA;AAAjB,QAAmC,KAAKwB,KAA9C;AAEA,SAAKC,QAAL,CAAc;AACZe,MAAAA,WAAW,EAAE,CACX;AACE5B,QAAAA,CAAC,EAAEyK,OAAO,CAAC,CAAD,CAAP,CAAWpG,KAAX,GAAmBjF,aADxB;AAEEa,QAAAA,CAAC,EAAEwK,OAAO,CAAC,CAAD,CAAP,CAAWnG,KAAX,GAAmBjF;AAFxB,OADW,EAKX;AACEW,QAAAA,CAAC,EAAEyK,OAAO,CAAC,CAAD,CAAP,CAAWpG,KAAX,GAAmBjF,aADxB;AAEEa,QAAAA,CAAC,EAAEwK,OAAO,CAAC,CAAD,CAAP,CAAWnG,KAAX,GAAmBjF;AAFxB,OALW,EASXwK,UATW,EAUX,GAAGW,MAVQ;AADD,KAAd;AAcD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;;;AACEH,EAAAA,qCAAqC,CAACT,kBAAD,EAA4B;AAC/D,UAAM;AAAEc,MAAAA;AAAF,QAA0B,KAAK5K,KAArC;AAEA,QAAI6K,KAAK,GAAG,IAAZ;;AAEA,QAAI,KAAK9I,yBAAL,IAAkC6I,mBAAtC,EAA2D;AACzD,YAAMrH,EAAE,GAAGuG,kBAAkB,CAAC5J,CAAnB,GAAuB,KAAK6B,yBAAL,CAA+B7B,CAAjE;AACA,YAAMsD,EAAE,GAAGsG,kBAAkB,CAAC3J,CAAnB,GAAuB,KAAK4B,yBAAL,CAA+B5B,CAAjE;AAEA,YAAM2K,MAAM,GAAGvH,EAAE,GAAG,KAAKpB,SAAV,GAAsByI,mBAArC;AACA,YAAMG,MAAM,GAAGvH,EAAE,GAAG,KAAKrB,SAAV,GAAsByI,mBAArC;AAEAC,MAAAA,KAAK,GAAG;AACN3K,QAAAA,CAAC,EAAE4K,MADG;AAEN3K,QAAAA,CAAC,EAAE4K;AAFG,OAAR;AAID;;AAED,SAAKhJ,yBAAL,GAAiC+H,kBAAjC;AAEA,WAAOe,KAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;;;AACEnH,EAAAA,eAAe,CAACzC,YAAD,EAAyC;AACtD;AACA,QACE,CAAC,KAAKjB,KAAL,CAAWiC,UAAZ,IACC,KAAKjC,KAAL,CAAWkC,uBAAX,IACC,KAAKC,SAAL,KAAmB,KAAKnC,KAAL,CAAWoC,WAHlC,EAIE;AACA;AACD;;AACD,UAAMyI,KAAK,GAAG,KAAKN,qCAAL,CAA2C;AACvDrK,MAAAA,CAAC,EAAEe,YAAY,CAAC+J,KADuC;AAEvD7K,MAAAA,CAAC,EAAEc,YAAY,CAACgK;AAFuC,KAA3C,CAAd;;AAIA,QAAI,CAACJ,KAAL,EAAY;AAEZ,UAAM/F,OAAO,GAAG,KAAKA,OAAL,GAAe+F,KAAK,CAAC3K,CAArC;AACA,UAAM6E,OAAO,GAAG,KAAKA,OAAL,GAAe8F,KAAK,CAAC1K,CAArC;;AAEA,QACE,KAAKH,KAAL,CAAWgK,KAAX,IACA,KAAKlJ,KAAL,CAAWxB,aADX,IAEA,KAAKwB,KAAL,CAAWvB,aAHb,EAIE;AACA,YAAMW,CAAC,GAAGe,YAAY,CAAC+J,KAAb,GAAqB,KAAKlK,KAAL,CAAWxB,aAA1C;AACA,YAAMa,CAAC,GAAGc,YAAY,CAACgK,KAAb,GAAqB,KAAKnK,KAAL,CAAWvB,aAA1C;AACA,WAAKwB,QAAL,CAAc;AAAEe,QAAAA,WAAW,EAAE,CAAC;AAAE5B,UAAAA,CAAF;AAAKC,UAAAA;AAAL,SAAD;AAAf,OAAd;AACD;;AAED,SAAK+K,qBAAL,CAA2BpG,OAA3B,EAAoCC,OAApC;;AAEA,SAAKpD,QAAL;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;;;AACEuJ,EAAAA,qBAAqB,CAACC,UAAD,EAAqBC,UAArB,EAAyC;AAC5D,UAAM;AAAEC,MAAAA,gBAAF;AAAoBC,MAAAA;AAApB,QAAwC,KAAKtL,KAAnD;;AAEA,QAAIqL,gBAAJ,aAAIA,gBAAJ,eAAIA,gBAAgB,CAAG,IAAH,EAAS,IAAT,EAAe,KAAKlK,2BAAL,EAAf,CAApB,EAAwE;AACtE;AACD;;AAED,SAAK2D,OAAL,GAAeqG,UAAf;AACA,SAAKpG,OAAL,GAAeqG,UAAf;AAEA,SAAK5J,OAAL,CAAa+D,QAAb,CAAsB;AAAErF,MAAAA,CAAC,EAAE,KAAK4E,OAAV;AAAmB3E,MAAAA,CAAC,EAAE,KAAK4E;AAA3B,KAAtB;AACA,SAAKrD,QAAL,CAAc6D,QAAd,CAAuB,KAAKpD,SAA5B;AAEAmJ,IAAAA,eAAe,SAAf,IAAAA,eAAe,WAAf,YAAAA,eAAe,CAAG,IAAH,EAAS,IAAT,EAAe,KAAKnK,2BAAL,EAAf,CAAf;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;;;AAgHU6C,EAAAA,SAAS,CAACuH,KAAD,EAAoB;AACnC,SAAKZ,OAAL,CAAaa,IAAb,CAAkBD,KAAlB;AACA,SAAKxK,QAAL,CAAc;AAAE4J,MAAAA,OAAO,EAAE,CAAC,GAAG,KAAKA,OAAT;AAAX,KAAd;AACD;;AAEOc,EAAAA,YAAY,CAACF,KAAD,EAAoB;AACtC,SAAKZ,OAAL,CAAae,MAAb,CAAoB,KAAKf,OAAL,CAAagB,OAAb,CAAqBJ,KAArB,CAApB,EAAiD,CAAjD;AACA,SAAKxK,QAAL,CAAc;AAAE4J,MAAAA,OAAO,EAAE,CAAC,GAAG,KAAKA,OAAT;AAAX,KAAd;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;;;AACEtG,EAAAA,gBAAgB,CAACrD,CAAD,EAA2B;AACzC,UAAM;AAAE4K,MAAAA,iBAAF;AAAqBC,MAAAA,gBAArB;AAAuCC,MAAAA;AAAvC,QACJ,KAAK9L,KADP;AAGA4L,IAAAA,iBAAiB,SAAjB,IAAAA,iBAAiB,WAAjB,YAAAA,iBAAiB,CAAG5K,CAAH,EAAM,KAAKG,2BAAL,EAAN,CAAjB;;AAEA,UAAM4K,YAAY,GAAG,KAAKC,gBAAL,EAArB;;AACA,QAAID,YAAY,IAAI,IAApB,EAA0B;AAE1B,UAAM;AAAEzM,MAAAA,aAAF;AAAiBC,MAAAA;AAAjB,QAAmC,KAAKuB,KAA9C,CATyC,CAWzC;;AACA,UAAMmL,uBAAuB,GAAG;AAC9B/L,MAAAA,CAAC,EAAEc,CAAC,CAACsD,WAAF,CAAcC,KAAd,GAAsBjF,aADK;AAE9Ba,MAAAA,CAAC,EAAEa,CAAC,CAACsD,WAAF,CAAcE,KAAd,GAAsBjF;AAFK,KAAhC,CAZyC,CAiBzC;;AACA,QAAIuM,qBAAJ,EAA2B;AACzBG,MAAAA,uBAAuB,CAAC/L,CAAxB,GAA4B,CAA5B;AACA+L,MAAAA,uBAAuB,CAAC9L,CAAxB,GAA4B,CAA5B;AACD;;AAED,SAAK+L,MAAL,CAAYH,YAAZ,EAA0BE,uBAA1B;AAEAJ,IAAAA,gBAAgB,SAAhB,IAAAA,gBAAgB,WAAhB,YAAAA,gBAAgB,CACd7K,CADc,EAEd,KAAKG,2BAAL,CAAiC;AAAEgB,MAAAA,SAAS,EAAE4J;AAAb,KAAjC,CAFc,CAAhB;AAID;AAED;AACF;AACA;AACA;AACA;AACA;;;AACEC,EAAAA,gBAAgB,GAAG;AACjB,UAAM;AAAEG,MAAAA,QAAF;AAAYhD,MAAAA,OAAZ;AAAqB/G,MAAAA;AAArB,QAAqC,KAAKpC,KAAhD;AACA,UAAM;AAAEmC,MAAAA;AAAF,QAAgB,IAAtB;AAEA,QAAIgH,OAAO,IAAI,IAAf,EAAqB;;AAErB,QAAIhH,SAAS,CAAC0F,OAAV,CAAkB,CAAlB,MAAyBsB,OAAO,CAACtB,OAAR,CAAgB,CAAhB,CAA7B,EAAiD;AAC/C,aAAOzF,WAAP;AACD;;AAED,QAAI+J,QAAQ,IAAI,IAAhB,EAAsB;AAEtB,UAAMJ,YAAY,GAAG5J,SAAS,IAAI,IAAIgK,QAAR,CAA9B;;AACA,QAAIJ,YAAY,GAAG5C,OAAnB,EAA4B;AAC1B,aAAOA,OAAP;AACD;;AAED,WAAO4C,YAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACEG,EAAAA,MAAM,CAACrC,YAAD,EAAuBE,UAAvB,EAA2C;AAAA;;AAC/C,QAAI,CAAC,KAAK/J,KAAL,CAAWiI,WAAhB,EAA6B,OAAO,KAAP;AAC7B,QAAI,KAAKjI,KAAL,CAAWmJ,OAAX,IAAsBU,YAAY,GAAG,KAAK7J,KAAL,CAAWmJ,OAApD,EAA6D,OAAO,KAAP;AAC7D,QAAI,KAAKnJ,KAAL,CAAWoJ,OAAX,IAAsBS,YAAY,GAAG,KAAK7J,KAAL,CAAWoJ,OAApD,EAA6D,OAAO,KAAP;AAE7D,mDAAKpJ,KAAL,EAAWwJ,YAAX,oGAA0B,IAA1B,EAAgC,IAAhC,EAAsC,KAAKrI,2BAAL,EAAtC,EAL+C,CAO/C;;AACA,QAAIiL,UAAJ;;AACA,QAAIrC,UAAJ,EAAgB;AACd;AACA,UAAIsC,SAAS,GAAG,KAAKlK,SAArB,CAFc,CAGd;AACA;AACA;AACA;;AACAiK,MAAAA,UAAU,GAAG,KAAK1K,QAAL,CAAciF,WAAd,CAA0B,CAAC;AAAEtG,QAAAA,KAAK,EAAEgK;AAAT,OAAD,KAAyB;AAC9D,aAAK7I,OAAL,CAAa+D,QAAb,CAAsB;AACpBrF,UAAAA,CAAC,EAAEvB,mCAAmC,CACpC,KAAKmG,OAD+B,EAEpC,KAAKhE,KAAL,CAAW1B,aAFyB,EAGpCiN,SAHoC,EAIpChC,QAJoC,EAKpCN,UAAU,CAAC7J,CALyB,CADlB;AAQpBC,UAAAA,CAAC,EAAExB,mCAAmC,CACpC,KAAKoG,OAD+B,EAEpC,KAAKjE,KAAL,CAAWzB,cAFyB,EAGpCgN,SAHoC,EAIpChC,QAJoC,EAKpCN,UAAU,CAAC5J,CALyB;AARlB,SAAtB;AAgBAkM,QAAAA,SAAS,GAAGhC,QAAZ;AACD,OAlBY,CAAb;AAmBD,KAnC8C,CAqC/C;;;AACAnL,IAAAA,kBAAkB,CAAC,KAAKwC,QAAN,EAAgBmI,YAAhB,CAAlB,CAAgDtH,KAAhD,CAAsD,MAAM;AAC1D,UAAI,CAAC6J,UAAL,EAAiB;AACjB,WAAK1K,QAAL,CAAc4K,cAAd,CAA6BF,UAA7B;AACD,KAHD,EAtC+C,CA0C/C;;AAEA,oDAAKpM,KAAL,EAAWwK,WAAX,sGAAyB,IAAzB,EAA+B,IAA/B,EAAqC,KAAKrJ,2BAAL,EAArC;AACA,WAAO,IAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACEoL,EAAAA,MAAM,CAACC,eAAD,EAA0B;AAC9B;AACAA,IAAAA,eAAe,KAAfA,eAAe,GAAK,KAAKxM,KAAL,CAAWmM,QAAX,IAAuB,CAA5B,CAAf;AACA,WAAO,KAAKD,MAAL,CAAY,KAAK/J,SAAL,GAAiBqK,eAA7B,CAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACEC,EAAAA,MAAM,CAACtB,UAAD,EAAqBC,UAArB,EAAyC;AAC7C,UAAM;AAAEhM,MAAAA,aAAF;AAAiBC,MAAAA;AAAjB,QAAoC,KAAKyB,KAA/C;AACA,QAAI,CAAC1B,aAAD,IAAkB,CAACC,cAAvB,EAAuC;AAEvC,UAAMyF,OAAO,GAAG,CAACqG,UAAU,GAAG/L,aAAa,GAAG,CAA9B,IAAmC,KAAK+C,SAAxD;AACA,UAAM4C,OAAO,GAAG,CAACqG,UAAU,GAAG/L,cAAc,GAAG,CAA/B,IAAoC,KAAK8C,SAAzD;;AAEA,SAAK+I,qBAAL,CAA2B,CAACpG,OAA5B,EAAqC,CAACC,OAAtC;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACE2H,EAAAA,MAAM,CAACC,aAAD,EAAwBC,aAAxB,EAA+C;AACnD,UAAM9H,OAAO,GACX,CAAC,KAAKA,OAAL,GAAe,KAAK3C,SAApB,GAAgCwK,aAAjC,IAAkD,KAAKxK,SADzD;AAEA,UAAM4C,OAAO,GACX,CAAC,KAAKA,OAAL,GAAe,KAAK5C,SAApB,GAAgCyK,aAAjC,IAAkD,KAAKzK,SADzD;;AAGA,SAAK+I,qBAAL,CAA2BpG,OAA3B,EAAoCC,OAApC;AACD;;AAED8H,EAAAA,MAAM,GAAG;AACP,UAAM;AACJC,MAAAA,aADI;AAEJC,MAAAA,QAFI;AAGJC,MAAAA,0BAHI;AAIJlJ,MAAAA,cAJI;AAKJlB,MAAAA,iBALI;AAMJqK,MAAAA,oBANI;AAOJC,MAAAA,gBAPI;AAQJC,MAAAA;AARI,QASF,KAAKnN,KATT;AAUA,UAAM;AAAER,MAAAA,OAAF;AAAWmL,MAAAA,OAAX;AAAoB7I,MAAAA,WAAW,GAAG;AAAlC,QAAyC,KAAKhB,KAApD;AAEA,wBACE,oBAAC,IAAD;AACE,MAAA,KAAK,EAAEsM,MAAM,CAACC;AADhB,OAEM,KAAKzH,eAAL,CAAqB0H,WAF3B;AAGE,MAAA,GAAG,EAAE,KAAK3M,qBAHZ;AAIE,MAAA,QAAQ,EAAG4M,KAAD,IAAW;AAAA;;AACnB,sDAAKvN,KAAL,EAAWwN,QAAX,kGAAsBD,KAAtB;AACA,aAAK9E,mCAAL;AACD;AAPH,qBASE,oBAAC,QAAD,CAAU,IAAV;AACE,MAAA,KAAK,EAAE,CACL2E,MAAM,CAACK,WADF,EAEL,KAAKzN,KAAL,CAAW0N,KAFN,EAGL;AACEC,QAAAA,SAAS,EAAE,CACT;AAAEC,UAAAA,KAAK,EAAE,KAAKlM;AAAd,SADS,EAET,GAAG,KAAKF,OAAL,CAAaqM,qBAAb,EAFM;AADb,OAHK;AADT,OAYGd,QAZH,CATF,EAwBGC,0BAA0B,KACzBrC,OADyB,aACzBA,OADyB,uBACzBA,OAAO,CAAEmD,GAAT,CACGvC,KAAD,IACEzH,cAAc,iBACZ,oBAAC,qBAAD;AACE,MAAA,CAAC,EAAEyH,KAAK,CAACrL,CADX;AAEE,MAAA,CAAC,EAAEqL,KAAK,CAACpL,CAFX;AAGE,MAAA,GAAG,EAAEoL,KAAK,CAACtH,EAHb;AAIE,MAAA,iBAAiB,EAAEH,cAJrB;AAKE,MAAA,eAAe,EAAE,MAAM;AACrB,aAAK2H,YAAL,CAAkBF,KAAlB;AACD;AAPH,MAHN,CADyB,CAxB7B,EAyCGzJ,WAAW,CAACgM,GAAZ,CAAgB,CAAC;AAAE5N,MAAAA,CAAF;AAAKC,MAAAA;AAAL,KAAD,EAAW4N,KAAX,KAAqB;AACpC,0BAAO,oBAAC,eAAD;AAAiB,QAAA,GAAG,EAAEA,KAAtB;AAA6B,QAAA,CAAC,EAAE7N,CAAhC;AAAmC,QAAA,CAAC,EAAEC;AAAtC,QAAP;AACD,KAFA,CAzCH,EA6CGyC,iBAAiB,iBAChB,oBAAC,SAAD;AACE,MAAA,aAAa,EAAEkK,aADjB;AAEE,MAAA,iBAAiB,EAAElK,iBAFrB;AAGE,MAAA,OAAO,EAAEpD,OAHX;AAIE,MAAA,OAAO,EAAE0N,gBAJX;AAKE,MAAA,WAAW,EAAED,oBALf;AAME,MAAA,YAAY,EAAE,KAAKlH,uBANrB;AAOE,MAAA,OAAO,EAAE,KAAKc,OAPhB;AAQE,MAAA,UAAU,EAAGmH,IAAD,IAAkB;AAC5B,aAAKjN,QAAL,CAAc;AAAEvB,UAAAA,OAAO,EAAEwO;AAAX,SAAd;AACD,OAVH;AAWE,MAAA,QAAQ,EAAEb;AAXZ,MA9CJ,CADF;AA+DD;;AA1sCD;;gBAHIxN,uB,kBAQkB;AACpBsI,EAAAA,WAAW,EAAE,IADO;AAEpBhG,EAAAA,UAAU,EAAE,IAFQ;AAGpBG,EAAAA,WAAW,EAAE,CAHO;AAIpBqE,EAAAA,cAAc,EAAE,CAJI;AAKpBC,EAAAA,cAAc,EAAE,CALI;AAMpByC,EAAAA,OAAO,EAAE,GANW;AAOpBC,EAAAA,OAAO,EAAE,GAPW;AAQpBC,EAAAA,wBAAwB,EAAE,CARN;AASpBC,EAAAA,yBAAyB,EAAE,CATP;AAUpBsB,EAAAA,mBAAmB,EAAE,CAVD;AAWpB9G,EAAAA,cAAc,EAAE,GAXI;AAYpByD,EAAAA,aAAa,EAAE,IAZK;AAapB4E,EAAAA,QAAQ,EAAE,GAbU;AAcpB/K,EAAAA,WAAW,EAAE,IAdO;AAepBE,EAAAA,iBAAiB,EAAE,GAfC;AAgBpB6D,EAAAA,YAAY,EAAE8I,SAhBM;AAiBpB7I,EAAAA,aAAa,EAAE6I,SAjBK;AAkBpBtG,EAAAA,kBAAkB,EAAE,CAlBA;AAmBpBqF,EAAAA,0BAA0B,EAAE,IAnBR;AAoBpBpK,EAAAA,iBAAiB,EAAEqL,SApBC;AAqBpBnB,EAAAA,aAAa,EAAEmB,SArBK;AAsBpBzN,EAAAA,yBAAyB,EAAEyN,SAtBP;AAuBpBjF,EAAAA,uBAAuB,EAAEiF,SAvBL;AAwBpBrH,EAAAA,UAAU,EAAE,IAxBQ;AAyBpB1E,EAAAA,uBAAuB,EAAE;AAzBL,C;;AAwsCxB,MAAMkL,MAAM,GAAG/O,UAAU,CAACwH,MAAX,CAAkB;AAC/BwH,EAAAA,SAAS,EAAE;AACTa,IAAAA,UAAU,EAAE,QADH;AAETC,IAAAA,IAAI,EAAE,CAFG;AAGTC,IAAAA,cAAc,EAAE,QAHP;AAITC,IAAAA,QAAQ,EAAE,QAJD;AAKT9N,IAAAA,QAAQ,EAAE;AALD,GADoB;AAQ/BkN,EAAAA,WAAW,EAAE;AACXS,IAAAA,UAAU,EAAE,QADD;AAEXC,IAAAA,IAAI,EAAE,CAFK;AAGXC,IAAAA,cAAc,EAAE,QAHL;AAIX3O,IAAAA,KAAK,EAAE;AAJI;AARkB,CAAlB,CAAf;AAgBA,eAAeE,uBAAf;AAEA,SAASA,uBAAT","sourcesContent":["import React, { Component, createRef, RefObject } from 'react';\nimport {\n Animated,\n Easing,\n GestureResponderEvent,\n PanResponder,\n PanResponderCallbacks,\n PanResponderGestureState,\n PanResponderInstance,\n StyleSheet,\n View,\n} from 'react-native';\n\nimport {\n Vec2D,\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState,\n TouchPoint,\n ZoomableViewEvent,\n Size2D,\n} from './typings';\n\nimport { AnimatedTouchFeedback } from './components';\nimport { DebugTouchPoint } from './debugHelper';\nimport {\n calcGestureCenterPoint,\n calcGestureTouchDistance,\n calcNewScaledOffsetForZoomCentering,\n} from './helper';\nimport { applyPanBoundariesToOffset } from './helper/applyPanBoundariesToOffset';\nimport { viewportPositionToImagePosition } from './helper/coordinateConversion';\nimport { StaticPin } from './components/StaticPin';\nimport { debounce } from 'lodash';\nimport {\n getBoundaryCrossedAnim,\n getPanMomentumDecayAnim,\n getZoomToAnimation,\n} from './animations';\n\nconst initialState: ReactNativeZoomableViewState = {\n originalWidth: 0,\n originalHeight: 0,\n originalPageX: 0,\n originalPageY: 0,\n pinSize: { width: 0, height: 0 },\n};\n\nclass ReactNativeZoomableView extends Component<\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState\n> {\n zoomSubjectWrapperRef: RefObject;\n gestureHandlers: PanResponderInstance;\n doubleTapFirstTapReleaseTimestamp: number | undefined;\n\n static defaultProps = {\n zoomEnabled: true,\n panEnabled: true,\n initialZoom: 1,\n initialOffsetX: 0,\n initialOffsetY: 0,\n maxZoom: 1.5,\n minZoom: 0.5,\n pinchToZoomInSensitivity: 1,\n pinchToZoomOutSensitivity: 1,\n movementSensibility: 1,\n doubleTapDelay: 300,\n bindToBorders: true,\n zoomStep: 0.5,\n onLongPress: null,\n longPressDuration: 700,\n contentWidth: undefined,\n contentHeight: undefined,\n panBoundaryPadding: 0,\n visualTouchFeedbackEnabled: true,\n staticPinPosition: undefined,\n staticPinIcon: undefined,\n onStaticPinPositionChange: undefined,\n onStaticPinPositionMove: undefined,\n animatePin: true,\n disablePanOnInitialZoom: false,\n };\n\n private panAnim = new Animated.ValueXY({ x: 0, y: 0 });\n private zoomAnim = new Animated.Value(1);\n private pinAnim = new Animated.ValueXY({ x: 0, y: 0 });\n\n private __offsets = {\n x: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n y: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n };\n\n private zoomLevel = 1;\n private lastGestureCenterPosition: { x: number; y: number } | null = null;\n private lastGestureTouchDistance: number | null = null;\n private gestureType: 'pinch' | 'shift' | null;\n\n private _gestureStarted = false;\n private set gestureStarted(v: boolean) {\n this._gestureStarted = v;\n }\n\n public get gestureStarted() {\n return this._gestureStarted;\n }\n\n /**\n * Last press time (used to evaluate whether user double tapped)\n * @type {number}\n */\n private longPressTimeout: NodeJS.Timeout | null = null;\n private onTransformInvocationInitialized: boolean | undefined;\n private singleTapTimeoutId: NodeJS.Timeout | undefined;\n private touches: TouchPoint[] = [];\n private doubleTapFirstTap: TouchPoint | undefined;\n private measureZoomSubjectInterval: NodeJS.Timer | undefined;\n\n constructor(props: ReactNativeZoomableViewProps) {\n super(props);\n // This needs to be done before anything else to initialize the state.\n // Otherwise, the logic below may reference the state when it's undefined,\n // causing runtime errors.\n this.state = { ...initialState };\n\n this.gestureHandlers = PanResponder.create({\n onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,\n onPanResponderGrant: this._handlePanResponderGrant,\n onPanResponderMove: this._handlePanResponderMove,\n onPanResponderRelease: this._handlePanResponderEnd,\n onPanResponderTerminate: (evt, gestureState) => {\n // We should also call _handlePanResponderEnd\n // to properly perform cleanups when the gesture is terminated\n // (aka gesture handling responsibility is taken over by another component).\n // This also fixes a weird issue where\n // on real device, sometimes onPanResponderRelease is not called when you lift 2 fingers up,\n // but onPanResponderTerminate is called instead for no apparent reason.\n this._handlePanResponderEnd(evt, gestureState);\n this.props.onPanResponderTerminate?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n );\n },\n onPanResponderTerminationRequest: (evt, gestureState) =>\n !!this.props.onPanResponderTerminationRequest?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ),\n // Defaults to true to prevent parent components, such as React Navigation's tab view, from taking over as responder.\n onShouldBlockNativeResponder: (evt, gestureState) =>\n this.props.onShouldBlockNativeResponder?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ) ?? true,\n onStartShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onStartShouldSetPanResponderCapture?.(evt, gestureState),\n onMoveShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onMoveShouldSetPanResponderCapture?.(evt, gestureState),\n });\n\n this.zoomSubjectWrapperRef = createRef();\n\n if (this.props.zoomAnimatedValue)\n this.zoomAnim = this.props.zoomAnimatedValue;\n if (this.props.panAnimatedValueXY)\n this.panAnim = this.props.panAnimatedValueXY;\n\n if (this.props.initialZoom) this.zoomLevel = this.props.initialZoom;\n if (this.props.initialOffsetX != null)\n this.offsetX = this.props.initialOffsetX;\n if (this.props.initialOffsetY != null)\n this.offsetY = this.props.initialOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n this.panAnim.addListener(({ x, y }) => {\n this.offsetX = x;\n this.offsetY = y;\n });\n this.zoomAnim.addListener(({ value }) => {\n this.zoomLevel = value;\n });\n\n this.lastGestureTouchDistance = 150;\n\n this.gestureType = null;\n }\n\n private raisePin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: -10 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private dropPin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: 0 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private set offsetX(x: number) {\n this.__setOffset('x', x);\n }\n\n private set offsetY(y: number) {\n this.__setOffset('y', y);\n }\n\n private get offsetX() {\n return this.__getOffset('x');\n }\n\n private get offsetY() {\n return this.__getOffset('y');\n }\n\n private __setOffset(axis: 'x' | 'y', offset: number) {\n const offsetState = this.__offsets[axis];\n\n if (this.props.bindToBorders) {\n const containerSize =\n axis === 'x' ? this.state.originalWidth : this.state.originalHeight;\n const contentSize =\n axis === 'x'\n ? this.props.contentWidth || this.state.originalWidth\n : this.props.contentHeight || this.state.originalHeight;\n\n const boundOffset =\n contentSize && containerSize && this.props.panBoundaryPadding != null\n ? applyPanBoundariesToOffset(\n offset,\n containerSize,\n contentSize,\n this.zoomLevel,\n this.props.panBoundaryPadding\n )\n : offset;\n\n if (!this.gestureType && !offsetState.boundaryCrossedAnimInEffect) {\n const boundariesApplied =\n boundOffset !== offset &&\n boundOffset.toFixed(3) !== offset.toFixed(3);\n if (boundariesApplied) {\n offsetState.boundaryCrossedAnimInEffect = true;\n getBoundaryCrossedAnim(this.panAnim[axis], boundOffset).start(() => {\n offsetState.boundaryCrossedAnimInEffect = false;\n });\n return;\n }\n }\n }\n\n offsetState.value = offset;\n }\n\n private __getOffset(axis: 'x' | 'y') {\n return this.__offsets[axis].value;\n }\n\n componentDidUpdate(\n prevProps: ReactNativeZoomableViewProps,\n prevState: ReactNativeZoomableViewState\n ) {\n const { zoomEnabled, initialZoom } = this.props;\n if (prevProps.zoomEnabled && !zoomEnabled && initialZoom) {\n this.zoomLevel = initialZoom;\n this.zoomAnim.setValue(this.zoomLevel);\n }\n if (\n !this.onTransformInvocationInitialized &&\n this._invokeOnTransform().successful\n ) {\n this.panAnim.addListener(() => this._invokeOnTransform());\n this.zoomAnim.addListener(() => this._invokeOnTransform());\n this.onTransformInvocationInitialized = true;\n }\n\n const currState = this.state;\n const originalMeasurementsChanged =\n currState.originalHeight !== prevState.originalHeight ||\n currState.originalWidth !== prevState.originalWidth ||\n currState.originalPageX !== prevState.originalPageX ||\n currState.originalPageY !== prevState.originalPageY;\n\n const staticPinPositionChanged =\n prevProps.staticPinPosition?.x !== this.props.staticPinPosition?.x ||\n prevProps.staticPinPosition?.y !== this.props.staticPinPosition?.y;\n\n if (\n this.onTransformInvocationInitialized &&\n (originalMeasurementsChanged || staticPinPositionChanged)\n ) {\n this._invokeOnTransform();\n }\n }\n\n componentDidMount() {\n this.grabZoomSubjectOriginalMeasurements();\n // We've already run `grabZoomSubjectOriginalMeasurements` at various events\n // to make sure the measurements are promptly updated.\n // However, there might be cases we haven't accounted for, especially when\n // native processes are involved. To account for those cases,\n // we'll use an interval here to ensure we're always up-to-date.\n // The `setState` in `grabZoomSubjectOriginalMeasurements` won't trigger a rerender\n // if the values given haven't changed, so we're not running performance risk here.\n this.measureZoomSubjectInterval = setInterval(\n this.grabZoomSubjectOriginalMeasurements,\n 1e3\n );\n }\n\n componentWillUnmount() {\n this.measureZoomSubjectInterval &&\n clearInterval(this.measureZoomSubjectInterval);\n }\n\n debouncedOnStaticPinPositionChange = debounce(\n (position: Vec2D) => this.props.onStaticPinPositionChange?.(position),\n 100\n );\n\n /**\n * try to invoke onTransform\n * @private\n */\n _invokeOnTransform() {\n const zoomableViewEvent = this._getZoomableViewEventObject();\n const position = this._staticPinPosition();\n\n if (!zoomableViewEvent.originalWidth || !zoomableViewEvent.originalHeight)\n return { successful: false };\n\n this.props.onTransform?.(zoomableViewEvent);\n\n if (position) {\n this.props.onStaticPinPositionMove?.(position);\n this.debouncedOnStaticPinPositionChange(position);\n }\n\n return { successful: true };\n }\n\n /**\n * Returns additional information about components current state for external event hooks\n *\n * @returns {{}}\n * @private\n */\n _getZoomableViewEventObject(overwriteObj = {}): ZoomableViewEvent {\n return {\n zoomLevel: this.zoomLevel,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n originalHeight: this.state.originalHeight,\n originalWidth: this.state.originalWidth,\n originalPageX: this.state.originalPageX,\n originalPageY: this.state.originalPageY,\n ...overwriteObj,\n } as ZoomableViewEvent;\n }\n\n /**\n * Get the original box dimensions and save them for later use.\n * (They will be used to calculate boxBorders)\n *\n * @private\n */\n private grabZoomSubjectOriginalMeasurements = () => {\n // make sure we measure after animations are complete\n requestAnimationFrame(() => {\n // this setTimeout is here to fix a weird issue on iOS where the measurements are all `0`\n // when navigating back (react-navigation stack) from another view\n // while closing the keyboard at the same time\n setTimeout(() => {\n // In normal conditions, we're supposed to measure zoomSubject instead of its wrapper.\n // However, our zoomSubject may have been transformed by an initial zoomLevel or offset,\n // in which case these measurements will not represent the true \"original\" measurements.\n // We just need to make sure the zoomSubjectWrapper perfectly aligns with the zoomSubject\n // (no border, space, or anything between them)\n const zoomSubjectWrapperRef = this.zoomSubjectWrapperRef;\n // we don't wanna measure when zoomSubjectWrapperRef is not yet available or has been unmounted\n zoomSubjectWrapperRef.current?.measureInWindow(\n (x, y, width, height) => {\n // When the component is off-screen, these become all 0s, so we don't set them\n // to avoid messing up calculations, especially ones that are done right after\n // the component transitions from hidden to visible.\n if (!x && !y && !width && !height) return;\n\n // If these values are all the same, don't re-set them in state\n // this way we don't re-render\n if (\n this.state.originalWidth === width &&\n this.state.originalHeight === height &&\n this.state.originalPageX === x &&\n this.state.originalPageY === y\n ) {\n return;\n }\n\n this.setState({\n originalWidth: width,\n originalHeight: height,\n originalPageX: x,\n originalPageY: y,\n });\n }\n );\n });\n });\n };\n\n /**\n * Handles the start of touch events and checks for taps\n *\n * @param e\n * @param gestureState\n * @returns {boolean}\n *\n * @private\n */\n _handleStartShouldSetPanResponder = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onStartShouldSetPanResponder) {\n this.props.onStartShouldSetPanResponder(\n e,\n gestureState,\n this._getZoomableViewEventObject(),\n false\n );\n }\n\n // Always set pan responder on start\n // of gesture so we can handle tap.\n // \"Pan threshold validation\" will be handled\n // in `onPanResponderMove` instead of in `onMoveShouldSetPanResponder`\n return true;\n };\n\n /**\n * Calculates pinch distance\n *\n * @param e\n * @param gestureState\n * @private\n */\n _handlePanResponderGrant: NonNullable<\n PanResponderCallbacks['onPanResponderGrant']\n > = (e, gestureState) => {\n if (this.props.onLongPress) {\n this.longPressTimeout = setTimeout(() => {\n this.props.onLongPress?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n this.longPressTimeout = null;\n }, this.props.longPressDuration);\n }\n\n this.props.onPanResponderGrant?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n this.panAnim.stopAnimation();\n this.zoomAnim.stopAnimation();\n this.gestureStarted = true;\n\n this.raisePin();\n };\n\n /**\n * Handles the end of touch events\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderEnd: NonNullable<\n PanResponderCallbacks['onPanResponderEnd']\n > = (e, gestureState) => {\n if (!this.gestureType) {\n this._resolveAndHandleTap(e);\n }\n\n this.setState({ debugPoints: [] });\n\n this.lastGestureCenterPosition = null;\n\n const disableMomentum =\n this.props.disableMomentum ||\n (this.props.panEnabled &&\n this.gestureType === 'shift' &&\n this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom);\n\n // Trigger final shift animation unless disablePanOnInitialZoom is set and we're on the initial zoom level\n // or disableMomentum\n if (!disableMomentum) {\n getPanMomentumDecayAnim(this.panAnim, {\n x: gestureState.vx / this.zoomLevel,\n y: gestureState.vy / this.zoomLevel,\n }).start();\n }\n\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n this.props.onPanResponderEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n if (this.gestureType === 'pinch') {\n this.props.onZoomEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n } else if (this.gestureType === 'shift') {\n this.props.onShiftingEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n if (this.props.staticPinPosition) {\n this._updateStaticPin();\n }\n\n this.dropPin();\n\n this.gestureType = null;\n this.gestureStarted = false;\n };\n\n /**\n * Handles the actual movement of our pan responder\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderMove = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onPanResponderMove) {\n if (\n this.props.onPanResponderMove(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return false;\n }\n }\n\n // Only supports 2 touches and below,\n // any invalid number will cause the gesture to end.\n if (gestureState.numberActiveTouches <= 2) {\n if (!this.gestureStarted) {\n this._handlePanResponderGrant(e, gestureState);\n }\n } else {\n if (this.gestureStarted) {\n this._handlePanResponderEnd(e, gestureState);\n }\n return true;\n }\n\n if (gestureState.numberActiveTouches === 2) {\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'pinch') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n this.lastGestureTouchDistance = calcGestureTouchDistance(\n e,\n gestureState\n );\n }\n this.gestureType = 'pinch';\n this._handlePinching(e, gestureState);\n } else if (gestureState.numberActiveTouches === 1) {\n if (\n this.longPressTimeout &&\n (Math.abs(gestureState.dx) > 5 || Math.abs(gestureState.dy) > 5)\n ) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'shift') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n }\n\n const { dx, dy } = gestureState;\n const isShiftGesture = Math.abs(dx) > 2 || Math.abs(dy) > 2;\n if (isShiftGesture) {\n this.gestureType = 'shift';\n this._handleShifting(gestureState);\n }\n }\n };\n\n /**\n * Handles the pinch movement and zooming\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePinching(\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) {\n if (!this.props.zoomEnabled) return;\n\n const {\n maxZoom,\n minZoom,\n pinchToZoomInSensitivity,\n pinchToZoomOutSensitivity,\n } = this.props;\n\n const distance = calcGestureTouchDistance(e, gestureState);\n\n if (\n this.props.onZoomBefore &&\n this.props.onZoomBefore(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return;\n }\n\n if (!distance) return;\n if (!this.lastGestureTouchDistance) return;\n\n // define the new zoom level and take zoom level sensitivity into consideration\n const zoomGrowthFromLastGestureState =\n distance / this.lastGestureTouchDistance;\n this.lastGestureTouchDistance = distance;\n\n const pinchToZoomSensitivity =\n zoomGrowthFromLastGestureState < 1\n ? pinchToZoomOutSensitivity\n : pinchToZoomInSensitivity;\n\n if (pinchToZoomSensitivity == null) return;\n const deltaGrowth = zoomGrowthFromLastGestureState - 1;\n // 0 - no resistance\n // 10 - 90% resistance\n const deltaGrowthAdjustedBySensitivity =\n deltaGrowth * (1 - (pinchToZoomSensitivity * 9) / 100);\n\n let newZoomLevel = this.zoomLevel * (1 + deltaGrowthAdjustedBySensitivity);\n\n // make sure max and min zoom levels are respected\n if (maxZoom != null && newZoomLevel > maxZoom) {\n newZoomLevel = maxZoom;\n }\n\n if (minZoom != null && newZoomLevel < minZoom) {\n newZoomLevel = minZoom;\n }\n\n const gestureCenterPoint = calcGestureCenterPoint(e, gestureState);\n\n if (!gestureCenterPoint) return;\n\n let zoomCenter = {\n x: gestureCenterPoint.x - this.state.originalPageX,\n y: gestureCenterPoint.y - this.state.originalPageY,\n };\n\n if (this.props.staticPinPosition) {\n // When we use a static pin position, the zoom centre is the same as that position,\n // otherwise the pin moves around way too much while zooming.\n zoomCenter = {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n };\n }\n\n // Uncomment to debug\n this.props.debug && this._setPinchDebugPoints(e, zoomCenter);\n\n const { originalHeight, originalWidth } = this.state;\n\n const oldOffsetX = this.offsetX;\n const oldOffsetY = this.offsetY;\n const oldScale = this.zoomLevel;\n const newScale = newZoomLevel;\n\n if (!originalHeight || !originalWidth) return;\n\n let offsetY = calcNewScaledOffsetForZoomCentering(\n oldOffsetY,\n originalHeight,\n oldScale,\n newScale,\n zoomCenter.y\n );\n let offsetX = calcNewScaledOffsetForZoomCentering(\n oldOffsetX,\n originalWidth,\n oldScale,\n newScale,\n zoomCenter.x\n );\n\n const offsetShift =\n this._calcOffsetShiftSinceLastGestureState(gestureCenterPoint);\n if (offsetShift) {\n offsetX += offsetShift.x;\n offsetY += offsetShift.y;\n }\n\n this.offsetX = offsetX;\n this.offsetY = offsetY;\n this.zoomLevel = newScale;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n this.props.onZoomAfter?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n /**\n * Used to debug pinch events\n * @param gestureResponderEvent\n * @param zoomCenter\n * @param points\n */\n _setPinchDebugPoints(\n gestureResponderEvent: GestureResponderEvent,\n zoomCenter: Vec2D,\n ...points: Vec2D[]\n ) {\n const { touches } = gestureResponderEvent.nativeEvent;\n const { originalPageY, originalPageX } = this.state;\n\n this.setState({\n debugPoints: [\n {\n x: touches[0].pageX - originalPageX,\n y: touches[0].pageY - originalPageY,\n },\n {\n x: touches[1].pageX - originalPageX,\n y: touches[1].pageY - originalPageY,\n },\n zoomCenter,\n ...points,\n ],\n });\n }\n\n /**\n * Calculates the amount the offset should shift since the last position during panning\n *\n * @param {Vec2D} gestureCenterPoint\n *\n * @private\n */\n _calcOffsetShiftSinceLastGestureState(gestureCenterPoint: Vec2D) {\n const { movementSensibility } = this.props;\n\n let shift = null;\n\n if (this.lastGestureCenterPosition && movementSensibility) {\n const dx = gestureCenterPoint.x - this.lastGestureCenterPosition.x;\n const dy = gestureCenterPoint.y - this.lastGestureCenterPosition.y;\n\n const shiftX = dx / this.zoomLevel / movementSensibility;\n const shiftY = dy / this.zoomLevel / movementSensibility;\n\n shift = {\n x: shiftX,\n y: shiftY,\n };\n }\n\n this.lastGestureCenterPosition = gestureCenterPoint;\n\n return shift;\n }\n\n /**\n * Handles movement by tap and move\n *\n * @param gestureState\n *\n * @private\n */\n _handleShifting(gestureState: PanResponderGestureState) {\n // Skips shifting if panEnabled is false or disablePanOnInitialZoom is true and we're on the initial zoom level\n if (\n !this.props.panEnabled ||\n (this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom)\n ) {\n return;\n }\n const shift = this._calcOffsetShiftSinceLastGestureState({\n x: gestureState.moveX,\n y: gestureState.moveY,\n });\n if (!shift) return;\n\n const offsetX = this.offsetX + shift.x;\n const offsetY = this.offsetY + shift.y;\n\n if (\n this.props.debug &&\n this.state.originalPageX &&\n this.state.originalPageY\n ) {\n const x = gestureState.moveX - this.state.originalPageX;\n const y = gestureState.moveY - this.state.originalPageY;\n this.setState({ debugPoints: [{ x, y }] });\n }\n\n this._setNewOffsetPosition(offsetX, offsetY);\n\n this.raisePin();\n }\n\n /**\n * Set the state to offset moved\n *\n * @param {number} newOffsetX\n * @param {number} newOffsetY\n * @returns\n */\n _setNewOffsetPosition(newOffsetX: number, newOffsetY: number) {\n const { onShiftingBefore, onShiftingAfter } = this.props;\n\n if (onShiftingBefore?.(null, null, this._getZoomableViewEventObject())) {\n return;\n }\n\n this.offsetX = newOffsetX;\n this.offsetY = newOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n onShiftingAfter?.(null, null, this._getZoomableViewEventObject());\n }\n\n /**\n * Check whether the press event is double tap\n * or single tap and handle the event accordingly\n *\n * @param e\n *\n * @private\n */\n private _resolveAndHandleTap = (e: GestureResponderEvent) => {\n const now = Date.now();\n if (\n this.doubleTapFirstTapReleaseTimestamp &&\n this.props.doubleTapDelay &&\n now - this.doubleTapFirstTapReleaseTimestamp < this.props.doubleTapDelay\n ) {\n this.doubleTapFirstTap &&\n this._addTouch({\n ...this.doubleTapFirstTap,\n id: now.toString(),\n isSecondTap: true,\n });\n this.singleTapTimeoutId && clearTimeout(this.singleTapTimeoutId);\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n delete this.doubleTapFirstTap;\n this._handleDoubleTap(e);\n } else {\n this.doubleTapFirstTapReleaseTimestamp = now;\n this.doubleTapFirstTap = {\n id: now.toString(),\n x: e.nativeEvent.pageX - this.state.originalPageX,\n y: e.nativeEvent.pageY - this.state.originalPageY,\n };\n this._addTouch(this.doubleTapFirstTap);\n\n // persist event so e.nativeEvent is preserved after a timeout delay\n e.persist();\n this.singleTapTimeoutId = setTimeout(() => {\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n\n // Pan to the tapped location\n if (this.props.staticPinPosition && this.doubleTapFirstTap) {\n const tapX =\n this.props.staticPinPosition.x - this.doubleTapFirstTap.x;\n const tapY =\n this.props.staticPinPosition.y - this.doubleTapFirstTap.y;\n\n Animated.timing(this.panAnim, {\n toValue: {\n x: this.offsetX + tapX / this.zoomLevel,\n y: this.offsetY + tapY / this.zoomLevel,\n },\n useNativeDriver: true,\n duration: 200,\n }).start(() => {\n this._updateStaticPin();\n });\n }\n\n this.props.onSingleTap?.(e, this._getZoomableViewEventObject());\n }, this.props.doubleTapDelay);\n }\n };\n\n moveStaticPinTo = (position: Vec2D, duration?: number) => {\n const { originalWidth, originalHeight } = this.state;\n const { staticPinPosition, contentWidth, contentHeight } = this.props;\n\n if (!staticPinPosition) return;\n if (!originalWidth || !originalHeight) return;\n if (!contentWidth || !contentHeight) return;\n\n // Offset for the static pin\n const pinX = staticPinPosition.x - originalWidth / 2;\n const pinY = staticPinPosition.y - originalHeight / 2;\n\n this.offsetX = contentWidth / 2 - position.x + pinX / this.zoomLevel;\n this.offsetY = contentHeight / 2 - position.y + pinY / this.zoomLevel;\n\n if (duration) {\n Animated.timing(this.panAnim, {\n toValue: { x: this.offsetX, y: this.offsetY },\n useNativeDriver: true,\n duration,\n }).start();\n } else {\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n }\n };\n\n private _staticPinPosition = () => {\n if (!this.props.staticPinPosition) return;\n if (!this.props.contentWidth || !this.props.contentHeight) return;\n\n return viewportPositionToImagePosition({\n viewportPosition: {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n },\n imageSize: {\n height: this.props.contentHeight,\n width: this.props.contentWidth,\n },\n zoomableEvent: {\n ...this._getZoomableViewEventObject(),\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n zoomLevel: this.zoomLevel,\n },\n });\n };\n\n private _updateStaticPin = () => {\n const position = this._staticPinPosition();\n if (!position) return;\n this.props.onStaticPinPositionChange?.(position);\n };\n\n private _addTouch(touch: TouchPoint) {\n this.touches.push(touch);\n this.setState({ touches: [...this.touches] });\n }\n\n private _removeTouch(touch: TouchPoint) {\n this.touches.splice(this.touches.indexOf(touch), 1);\n this.setState({ touches: [...this.touches] });\n }\n\n /**\n * Handles the double tap event\n *\n * @param e\n *\n * @private\n */\n _handleDoubleTap(e: GestureResponderEvent) {\n const { onDoubleTapBefore, onDoubleTapAfter, doubleTapZoomToCenter } =\n this.props;\n\n onDoubleTapBefore?.(e, this._getZoomableViewEventObject());\n\n const nextZoomStep = this._getNextZoomStep();\n if (nextZoomStep == null) return;\n\n const { originalPageX, originalPageY } = this.state;\n\n // define new zoom position coordinates\n const zoomPositionCoordinates = {\n x: e.nativeEvent.pageX - originalPageX,\n y: e.nativeEvent.pageY - originalPageY,\n };\n\n // if doubleTapZoomToCenter enabled -> always zoom to center instead\n if (doubleTapZoomToCenter) {\n zoomPositionCoordinates.x = 0;\n zoomPositionCoordinates.y = 0;\n }\n\n this.zoomTo(nextZoomStep, zoomPositionCoordinates);\n\n onDoubleTapAfter?.(\n e,\n this._getZoomableViewEventObject({ zoomLevel: nextZoomStep })\n );\n }\n\n /**\n * Returns the next zoom step based on current step and zoomStep property.\n * If we are zoomed all the way in -> return to initialzoom\n *\n * @returns {*}\n */\n _getNextZoomStep() {\n const { zoomStep, maxZoom, initialZoom } = this.props;\n const { zoomLevel } = this;\n\n if (maxZoom == null) return;\n\n if (zoomLevel.toFixed(2) === maxZoom.toFixed(2)) {\n return initialZoom;\n }\n\n if (zoomStep == null) return;\n\n const nextZoomStep = zoomLevel * (1 + zoomStep);\n if (nextZoomStep > maxZoom) {\n return maxZoom;\n }\n\n return nextZoomStep;\n }\n\n /**\n * Zooms to a specific level. A \"zoom center\" can be provided, which specifies\n * the point that will remain in the same position on the screen after the zoom.\n * The coordinates of the zoom center is relative to the zoom subject.\n * { x: 0, y: 0 } is the very center of the zoom subject.\n *\n * @param newZoomLevel\n * @param zoomCenter - If not supplied, the container's center is the zoom center\n */\n zoomTo(newZoomLevel: number, zoomCenter?: Vec2D) {\n if (!this.props.zoomEnabled) return false;\n if (this.props.maxZoom && newZoomLevel > this.props.maxZoom) return false;\n if (this.props.minZoom && newZoomLevel < this.props.minZoom) return false;\n\n this.props.onZoomBefore?.(null, null, this._getZoomableViewEventObject());\n\n // == Perform Pan Animation to preserve the zoom center while zooming ==\n let listenerId: string | undefined;\n if (zoomCenter) {\n // Calculates panAnim values based on changes in zoomAnim.\n let prevScale = this.zoomLevel;\n // Since zoomAnim is calculated in native driver,\n // it will jitter panAnim once in a while,\n // because here panAnim is being calculated in js.\n // However the jittering should mostly occur in simulator.\n listenerId = this.zoomAnim.addListener(({ value: newScale }) => {\n this.panAnim.setValue({\n x: calcNewScaledOffsetForZoomCentering(\n this.offsetX,\n this.state.originalWidth,\n prevScale,\n newScale,\n zoomCenter.x\n ),\n y: calcNewScaledOffsetForZoomCentering(\n this.offsetY,\n this.state.originalHeight,\n prevScale,\n newScale,\n zoomCenter.y\n ),\n });\n prevScale = newScale;\n });\n }\n\n // == Perform Zoom Animation ==\n getZoomToAnimation(this.zoomAnim, newZoomLevel).start(() => {\n if (!listenerId) return;\n this.zoomAnim.removeListener(listenerId);\n });\n // == Zoom Animation Ends ==\n\n this.props.onZoomAfter?.(null, null, this._getZoomableViewEventObject());\n return true;\n }\n\n /**\n * Zooms in or out by a specified change level\n * Use a positive number for `zoomLevelChange` to zoom in\n * Use a negative number for `zoomLevelChange` to zoom out\n *\n * Returns a promise if everything was updated and a boolean, whether it could be updated or if it exceeded the min/max zoom limits.\n *\n * @param {number | null} zoomLevelChange\n *\n * @return {bool}\n */\n zoomBy(zoomLevelChange: number) {\n // if no zoom level Change given -> just use zoom step\n zoomLevelChange ||= this.props.zoomStep || 0;\n return this.zoomTo(this.zoomLevel + zoomLevelChange);\n }\n\n /**\n * Moves the zoomed view to a specified position\n * Returns a promise when finished\n *\n * @param {number} newOffsetX the new position we want to move it to (x-axis)\n * @param {number} newOffsetY the new position we want to move it to (y-axis)\n *\n * @return {bool}\n */\n moveTo(newOffsetX: number, newOffsetY: number) {\n const { originalWidth, originalHeight } = this.state;\n if (!originalWidth || !originalHeight) return;\n\n const offsetX = (newOffsetX - originalWidth / 2) / this.zoomLevel;\n const offsetY = (newOffsetY - originalHeight / 2) / this.zoomLevel;\n\n this._setNewOffsetPosition(-offsetX, -offsetY);\n }\n\n /**\n * Moves the zoomed view by a certain amount.\n *\n * Returns a promise when finished\n *\n * @param {number} offsetChangeX the amount we want to move the offset by (x-axis)\n * @param {number} offsetChangeY the amount we want to move the offset by (y-axis)\n *\n * @return {bool}\n */\n moveBy(offsetChangeX: number, offsetChangeY: number) {\n const offsetX =\n (this.offsetX * this.zoomLevel - offsetChangeX) / this.zoomLevel;\n const offsetY =\n (this.offsetY * this.zoomLevel - offsetChangeY) / this.zoomLevel;\n\n this._setNewOffsetPosition(offsetX, offsetY);\n }\n\n render() {\n const {\n staticPinIcon,\n children,\n visualTouchFeedbackEnabled,\n doubleTapDelay,\n staticPinPosition,\n onStaticPinLongPress,\n onStaticPinPress,\n pinProps,\n } = this.props;\n const { pinSize, touches, debugPoints = [] } = this.state;\n\n return (\n {\n this.props.onLayout?.(event);\n this.grabZoomSubjectOriginalMeasurements();\n }}\n >\n \n {children}\n \n\n {visualTouchFeedbackEnabled &&\n touches?.map(\n (touch) =>\n doubleTapDelay && (\n {\n this._removeTouch(touch);\n }}\n />\n )\n )}\n\n {/* For Debugging Only */}\n {debugPoints.map(({ x, y }, index) => {\n return ;\n })}\n\n {staticPinPosition && (\n {\n this.setState({ pinSize: size });\n }}\n pinProps={pinProps}\n />\n )}\n \n );\n }\n}\n\nconst styles = StyleSheet.create({\n container: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n overflow: 'hidden',\n position: 'relative',\n },\n zoomSubject: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n width: '100%',\n },\n});\n\nexport default ReactNativeZoomableView;\n\nexport { ReactNativeZoomableView };\n"]} \ No newline at end of file diff --git a/lib/typescript/ReactNativeZoomableView.d.ts b/lib/typescript/ReactNativeZoomableView.d.ts index 48edb63..418ead4 100644 --- a/lib/typescript/ReactNativeZoomableView.d.ts +++ b/lib/typescript/ReactNativeZoomableView.d.ts @@ -203,7 +203,7 @@ declare class ReactNativeZoomableView extends Component Date: Fri, 10 Jan 2025 13:53:54 -0800 Subject: [PATCH 3/4] version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6682236..a4cf8c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@openspacelabs/react-native-zoomable-view", - "version": "2.3.1", + "version": "2.3.2", "description": "A view component for react-native with pinch to zoom, tap to move and double tap to zoom capability.", "main": "lib/commonjs/index", "module": "lib/module/index", From d62569a6eb27407b695c2eee9b072786e4a58354 Mon Sep 17 00:00:00 2001 From: thomasvo Date: Fri, 10 Jan 2025 13:55:29 -0800 Subject: [PATCH 4/4] simpler --- lib/commonjs/ReactNativeZoomableView.js | 3 +-- lib/commonjs/ReactNativeZoomableView.js.map | 2 +- lib/module/ReactNativeZoomableView.js | 3 +-- lib/module/ReactNativeZoomableView.js.map | 2 +- src/ReactNativeZoomableView.tsx | 3 +-- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/commonjs/ReactNativeZoomableView.js b/lib/commonjs/ReactNativeZoomableView.js index f371947..2dbbd9d 100644 --- a/lib/commonjs/ReactNativeZoomableView.js +++ b/lib/commonjs/ReactNativeZoomableView.js @@ -983,7 +983,7 @@ class ReactNativeZoomableView extends _react.Component { if (this.props.minZoom && newZoomLevel < this.props.minZoom) return false; (_this$props$onZoomBef = (_this$props17 = this.props).onZoomBefore) === null || _this$props$onZoomBef === void 0 ? void 0 : _this$props$onZoomBef.call(_this$props17, null, null, this._getZoomableViewEventObject()); // == Perform Pan Animation to preserve the zoom center while zooming == - let listenerId; + let listenerId = ''; if (zoomCenter) { // Calculates panAnim values based on changes in zoomAnim. @@ -1005,7 +1005,6 @@ class ReactNativeZoomableView extends _react.Component { (0, _animations.getZoomToAnimation)(this.zoomAnim, newZoomLevel).start(() => { - if (!listenerId) return; this.zoomAnim.removeListener(listenerId); }); // == Zoom Animation Ends == diff --git a/lib/commonjs/ReactNativeZoomableView.js.map b/lib/commonjs/ReactNativeZoomableView.js.map index ba109d7..dcc6a9f 100644 --- a/lib/commonjs/ReactNativeZoomableView.js.map +++ b/lib/commonjs/ReactNativeZoomableView.js.map @@ -1 +1 @@ -{"version":3,"sources":["ReactNativeZoomableView.tsx"],"names":["initialState","originalWidth","originalHeight","originalPageX","originalPageY","pinSize","width","height","ReactNativeZoomableView","Component","gestureStarted","v","_gestureStarted","constructor","props","Animated","ValueXY","x","y","Value","value","boundaryCrossedAnimInEffect","position","onStaticPinPositionChange","requestAnimationFrame","setTimeout","zoomSubjectWrapperRef","current","measureInWindow","state","setState","e","gestureState","onStartShouldSetPanResponder","_getZoomableViewEventObject","onLongPress","longPressTimeout","longPressDuration","onPanResponderGrant","panAnim","stopAnimation","zoomAnim","raisePin","gestureType","_resolveAndHandleTap","debugPoints","lastGestureCenterPosition","disableMomentum","panEnabled","disablePanOnInitialZoom","zoomLevel","initialZoom","vx","vy","start","clearTimeout","onPanResponderEnd","onZoomEnd","onShiftingEnd","staticPinPosition","_updateStaticPin","dropPin","onPanResponderMove","numberActiveTouches","_handlePanResponderGrant","_handlePanResponderEnd","lastGestureTouchDistance","_handlePinching","Math","abs","dx","dy","isShiftGesture","_handleShifting","now","Date","doubleTapFirstTapReleaseTimestamp","doubleTapDelay","doubleTapFirstTap","_addTouch","id","toString","isSecondTap","singleTapTimeoutId","_handleDoubleTap","nativeEvent","pageX","pageY","persist","tapX","tapY","timing","toValue","offsetX","offsetY","useNativeDriver","duration","onSingleTap","contentWidth","contentHeight","pinX","pinY","setValue","viewportPosition","imageSize","zoomableEvent","_staticPinPosition","gestureHandlers","PanResponder","create","_handleStartShouldSetPanResponder","_handlePanResponderMove","onPanResponderRelease","onPanResponderTerminate","evt","onPanResponderTerminationRequest","onShouldBlockNativeResponder","onStartShouldSetPanResponderCapture","onMoveShouldSetPanResponderCapture","zoomAnimatedValue","panAnimatedValueXY","initialOffsetX","initialOffsetY","addListener","animatePin","pinAnim","easing","Easing","out","ease","__setOffset","__getOffset","axis","offset","offsetState","__offsets","bindToBorders","containerSize","contentSize","boundOffset","panBoundaryPadding","boundariesApplied","toFixed","componentDidUpdate","prevProps","prevState","zoomEnabled","onTransformInvocationInitialized","_invokeOnTransform","successful","currState","originalMeasurementsChanged","staticPinPositionChanged","componentDidMount","grabZoomSubjectOriginalMeasurements","measureZoomSubjectInterval","setInterval","componentWillUnmount","clearInterval","zoomableViewEvent","onTransform","onStaticPinPositionMove","debouncedOnStaticPinPositionChange","overwriteObj","maxZoom","minZoom","pinchToZoomInSensitivity","pinchToZoomOutSensitivity","distance","onZoomBefore","zoomGrowthFromLastGestureState","pinchToZoomSensitivity","deltaGrowth","deltaGrowthAdjustedBySensitivity","newZoomLevel","gestureCenterPoint","zoomCenter","debug","_setPinchDebugPoints","oldOffsetX","oldOffsetY","oldScale","newScale","offsetShift","_calcOffsetShiftSinceLastGestureState","onZoomAfter","gestureResponderEvent","points","touches","movementSensibility","shift","shiftX","shiftY","moveX","moveY","_setNewOffsetPosition","newOffsetX","newOffsetY","onShiftingBefore","onShiftingAfter","touch","push","_removeTouch","splice","indexOf","onDoubleTapBefore","onDoubleTapAfter","doubleTapZoomToCenter","nextZoomStep","_getNextZoomStep","zoomPositionCoordinates","zoomTo","zoomStep","listenerId","prevScale","removeListener","zoomBy","zoomLevelChange","moveTo","moveBy","offsetChangeX","offsetChangeY","render","staticPinIcon","children","visualTouchFeedbackEnabled","onStaticPinLongPress","onStaticPinPress","pinProps","styles","container","panHandlers","event","onLayout","zoomSubject","style","transform","scale","getTranslateTransform","map","index","size","undefined","StyleSheet","alignItems","flex","justifyContent","overflow"],"mappings":"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","sourcesContent":["import React, { Component, createRef, RefObject } from 'react';\nimport {\n Animated,\n Easing,\n GestureResponderEvent,\n PanResponder,\n PanResponderCallbacks,\n PanResponderGestureState,\n PanResponderInstance,\n StyleSheet,\n View,\n} from 'react-native';\n\nimport {\n Vec2D,\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState,\n TouchPoint,\n ZoomableViewEvent,\n Size2D,\n} from './typings';\n\nimport { AnimatedTouchFeedback } from './components';\nimport { DebugTouchPoint } from './debugHelper';\nimport {\n calcGestureCenterPoint,\n calcGestureTouchDistance,\n calcNewScaledOffsetForZoomCentering,\n} from './helper';\nimport { applyPanBoundariesToOffset } from './helper/applyPanBoundariesToOffset';\nimport { viewportPositionToImagePosition } from './helper/coordinateConversion';\nimport { StaticPin } from './components/StaticPin';\nimport { debounce } from 'lodash';\nimport {\n getBoundaryCrossedAnim,\n getPanMomentumDecayAnim,\n getZoomToAnimation,\n} from './animations';\n\nconst initialState: ReactNativeZoomableViewState = {\n originalWidth: 0,\n originalHeight: 0,\n originalPageX: 0,\n originalPageY: 0,\n pinSize: { width: 0, height: 0 },\n};\n\nclass ReactNativeZoomableView extends Component<\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState\n> {\n zoomSubjectWrapperRef: RefObject;\n gestureHandlers: PanResponderInstance;\n doubleTapFirstTapReleaseTimestamp: number | undefined;\n\n static defaultProps = {\n zoomEnabled: true,\n panEnabled: true,\n initialZoom: 1,\n initialOffsetX: 0,\n initialOffsetY: 0,\n maxZoom: 1.5,\n minZoom: 0.5,\n pinchToZoomInSensitivity: 1,\n pinchToZoomOutSensitivity: 1,\n movementSensibility: 1,\n doubleTapDelay: 300,\n bindToBorders: true,\n zoomStep: 0.5,\n onLongPress: null,\n longPressDuration: 700,\n contentWidth: undefined,\n contentHeight: undefined,\n panBoundaryPadding: 0,\n visualTouchFeedbackEnabled: true,\n staticPinPosition: undefined,\n staticPinIcon: undefined,\n onStaticPinPositionChange: undefined,\n onStaticPinPositionMove: undefined,\n animatePin: true,\n disablePanOnInitialZoom: false,\n };\n\n private panAnim = new Animated.ValueXY({ x: 0, y: 0 });\n private zoomAnim = new Animated.Value(1);\n private pinAnim = new Animated.ValueXY({ x: 0, y: 0 });\n\n private __offsets = {\n x: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n y: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n };\n\n private zoomLevel = 1;\n private lastGestureCenterPosition: { x: number; y: number } | null = null;\n private lastGestureTouchDistance: number | null = null;\n private gestureType: 'pinch' | 'shift' | null;\n\n private _gestureStarted = false;\n private set gestureStarted(v: boolean) {\n this._gestureStarted = v;\n }\n\n public get gestureStarted() {\n return this._gestureStarted;\n }\n\n /**\n * Last press time (used to evaluate whether user double tapped)\n * @type {number}\n */\n private longPressTimeout: NodeJS.Timeout | null = null;\n private onTransformInvocationInitialized: boolean | undefined;\n private singleTapTimeoutId: NodeJS.Timeout | undefined;\n private touches: TouchPoint[] = [];\n private doubleTapFirstTap: TouchPoint | undefined;\n private measureZoomSubjectInterval: NodeJS.Timer | undefined;\n\n constructor(props: ReactNativeZoomableViewProps) {\n super(props);\n // This needs to be done before anything else to initialize the state.\n // Otherwise, the logic below may reference the state when it's undefined,\n // causing runtime errors.\n this.state = { ...initialState };\n\n this.gestureHandlers = PanResponder.create({\n onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,\n onPanResponderGrant: this._handlePanResponderGrant,\n onPanResponderMove: this._handlePanResponderMove,\n onPanResponderRelease: this._handlePanResponderEnd,\n onPanResponderTerminate: (evt, gestureState) => {\n // We should also call _handlePanResponderEnd\n // to properly perform cleanups when the gesture is terminated\n // (aka gesture handling responsibility is taken over by another component).\n // This also fixes a weird issue where\n // on real device, sometimes onPanResponderRelease is not called when you lift 2 fingers up,\n // but onPanResponderTerminate is called instead for no apparent reason.\n this._handlePanResponderEnd(evt, gestureState);\n this.props.onPanResponderTerminate?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n );\n },\n onPanResponderTerminationRequest: (evt, gestureState) =>\n !!this.props.onPanResponderTerminationRequest?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ),\n // Defaults to true to prevent parent components, such as React Navigation's tab view, from taking over as responder.\n onShouldBlockNativeResponder: (evt, gestureState) =>\n this.props.onShouldBlockNativeResponder?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ) ?? true,\n onStartShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onStartShouldSetPanResponderCapture?.(evt, gestureState),\n onMoveShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onMoveShouldSetPanResponderCapture?.(evt, gestureState),\n });\n\n this.zoomSubjectWrapperRef = createRef();\n\n if (this.props.zoomAnimatedValue)\n this.zoomAnim = this.props.zoomAnimatedValue;\n if (this.props.panAnimatedValueXY)\n this.panAnim = this.props.panAnimatedValueXY;\n\n if (this.props.initialZoom) this.zoomLevel = this.props.initialZoom;\n if (this.props.initialOffsetX != null)\n this.offsetX = this.props.initialOffsetX;\n if (this.props.initialOffsetY != null)\n this.offsetY = this.props.initialOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n this.panAnim.addListener(({ x, y }) => {\n this.offsetX = x;\n this.offsetY = y;\n });\n this.zoomAnim.addListener(({ value }) => {\n this.zoomLevel = value;\n });\n\n this.lastGestureTouchDistance = 150;\n\n this.gestureType = null;\n }\n\n private raisePin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: -10 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private dropPin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: 0 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private set offsetX(x: number) {\n this.__setOffset('x', x);\n }\n\n private set offsetY(y: number) {\n this.__setOffset('y', y);\n }\n\n private get offsetX() {\n return this.__getOffset('x');\n }\n\n private get offsetY() {\n return this.__getOffset('y');\n }\n\n private __setOffset(axis: 'x' | 'y', offset: number) {\n const offsetState = this.__offsets[axis];\n\n if (this.props.bindToBorders) {\n const containerSize =\n axis === 'x' ? this.state.originalWidth : this.state.originalHeight;\n const contentSize =\n axis === 'x'\n ? this.props.contentWidth || this.state.originalWidth\n : this.props.contentHeight || this.state.originalHeight;\n\n const boundOffset =\n contentSize && containerSize && this.props.panBoundaryPadding != null\n ? applyPanBoundariesToOffset(\n offset,\n containerSize,\n contentSize,\n this.zoomLevel,\n this.props.panBoundaryPadding\n )\n : offset;\n\n if (!this.gestureType && !offsetState.boundaryCrossedAnimInEffect) {\n const boundariesApplied =\n boundOffset !== offset &&\n boundOffset.toFixed(3) !== offset.toFixed(3);\n if (boundariesApplied) {\n offsetState.boundaryCrossedAnimInEffect = true;\n getBoundaryCrossedAnim(this.panAnim[axis], boundOffset).start(() => {\n offsetState.boundaryCrossedAnimInEffect = false;\n });\n return;\n }\n }\n }\n\n offsetState.value = offset;\n }\n\n private __getOffset(axis: 'x' | 'y') {\n return this.__offsets[axis].value;\n }\n\n componentDidUpdate(\n prevProps: ReactNativeZoomableViewProps,\n prevState: ReactNativeZoomableViewState\n ) {\n const { zoomEnabled, initialZoom } = this.props;\n if (prevProps.zoomEnabled && !zoomEnabled && initialZoom) {\n this.zoomLevel = initialZoom;\n this.zoomAnim.setValue(this.zoomLevel);\n }\n if (\n !this.onTransformInvocationInitialized &&\n this._invokeOnTransform().successful\n ) {\n this.panAnim.addListener(() => this._invokeOnTransform());\n this.zoomAnim.addListener(() => this._invokeOnTransform());\n this.onTransformInvocationInitialized = true;\n }\n\n const currState = this.state;\n const originalMeasurementsChanged =\n currState.originalHeight !== prevState.originalHeight ||\n currState.originalWidth !== prevState.originalWidth ||\n currState.originalPageX !== prevState.originalPageX ||\n currState.originalPageY !== prevState.originalPageY;\n\n const staticPinPositionChanged =\n prevProps.staticPinPosition?.x !== this.props.staticPinPosition?.x ||\n prevProps.staticPinPosition?.y !== this.props.staticPinPosition?.y;\n\n if (\n this.onTransformInvocationInitialized &&\n (originalMeasurementsChanged || staticPinPositionChanged)\n ) {\n this._invokeOnTransform();\n }\n }\n\n componentDidMount() {\n this.grabZoomSubjectOriginalMeasurements();\n // We've already run `grabZoomSubjectOriginalMeasurements` at various events\n // to make sure the measurements are promptly updated.\n // However, there might be cases we haven't accounted for, especially when\n // native processes are involved. To account for those cases,\n // we'll use an interval here to ensure we're always up-to-date.\n // The `setState` in `grabZoomSubjectOriginalMeasurements` won't trigger a rerender\n // if the values given haven't changed, so we're not running performance risk here.\n this.measureZoomSubjectInterval = setInterval(\n this.grabZoomSubjectOriginalMeasurements,\n 1e3\n );\n }\n\n componentWillUnmount() {\n this.measureZoomSubjectInterval &&\n clearInterval(this.measureZoomSubjectInterval);\n }\n\n debouncedOnStaticPinPositionChange = debounce(\n (position: Vec2D) => this.props.onStaticPinPositionChange?.(position),\n 100\n );\n\n /**\n * try to invoke onTransform\n * @private\n */\n _invokeOnTransform() {\n const zoomableViewEvent = this._getZoomableViewEventObject();\n const position = this._staticPinPosition();\n\n if (!zoomableViewEvent.originalWidth || !zoomableViewEvent.originalHeight)\n return { successful: false };\n\n this.props.onTransform?.(zoomableViewEvent);\n\n if (position) {\n this.props.onStaticPinPositionMove?.(position);\n this.debouncedOnStaticPinPositionChange(position);\n }\n\n return { successful: true };\n }\n\n /**\n * Returns additional information about components current state for external event hooks\n *\n * @returns {{}}\n * @private\n */\n _getZoomableViewEventObject(overwriteObj = {}): ZoomableViewEvent {\n return {\n zoomLevel: this.zoomLevel,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n originalHeight: this.state.originalHeight,\n originalWidth: this.state.originalWidth,\n originalPageX: this.state.originalPageX,\n originalPageY: this.state.originalPageY,\n ...overwriteObj,\n } as ZoomableViewEvent;\n }\n\n /**\n * Get the original box dimensions and save them for later use.\n * (They will be used to calculate boxBorders)\n *\n * @private\n */\n private grabZoomSubjectOriginalMeasurements = () => {\n // make sure we measure after animations are complete\n requestAnimationFrame(() => {\n // this setTimeout is here to fix a weird issue on iOS where the measurements are all `0`\n // when navigating back (react-navigation stack) from another view\n // while closing the keyboard at the same time\n setTimeout(() => {\n // In normal conditions, we're supposed to measure zoomSubject instead of its wrapper.\n // However, our zoomSubject may have been transformed by an initial zoomLevel or offset,\n // in which case these measurements will not represent the true \"original\" measurements.\n // We just need to make sure the zoomSubjectWrapper perfectly aligns with the zoomSubject\n // (no border, space, or anything between them)\n const zoomSubjectWrapperRef = this.zoomSubjectWrapperRef;\n // we don't wanna measure when zoomSubjectWrapperRef is not yet available or has been unmounted\n zoomSubjectWrapperRef.current?.measureInWindow(\n (x, y, width, height) => {\n // When the component is off-screen, these become all 0s, so we don't set them\n // to avoid messing up calculations, especially ones that are done right after\n // the component transitions from hidden to visible.\n if (!x && !y && !width && !height) return;\n\n // If these values are all the same, don't re-set them in state\n // this way we don't re-render\n if (\n this.state.originalWidth === width &&\n this.state.originalHeight === height &&\n this.state.originalPageX === x &&\n this.state.originalPageY === y\n ) {\n return;\n }\n\n this.setState({\n originalWidth: width,\n originalHeight: height,\n originalPageX: x,\n originalPageY: y,\n });\n }\n );\n });\n });\n };\n\n /**\n * Handles the start of touch events and checks for taps\n *\n * @param e\n * @param gestureState\n * @returns {boolean}\n *\n * @private\n */\n _handleStartShouldSetPanResponder = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onStartShouldSetPanResponder) {\n this.props.onStartShouldSetPanResponder(\n e,\n gestureState,\n this._getZoomableViewEventObject(),\n false\n );\n }\n\n // Always set pan responder on start\n // of gesture so we can handle tap.\n // \"Pan threshold validation\" will be handled\n // in `onPanResponderMove` instead of in `onMoveShouldSetPanResponder`\n return true;\n };\n\n /**\n * Calculates pinch distance\n *\n * @param e\n * @param gestureState\n * @private\n */\n _handlePanResponderGrant: NonNullable<\n PanResponderCallbacks['onPanResponderGrant']\n > = (e, gestureState) => {\n if (this.props.onLongPress) {\n this.longPressTimeout = setTimeout(() => {\n this.props.onLongPress?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n this.longPressTimeout = null;\n }, this.props.longPressDuration);\n }\n\n this.props.onPanResponderGrant?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n this.panAnim.stopAnimation();\n this.zoomAnim.stopAnimation();\n this.gestureStarted = true;\n\n this.raisePin();\n };\n\n /**\n * Handles the end of touch events\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderEnd: NonNullable<\n PanResponderCallbacks['onPanResponderEnd']\n > = (e, gestureState) => {\n if (!this.gestureType) {\n this._resolveAndHandleTap(e);\n }\n\n this.setState({ debugPoints: [] });\n\n this.lastGestureCenterPosition = null;\n\n const disableMomentum =\n this.props.disableMomentum ||\n (this.props.panEnabled &&\n this.gestureType === 'shift' &&\n this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom);\n\n // Trigger final shift animation unless disablePanOnInitialZoom is set and we're on the initial zoom level\n // or disableMomentum\n if (!disableMomentum) {\n getPanMomentumDecayAnim(this.panAnim, {\n x: gestureState.vx / this.zoomLevel,\n y: gestureState.vy / this.zoomLevel,\n }).start();\n }\n\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n this.props.onPanResponderEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n if (this.gestureType === 'pinch') {\n this.props.onZoomEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n } else if (this.gestureType === 'shift') {\n this.props.onShiftingEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n if (this.props.staticPinPosition) {\n this._updateStaticPin();\n }\n\n this.dropPin();\n\n this.gestureType = null;\n this.gestureStarted = false;\n };\n\n /**\n * Handles the actual movement of our pan responder\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderMove = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onPanResponderMove) {\n if (\n this.props.onPanResponderMove(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return false;\n }\n }\n\n // Only supports 2 touches and below,\n // any invalid number will cause the gesture to end.\n if (gestureState.numberActiveTouches <= 2) {\n if (!this.gestureStarted) {\n this._handlePanResponderGrant(e, gestureState);\n }\n } else {\n if (this.gestureStarted) {\n this._handlePanResponderEnd(e, gestureState);\n }\n return true;\n }\n\n if (gestureState.numberActiveTouches === 2) {\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'pinch') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n this.lastGestureTouchDistance = calcGestureTouchDistance(\n e,\n gestureState\n );\n }\n this.gestureType = 'pinch';\n this._handlePinching(e, gestureState);\n } else if (gestureState.numberActiveTouches === 1) {\n if (\n this.longPressTimeout &&\n (Math.abs(gestureState.dx) > 5 || Math.abs(gestureState.dy) > 5)\n ) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'shift') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n }\n\n const { dx, dy } = gestureState;\n const isShiftGesture = Math.abs(dx) > 2 || Math.abs(dy) > 2;\n if (isShiftGesture) {\n this.gestureType = 'shift';\n this._handleShifting(gestureState);\n }\n }\n };\n\n /**\n * Handles the pinch movement and zooming\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePinching(\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) {\n if (!this.props.zoomEnabled) return;\n\n const {\n maxZoom,\n minZoom,\n pinchToZoomInSensitivity,\n pinchToZoomOutSensitivity,\n } = this.props;\n\n const distance = calcGestureTouchDistance(e, gestureState);\n\n if (\n this.props.onZoomBefore &&\n this.props.onZoomBefore(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return;\n }\n\n if (!distance) return;\n if (!this.lastGestureTouchDistance) return;\n\n // define the new zoom level and take zoom level sensitivity into consideration\n const zoomGrowthFromLastGestureState =\n distance / this.lastGestureTouchDistance;\n this.lastGestureTouchDistance = distance;\n\n const pinchToZoomSensitivity =\n zoomGrowthFromLastGestureState < 1\n ? pinchToZoomOutSensitivity\n : pinchToZoomInSensitivity;\n\n if (pinchToZoomSensitivity == null) return;\n const deltaGrowth = zoomGrowthFromLastGestureState - 1;\n // 0 - no resistance\n // 10 - 90% resistance\n const deltaGrowthAdjustedBySensitivity =\n deltaGrowth * (1 - (pinchToZoomSensitivity * 9) / 100);\n\n let newZoomLevel = this.zoomLevel * (1 + deltaGrowthAdjustedBySensitivity);\n\n // make sure max and min zoom levels are respected\n if (maxZoom != null && newZoomLevel > maxZoom) {\n newZoomLevel = maxZoom;\n }\n\n if (minZoom != null && newZoomLevel < minZoom) {\n newZoomLevel = minZoom;\n }\n\n const gestureCenterPoint = calcGestureCenterPoint(e, gestureState);\n\n if (!gestureCenterPoint) return;\n\n let zoomCenter = {\n x: gestureCenterPoint.x - this.state.originalPageX,\n y: gestureCenterPoint.y - this.state.originalPageY,\n };\n\n if (this.props.staticPinPosition) {\n // When we use a static pin position, the zoom centre is the same as that position,\n // otherwise the pin moves around way too much while zooming.\n zoomCenter = {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n };\n }\n\n // Uncomment to debug\n this.props.debug && this._setPinchDebugPoints(e, zoomCenter);\n\n const { originalHeight, originalWidth } = this.state;\n\n const oldOffsetX = this.offsetX;\n const oldOffsetY = this.offsetY;\n const oldScale = this.zoomLevel;\n const newScale = newZoomLevel;\n\n if (!originalHeight || !originalWidth) return;\n\n let offsetY = calcNewScaledOffsetForZoomCentering(\n oldOffsetY,\n originalHeight,\n oldScale,\n newScale,\n zoomCenter.y\n );\n let offsetX = calcNewScaledOffsetForZoomCentering(\n oldOffsetX,\n originalWidth,\n oldScale,\n newScale,\n zoomCenter.x\n );\n\n const offsetShift =\n this._calcOffsetShiftSinceLastGestureState(gestureCenterPoint);\n if (offsetShift) {\n offsetX += offsetShift.x;\n offsetY += offsetShift.y;\n }\n\n this.offsetX = offsetX;\n this.offsetY = offsetY;\n this.zoomLevel = newScale;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n this.props.onZoomAfter?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n /**\n * Used to debug pinch events\n * @param gestureResponderEvent\n * @param zoomCenter\n * @param points\n */\n _setPinchDebugPoints(\n gestureResponderEvent: GestureResponderEvent,\n zoomCenter: Vec2D,\n ...points: Vec2D[]\n ) {\n const { touches } = gestureResponderEvent.nativeEvent;\n const { originalPageY, originalPageX } = this.state;\n\n this.setState({\n debugPoints: [\n {\n x: touches[0].pageX - originalPageX,\n y: touches[0].pageY - originalPageY,\n },\n {\n x: touches[1].pageX - originalPageX,\n y: touches[1].pageY - originalPageY,\n },\n zoomCenter,\n ...points,\n ],\n });\n }\n\n /**\n * Calculates the amount the offset should shift since the last position during panning\n *\n * @param {Vec2D} gestureCenterPoint\n *\n * @private\n */\n _calcOffsetShiftSinceLastGestureState(gestureCenterPoint: Vec2D) {\n const { movementSensibility } = this.props;\n\n let shift = null;\n\n if (this.lastGestureCenterPosition && movementSensibility) {\n const dx = gestureCenterPoint.x - this.lastGestureCenterPosition.x;\n const dy = gestureCenterPoint.y - this.lastGestureCenterPosition.y;\n\n const shiftX = dx / this.zoomLevel / movementSensibility;\n const shiftY = dy / this.zoomLevel / movementSensibility;\n\n shift = {\n x: shiftX,\n y: shiftY,\n };\n }\n\n this.lastGestureCenterPosition = gestureCenterPoint;\n\n return shift;\n }\n\n /**\n * Handles movement by tap and move\n *\n * @param gestureState\n *\n * @private\n */\n _handleShifting(gestureState: PanResponderGestureState) {\n // Skips shifting if panEnabled is false or disablePanOnInitialZoom is true and we're on the initial zoom level\n if (\n !this.props.panEnabled ||\n (this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom)\n ) {\n return;\n }\n const shift = this._calcOffsetShiftSinceLastGestureState({\n x: gestureState.moveX,\n y: gestureState.moveY,\n });\n if (!shift) return;\n\n const offsetX = this.offsetX + shift.x;\n const offsetY = this.offsetY + shift.y;\n\n if (\n this.props.debug &&\n this.state.originalPageX &&\n this.state.originalPageY\n ) {\n const x = gestureState.moveX - this.state.originalPageX;\n const y = gestureState.moveY - this.state.originalPageY;\n this.setState({ debugPoints: [{ x, y }] });\n }\n\n this._setNewOffsetPosition(offsetX, offsetY);\n\n this.raisePin();\n }\n\n /**\n * Set the state to offset moved\n *\n * @param {number} newOffsetX\n * @param {number} newOffsetY\n * @returns\n */\n _setNewOffsetPosition(newOffsetX: number, newOffsetY: number) {\n const { onShiftingBefore, onShiftingAfter } = this.props;\n\n if (onShiftingBefore?.(null, null, this._getZoomableViewEventObject())) {\n return;\n }\n\n this.offsetX = newOffsetX;\n this.offsetY = newOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n onShiftingAfter?.(null, null, this._getZoomableViewEventObject());\n }\n\n /**\n * Check whether the press event is double tap\n * or single tap and handle the event accordingly\n *\n * @param e\n *\n * @private\n */\n private _resolveAndHandleTap = (e: GestureResponderEvent) => {\n const now = Date.now();\n if (\n this.doubleTapFirstTapReleaseTimestamp &&\n this.props.doubleTapDelay &&\n now - this.doubleTapFirstTapReleaseTimestamp < this.props.doubleTapDelay\n ) {\n this.doubleTapFirstTap &&\n this._addTouch({\n ...this.doubleTapFirstTap,\n id: now.toString(),\n isSecondTap: true,\n });\n this.singleTapTimeoutId && clearTimeout(this.singleTapTimeoutId);\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n delete this.doubleTapFirstTap;\n this._handleDoubleTap(e);\n } else {\n this.doubleTapFirstTapReleaseTimestamp = now;\n this.doubleTapFirstTap = {\n id: now.toString(),\n x: e.nativeEvent.pageX - this.state.originalPageX,\n y: e.nativeEvent.pageY - this.state.originalPageY,\n };\n this._addTouch(this.doubleTapFirstTap);\n\n // persist event so e.nativeEvent is preserved after a timeout delay\n e.persist();\n this.singleTapTimeoutId = setTimeout(() => {\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n\n // Pan to the tapped location\n if (this.props.staticPinPosition && this.doubleTapFirstTap) {\n const tapX =\n this.props.staticPinPosition.x - this.doubleTapFirstTap.x;\n const tapY =\n this.props.staticPinPosition.y - this.doubleTapFirstTap.y;\n\n Animated.timing(this.panAnim, {\n toValue: {\n x: this.offsetX + tapX / this.zoomLevel,\n y: this.offsetY + tapY / this.zoomLevel,\n },\n useNativeDriver: true,\n duration: 200,\n }).start(() => {\n this._updateStaticPin();\n });\n }\n\n this.props.onSingleTap?.(e, this._getZoomableViewEventObject());\n }, this.props.doubleTapDelay);\n }\n };\n\n moveStaticPinTo = (position: Vec2D, duration?: number) => {\n const { originalWidth, originalHeight } = this.state;\n const { staticPinPosition, contentWidth, contentHeight } = this.props;\n\n if (!staticPinPosition) return;\n if (!originalWidth || !originalHeight) return;\n if (!contentWidth || !contentHeight) return;\n\n // Offset for the static pin\n const pinX = staticPinPosition.x - originalWidth / 2;\n const pinY = staticPinPosition.y - originalHeight / 2;\n\n this.offsetX = contentWidth / 2 - position.x + pinX / this.zoomLevel;\n this.offsetY = contentHeight / 2 - position.y + pinY / this.zoomLevel;\n\n if (duration) {\n Animated.timing(this.panAnim, {\n toValue: { x: this.offsetX, y: this.offsetY },\n useNativeDriver: true,\n duration,\n }).start();\n } else {\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n }\n };\n\n private _staticPinPosition = () => {\n if (!this.props.staticPinPosition) return;\n if (!this.props.contentWidth || !this.props.contentHeight) return;\n\n return viewportPositionToImagePosition({\n viewportPosition: {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n },\n imageSize: {\n height: this.props.contentHeight,\n width: this.props.contentWidth,\n },\n zoomableEvent: {\n ...this._getZoomableViewEventObject(),\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n zoomLevel: this.zoomLevel,\n },\n });\n };\n\n private _updateStaticPin = () => {\n const position = this._staticPinPosition();\n if (!position) return;\n this.props.onStaticPinPositionChange?.(position);\n };\n\n private _addTouch(touch: TouchPoint) {\n this.touches.push(touch);\n this.setState({ touches: [...this.touches] });\n }\n\n private _removeTouch(touch: TouchPoint) {\n this.touches.splice(this.touches.indexOf(touch), 1);\n this.setState({ touches: [...this.touches] });\n }\n\n /**\n * Handles the double tap event\n *\n * @param e\n *\n * @private\n */\n _handleDoubleTap(e: GestureResponderEvent) {\n const { onDoubleTapBefore, onDoubleTapAfter, doubleTapZoomToCenter } =\n this.props;\n\n onDoubleTapBefore?.(e, this._getZoomableViewEventObject());\n\n const nextZoomStep = this._getNextZoomStep();\n if (nextZoomStep == null) return;\n\n const { originalPageX, originalPageY } = this.state;\n\n // define new zoom position coordinates\n const zoomPositionCoordinates = {\n x: e.nativeEvent.pageX - originalPageX,\n y: e.nativeEvent.pageY - originalPageY,\n };\n\n // if doubleTapZoomToCenter enabled -> always zoom to center instead\n if (doubleTapZoomToCenter) {\n zoomPositionCoordinates.x = 0;\n zoomPositionCoordinates.y = 0;\n }\n\n this.zoomTo(nextZoomStep, zoomPositionCoordinates);\n\n onDoubleTapAfter?.(\n e,\n this._getZoomableViewEventObject({ zoomLevel: nextZoomStep })\n );\n }\n\n /**\n * Returns the next zoom step based on current step and zoomStep property.\n * If we are zoomed all the way in -> return to initialzoom\n *\n * @returns {*}\n */\n _getNextZoomStep() {\n const { zoomStep, maxZoom, initialZoom } = this.props;\n const { zoomLevel } = this;\n\n if (maxZoom == null) return;\n\n if (zoomLevel.toFixed(2) === maxZoom.toFixed(2)) {\n return initialZoom;\n }\n\n if (zoomStep == null) return;\n\n const nextZoomStep = zoomLevel * (1 + zoomStep);\n if (nextZoomStep > maxZoom) {\n return maxZoom;\n }\n\n return nextZoomStep;\n }\n\n /**\n * Zooms to a specific level. A \"zoom center\" can be provided, which specifies\n * the point that will remain in the same position on the screen after the zoom.\n * The coordinates of the zoom center is relative to the zoom subject.\n * { x: 0, y: 0 } is the very center of the zoom subject.\n *\n * @param newZoomLevel\n * @param zoomCenter - If not supplied, the container's center is the zoom center\n */\n zoomTo(newZoomLevel: number, zoomCenter?: Vec2D) {\n if (!this.props.zoomEnabled) return false;\n if (this.props.maxZoom && newZoomLevel > this.props.maxZoom) return false;\n if (this.props.minZoom && newZoomLevel < this.props.minZoom) return false;\n\n this.props.onZoomBefore?.(null, null, this._getZoomableViewEventObject());\n\n // == Perform Pan Animation to preserve the zoom center while zooming ==\n let listenerId: string | undefined;\n if (zoomCenter) {\n // Calculates panAnim values based on changes in zoomAnim.\n let prevScale = this.zoomLevel;\n // Since zoomAnim is calculated in native driver,\n // it will jitter panAnim once in a while,\n // because here panAnim is being calculated in js.\n // However the jittering should mostly occur in simulator.\n listenerId = this.zoomAnim.addListener(({ value: newScale }) => {\n this.panAnim.setValue({\n x: calcNewScaledOffsetForZoomCentering(\n this.offsetX,\n this.state.originalWidth,\n prevScale,\n newScale,\n zoomCenter.x\n ),\n y: calcNewScaledOffsetForZoomCentering(\n this.offsetY,\n this.state.originalHeight,\n prevScale,\n newScale,\n zoomCenter.y\n ),\n });\n prevScale = newScale;\n });\n }\n\n // == Perform Zoom Animation ==\n getZoomToAnimation(this.zoomAnim, newZoomLevel).start(() => {\n if (!listenerId) return;\n this.zoomAnim.removeListener(listenerId);\n });\n // == Zoom Animation Ends ==\n\n this.props.onZoomAfter?.(null, null, this._getZoomableViewEventObject());\n return true;\n }\n\n /**\n * Zooms in or out by a specified change level\n * Use a positive number for `zoomLevelChange` to zoom in\n * Use a negative number for `zoomLevelChange` to zoom out\n *\n * Returns a promise if everything was updated and a boolean, whether it could be updated or if it exceeded the min/max zoom limits.\n *\n * @param {number | null} zoomLevelChange\n *\n * @return {bool}\n */\n zoomBy(zoomLevelChange: number) {\n // if no zoom level Change given -> just use zoom step\n zoomLevelChange ||= this.props.zoomStep || 0;\n return this.zoomTo(this.zoomLevel + zoomLevelChange);\n }\n\n /**\n * Moves the zoomed view to a specified position\n * Returns a promise when finished\n *\n * @param {number} newOffsetX the new position we want to move it to (x-axis)\n * @param {number} newOffsetY the new position we want to move it to (y-axis)\n *\n * @return {bool}\n */\n moveTo(newOffsetX: number, newOffsetY: number) {\n const { originalWidth, originalHeight } = this.state;\n if (!originalWidth || !originalHeight) return;\n\n const offsetX = (newOffsetX - originalWidth / 2) / this.zoomLevel;\n const offsetY = (newOffsetY - originalHeight / 2) / this.zoomLevel;\n\n this._setNewOffsetPosition(-offsetX, -offsetY);\n }\n\n /**\n * Moves the zoomed view by a certain amount.\n *\n * Returns a promise when finished\n *\n * @param {number} offsetChangeX the amount we want to move the offset by (x-axis)\n * @param {number} offsetChangeY the amount we want to move the offset by (y-axis)\n *\n * @return {bool}\n */\n moveBy(offsetChangeX: number, offsetChangeY: number) {\n const offsetX =\n (this.offsetX * this.zoomLevel - offsetChangeX) / this.zoomLevel;\n const offsetY =\n (this.offsetY * this.zoomLevel - offsetChangeY) / this.zoomLevel;\n\n this._setNewOffsetPosition(offsetX, offsetY);\n }\n\n render() {\n const {\n staticPinIcon,\n children,\n visualTouchFeedbackEnabled,\n doubleTapDelay,\n staticPinPosition,\n onStaticPinLongPress,\n onStaticPinPress,\n pinProps,\n } = this.props;\n const { pinSize, touches, debugPoints = [] } = this.state;\n\n return (\n {\n this.props.onLayout?.(event);\n this.grabZoomSubjectOriginalMeasurements();\n }}\n >\n \n {children}\n \n\n {visualTouchFeedbackEnabled &&\n touches?.map(\n (touch) =>\n doubleTapDelay && (\n {\n this._removeTouch(touch);\n }}\n />\n )\n )}\n\n {/* For Debugging Only */}\n {debugPoints.map(({ x, y }, index) => {\n return ;\n })}\n\n {staticPinPosition && (\n {\n this.setState({ pinSize: size });\n }}\n pinProps={pinProps}\n />\n )}\n \n );\n }\n}\n\nconst styles = StyleSheet.create({\n container: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n overflow: 'hidden',\n position: 'relative',\n },\n zoomSubject: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n width: '100%',\n },\n});\n\nexport default ReactNativeZoomableView;\n\nexport { ReactNativeZoomableView };\n"]} \ No newline at end of file +{"version":3,"sources":["ReactNativeZoomableView.tsx"],"names":["initialState","originalWidth","originalHeight","originalPageX","originalPageY","pinSize","width","height","ReactNativeZoomableView","Component","gestureStarted","v","_gestureStarted","constructor","props","Animated","ValueXY","x","y","Value","value","boundaryCrossedAnimInEffect","position","onStaticPinPositionChange","requestAnimationFrame","setTimeout","zoomSubjectWrapperRef","current","measureInWindow","state","setState","e","gestureState","onStartShouldSetPanResponder","_getZoomableViewEventObject","onLongPress","longPressTimeout","longPressDuration","onPanResponderGrant","panAnim","stopAnimation","zoomAnim","raisePin","gestureType","_resolveAndHandleTap","debugPoints","lastGestureCenterPosition","disableMomentum","panEnabled","disablePanOnInitialZoom","zoomLevel","initialZoom","vx","vy","start","clearTimeout","onPanResponderEnd","onZoomEnd","onShiftingEnd","staticPinPosition","_updateStaticPin","dropPin","onPanResponderMove","numberActiveTouches","_handlePanResponderGrant","_handlePanResponderEnd","lastGestureTouchDistance","_handlePinching","Math","abs","dx","dy","isShiftGesture","_handleShifting","now","Date","doubleTapFirstTapReleaseTimestamp","doubleTapDelay","doubleTapFirstTap","_addTouch","id","toString","isSecondTap","singleTapTimeoutId","_handleDoubleTap","nativeEvent","pageX","pageY","persist","tapX","tapY","timing","toValue","offsetX","offsetY","useNativeDriver","duration","onSingleTap","contentWidth","contentHeight","pinX","pinY","setValue","viewportPosition","imageSize","zoomableEvent","_staticPinPosition","gestureHandlers","PanResponder","create","_handleStartShouldSetPanResponder","_handlePanResponderMove","onPanResponderRelease","onPanResponderTerminate","evt","onPanResponderTerminationRequest","onShouldBlockNativeResponder","onStartShouldSetPanResponderCapture","onMoveShouldSetPanResponderCapture","zoomAnimatedValue","panAnimatedValueXY","initialOffsetX","initialOffsetY","addListener","animatePin","pinAnim","easing","Easing","out","ease","__setOffset","__getOffset","axis","offset","offsetState","__offsets","bindToBorders","containerSize","contentSize","boundOffset","panBoundaryPadding","boundariesApplied","toFixed","componentDidUpdate","prevProps","prevState","zoomEnabled","onTransformInvocationInitialized","_invokeOnTransform","successful","currState","originalMeasurementsChanged","staticPinPositionChanged","componentDidMount","grabZoomSubjectOriginalMeasurements","measureZoomSubjectInterval","setInterval","componentWillUnmount","clearInterval","zoomableViewEvent","onTransform","onStaticPinPositionMove","debouncedOnStaticPinPositionChange","overwriteObj","maxZoom","minZoom","pinchToZoomInSensitivity","pinchToZoomOutSensitivity","distance","onZoomBefore","zoomGrowthFromLastGestureState","pinchToZoomSensitivity","deltaGrowth","deltaGrowthAdjustedBySensitivity","newZoomLevel","gestureCenterPoint","zoomCenter","debug","_setPinchDebugPoints","oldOffsetX","oldOffsetY","oldScale","newScale","offsetShift","_calcOffsetShiftSinceLastGestureState","onZoomAfter","gestureResponderEvent","points","touches","movementSensibility","shift","shiftX","shiftY","moveX","moveY","_setNewOffsetPosition","newOffsetX","newOffsetY","onShiftingBefore","onShiftingAfter","touch","push","_removeTouch","splice","indexOf","onDoubleTapBefore","onDoubleTapAfter","doubleTapZoomToCenter","nextZoomStep","_getNextZoomStep","zoomPositionCoordinates","zoomTo","zoomStep","listenerId","prevScale","removeListener","zoomBy","zoomLevelChange","moveTo","moveBy","offsetChangeX","offsetChangeY","render","staticPinIcon","children","visualTouchFeedbackEnabled","onStaticPinLongPress","onStaticPinPress","pinProps","styles","container","panHandlers","event","onLayout","zoomSubject","style","transform","scale","getTranslateTransform","map","index","size","undefined","StyleSheet","alignItems","flex","justifyContent","overflow"],"mappings":"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","sourcesContent":["import React, { Component, createRef, RefObject } from 'react';\nimport {\n Animated,\n Easing,\n GestureResponderEvent,\n PanResponder,\n PanResponderCallbacks,\n PanResponderGestureState,\n PanResponderInstance,\n StyleSheet,\n View,\n} from 'react-native';\n\nimport {\n Vec2D,\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState,\n TouchPoint,\n ZoomableViewEvent,\n Size2D,\n} from './typings';\n\nimport { AnimatedTouchFeedback } from './components';\nimport { DebugTouchPoint } from './debugHelper';\nimport {\n calcGestureCenterPoint,\n calcGestureTouchDistance,\n calcNewScaledOffsetForZoomCentering,\n} from './helper';\nimport { applyPanBoundariesToOffset } from './helper/applyPanBoundariesToOffset';\nimport { viewportPositionToImagePosition } from './helper/coordinateConversion';\nimport { StaticPin } from './components/StaticPin';\nimport { debounce } from 'lodash';\nimport {\n getBoundaryCrossedAnim,\n getPanMomentumDecayAnim,\n getZoomToAnimation,\n} from './animations';\n\nconst initialState: ReactNativeZoomableViewState = {\n originalWidth: 0,\n originalHeight: 0,\n originalPageX: 0,\n originalPageY: 0,\n pinSize: { width: 0, height: 0 },\n};\n\nclass ReactNativeZoomableView extends Component<\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState\n> {\n zoomSubjectWrapperRef: RefObject;\n gestureHandlers: PanResponderInstance;\n doubleTapFirstTapReleaseTimestamp: number | undefined;\n\n static defaultProps = {\n zoomEnabled: true,\n panEnabled: true,\n initialZoom: 1,\n initialOffsetX: 0,\n initialOffsetY: 0,\n maxZoom: 1.5,\n minZoom: 0.5,\n pinchToZoomInSensitivity: 1,\n pinchToZoomOutSensitivity: 1,\n movementSensibility: 1,\n doubleTapDelay: 300,\n bindToBorders: true,\n zoomStep: 0.5,\n onLongPress: null,\n longPressDuration: 700,\n contentWidth: undefined,\n contentHeight: undefined,\n panBoundaryPadding: 0,\n visualTouchFeedbackEnabled: true,\n staticPinPosition: undefined,\n staticPinIcon: undefined,\n onStaticPinPositionChange: undefined,\n onStaticPinPositionMove: undefined,\n animatePin: true,\n disablePanOnInitialZoom: false,\n };\n\n private panAnim = new Animated.ValueXY({ x: 0, y: 0 });\n private zoomAnim = new Animated.Value(1);\n private pinAnim = new Animated.ValueXY({ x: 0, y: 0 });\n\n private __offsets = {\n x: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n y: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n };\n\n private zoomLevel = 1;\n private lastGestureCenterPosition: { x: number; y: number } | null = null;\n private lastGestureTouchDistance: number | null = null;\n private gestureType: 'pinch' | 'shift' | null;\n\n private _gestureStarted = false;\n private set gestureStarted(v: boolean) {\n this._gestureStarted = v;\n }\n\n public get gestureStarted() {\n return this._gestureStarted;\n }\n\n /**\n * Last press time (used to evaluate whether user double tapped)\n * @type {number}\n */\n private longPressTimeout: NodeJS.Timeout | null = null;\n private onTransformInvocationInitialized: boolean | undefined;\n private singleTapTimeoutId: NodeJS.Timeout | undefined;\n private touches: TouchPoint[] = [];\n private doubleTapFirstTap: TouchPoint | undefined;\n private measureZoomSubjectInterval: NodeJS.Timer | undefined;\n\n constructor(props: ReactNativeZoomableViewProps) {\n super(props);\n // This needs to be done before anything else to initialize the state.\n // Otherwise, the logic below may reference the state when it's undefined,\n // causing runtime errors.\n this.state = { ...initialState };\n\n this.gestureHandlers = PanResponder.create({\n onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,\n onPanResponderGrant: this._handlePanResponderGrant,\n onPanResponderMove: this._handlePanResponderMove,\n onPanResponderRelease: this._handlePanResponderEnd,\n onPanResponderTerminate: (evt, gestureState) => {\n // We should also call _handlePanResponderEnd\n // to properly perform cleanups when the gesture is terminated\n // (aka gesture handling responsibility is taken over by another component).\n // This also fixes a weird issue where\n // on real device, sometimes onPanResponderRelease is not called when you lift 2 fingers up,\n // but onPanResponderTerminate is called instead for no apparent reason.\n this._handlePanResponderEnd(evt, gestureState);\n this.props.onPanResponderTerminate?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n );\n },\n onPanResponderTerminationRequest: (evt, gestureState) =>\n !!this.props.onPanResponderTerminationRequest?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ),\n // Defaults to true to prevent parent components, such as React Navigation's tab view, from taking over as responder.\n onShouldBlockNativeResponder: (evt, gestureState) =>\n this.props.onShouldBlockNativeResponder?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ) ?? true,\n onStartShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onStartShouldSetPanResponderCapture?.(evt, gestureState),\n onMoveShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onMoveShouldSetPanResponderCapture?.(evt, gestureState),\n });\n\n this.zoomSubjectWrapperRef = createRef();\n\n if (this.props.zoomAnimatedValue)\n this.zoomAnim = this.props.zoomAnimatedValue;\n if (this.props.panAnimatedValueXY)\n this.panAnim = this.props.panAnimatedValueXY;\n\n if (this.props.initialZoom) this.zoomLevel = this.props.initialZoom;\n if (this.props.initialOffsetX != null)\n this.offsetX = this.props.initialOffsetX;\n if (this.props.initialOffsetY != null)\n this.offsetY = this.props.initialOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n this.panAnim.addListener(({ x, y }) => {\n this.offsetX = x;\n this.offsetY = y;\n });\n this.zoomAnim.addListener(({ value }) => {\n this.zoomLevel = value;\n });\n\n this.lastGestureTouchDistance = 150;\n\n this.gestureType = null;\n }\n\n private raisePin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: -10 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private dropPin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: 0 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private set offsetX(x: number) {\n this.__setOffset('x', x);\n }\n\n private set offsetY(y: number) {\n this.__setOffset('y', y);\n }\n\n private get offsetX() {\n return this.__getOffset('x');\n }\n\n private get offsetY() {\n return this.__getOffset('y');\n }\n\n private __setOffset(axis: 'x' | 'y', offset: number) {\n const offsetState = this.__offsets[axis];\n\n if (this.props.bindToBorders) {\n const containerSize =\n axis === 'x' ? this.state.originalWidth : this.state.originalHeight;\n const contentSize =\n axis === 'x'\n ? this.props.contentWidth || this.state.originalWidth\n : this.props.contentHeight || this.state.originalHeight;\n\n const boundOffset =\n contentSize && containerSize && this.props.panBoundaryPadding != null\n ? applyPanBoundariesToOffset(\n offset,\n containerSize,\n contentSize,\n this.zoomLevel,\n this.props.panBoundaryPadding\n )\n : offset;\n\n if (!this.gestureType && !offsetState.boundaryCrossedAnimInEffect) {\n const boundariesApplied =\n boundOffset !== offset &&\n boundOffset.toFixed(3) !== offset.toFixed(3);\n if (boundariesApplied) {\n offsetState.boundaryCrossedAnimInEffect = true;\n getBoundaryCrossedAnim(this.panAnim[axis], boundOffset).start(() => {\n offsetState.boundaryCrossedAnimInEffect = false;\n });\n return;\n }\n }\n }\n\n offsetState.value = offset;\n }\n\n private __getOffset(axis: 'x' | 'y') {\n return this.__offsets[axis].value;\n }\n\n componentDidUpdate(\n prevProps: ReactNativeZoomableViewProps,\n prevState: ReactNativeZoomableViewState\n ) {\n const { zoomEnabled, initialZoom } = this.props;\n if (prevProps.zoomEnabled && !zoomEnabled && initialZoom) {\n this.zoomLevel = initialZoom;\n this.zoomAnim.setValue(this.zoomLevel);\n }\n if (\n !this.onTransformInvocationInitialized &&\n this._invokeOnTransform().successful\n ) {\n this.panAnim.addListener(() => this._invokeOnTransform());\n this.zoomAnim.addListener(() => this._invokeOnTransform());\n this.onTransformInvocationInitialized = true;\n }\n\n const currState = this.state;\n const originalMeasurementsChanged =\n currState.originalHeight !== prevState.originalHeight ||\n currState.originalWidth !== prevState.originalWidth ||\n currState.originalPageX !== prevState.originalPageX ||\n currState.originalPageY !== prevState.originalPageY;\n\n const staticPinPositionChanged =\n prevProps.staticPinPosition?.x !== this.props.staticPinPosition?.x ||\n prevProps.staticPinPosition?.y !== this.props.staticPinPosition?.y;\n\n if (\n this.onTransformInvocationInitialized &&\n (originalMeasurementsChanged || staticPinPositionChanged)\n ) {\n this._invokeOnTransform();\n }\n }\n\n componentDidMount() {\n this.grabZoomSubjectOriginalMeasurements();\n // We've already run `grabZoomSubjectOriginalMeasurements` at various events\n // to make sure the measurements are promptly updated.\n // However, there might be cases we haven't accounted for, especially when\n // native processes are involved. To account for those cases,\n // we'll use an interval here to ensure we're always up-to-date.\n // The `setState` in `grabZoomSubjectOriginalMeasurements` won't trigger a rerender\n // if the values given haven't changed, so we're not running performance risk here.\n this.measureZoomSubjectInterval = setInterval(\n this.grabZoomSubjectOriginalMeasurements,\n 1e3\n );\n }\n\n componentWillUnmount() {\n this.measureZoomSubjectInterval &&\n clearInterval(this.measureZoomSubjectInterval);\n }\n\n debouncedOnStaticPinPositionChange = debounce(\n (position: Vec2D) => this.props.onStaticPinPositionChange?.(position),\n 100\n );\n\n /**\n * try to invoke onTransform\n * @private\n */\n _invokeOnTransform() {\n const zoomableViewEvent = this._getZoomableViewEventObject();\n const position = this._staticPinPosition();\n\n if (!zoomableViewEvent.originalWidth || !zoomableViewEvent.originalHeight)\n return { successful: false };\n\n this.props.onTransform?.(zoomableViewEvent);\n\n if (position) {\n this.props.onStaticPinPositionMove?.(position);\n this.debouncedOnStaticPinPositionChange(position);\n }\n\n return { successful: true };\n }\n\n /**\n * Returns additional information about components current state for external event hooks\n *\n * @returns {{}}\n * @private\n */\n _getZoomableViewEventObject(overwriteObj = {}): ZoomableViewEvent {\n return {\n zoomLevel: this.zoomLevel,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n originalHeight: this.state.originalHeight,\n originalWidth: this.state.originalWidth,\n originalPageX: this.state.originalPageX,\n originalPageY: this.state.originalPageY,\n ...overwriteObj,\n } as ZoomableViewEvent;\n }\n\n /**\n * Get the original box dimensions and save them for later use.\n * (They will be used to calculate boxBorders)\n *\n * @private\n */\n private grabZoomSubjectOriginalMeasurements = () => {\n // make sure we measure after animations are complete\n requestAnimationFrame(() => {\n // this setTimeout is here to fix a weird issue on iOS where the measurements are all `0`\n // when navigating back (react-navigation stack) from another view\n // while closing the keyboard at the same time\n setTimeout(() => {\n // In normal conditions, we're supposed to measure zoomSubject instead of its wrapper.\n // However, our zoomSubject may have been transformed by an initial zoomLevel or offset,\n // in which case these measurements will not represent the true \"original\" measurements.\n // We just need to make sure the zoomSubjectWrapper perfectly aligns with the zoomSubject\n // (no border, space, or anything between them)\n const zoomSubjectWrapperRef = this.zoomSubjectWrapperRef;\n // we don't wanna measure when zoomSubjectWrapperRef is not yet available or has been unmounted\n zoomSubjectWrapperRef.current?.measureInWindow(\n (x, y, width, height) => {\n // When the component is off-screen, these become all 0s, so we don't set them\n // to avoid messing up calculations, especially ones that are done right after\n // the component transitions from hidden to visible.\n if (!x && !y && !width && !height) return;\n\n // If these values are all the same, don't re-set them in state\n // this way we don't re-render\n if (\n this.state.originalWidth === width &&\n this.state.originalHeight === height &&\n this.state.originalPageX === x &&\n this.state.originalPageY === y\n ) {\n return;\n }\n\n this.setState({\n originalWidth: width,\n originalHeight: height,\n originalPageX: x,\n originalPageY: y,\n });\n }\n );\n });\n });\n };\n\n /**\n * Handles the start of touch events and checks for taps\n *\n * @param e\n * @param gestureState\n * @returns {boolean}\n *\n * @private\n */\n _handleStartShouldSetPanResponder = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onStartShouldSetPanResponder) {\n this.props.onStartShouldSetPanResponder(\n e,\n gestureState,\n this._getZoomableViewEventObject(),\n false\n );\n }\n\n // Always set pan responder on start\n // of gesture so we can handle tap.\n // \"Pan threshold validation\" will be handled\n // in `onPanResponderMove` instead of in `onMoveShouldSetPanResponder`\n return true;\n };\n\n /**\n * Calculates pinch distance\n *\n * @param e\n * @param gestureState\n * @private\n */\n _handlePanResponderGrant: NonNullable<\n PanResponderCallbacks['onPanResponderGrant']\n > = (e, gestureState) => {\n if (this.props.onLongPress) {\n this.longPressTimeout = setTimeout(() => {\n this.props.onLongPress?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n this.longPressTimeout = null;\n }, this.props.longPressDuration);\n }\n\n this.props.onPanResponderGrant?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n this.panAnim.stopAnimation();\n this.zoomAnim.stopAnimation();\n this.gestureStarted = true;\n\n this.raisePin();\n };\n\n /**\n * Handles the end of touch events\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderEnd: NonNullable<\n PanResponderCallbacks['onPanResponderEnd']\n > = (e, gestureState) => {\n if (!this.gestureType) {\n this._resolveAndHandleTap(e);\n }\n\n this.setState({ debugPoints: [] });\n\n this.lastGestureCenterPosition = null;\n\n const disableMomentum =\n this.props.disableMomentum ||\n (this.props.panEnabled &&\n this.gestureType === 'shift' &&\n this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom);\n\n // Trigger final shift animation unless disablePanOnInitialZoom is set and we're on the initial zoom level\n // or disableMomentum\n if (!disableMomentum) {\n getPanMomentumDecayAnim(this.panAnim, {\n x: gestureState.vx / this.zoomLevel,\n y: gestureState.vy / this.zoomLevel,\n }).start();\n }\n\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n this.props.onPanResponderEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n if (this.gestureType === 'pinch') {\n this.props.onZoomEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n } else if (this.gestureType === 'shift') {\n this.props.onShiftingEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n if (this.props.staticPinPosition) {\n this._updateStaticPin();\n }\n\n this.dropPin();\n\n this.gestureType = null;\n this.gestureStarted = false;\n };\n\n /**\n * Handles the actual movement of our pan responder\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderMove = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onPanResponderMove) {\n if (\n this.props.onPanResponderMove(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return false;\n }\n }\n\n // Only supports 2 touches and below,\n // any invalid number will cause the gesture to end.\n if (gestureState.numberActiveTouches <= 2) {\n if (!this.gestureStarted) {\n this._handlePanResponderGrant(e, gestureState);\n }\n } else {\n if (this.gestureStarted) {\n this._handlePanResponderEnd(e, gestureState);\n }\n return true;\n }\n\n if (gestureState.numberActiveTouches === 2) {\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'pinch') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n this.lastGestureTouchDistance = calcGestureTouchDistance(\n e,\n gestureState\n );\n }\n this.gestureType = 'pinch';\n this._handlePinching(e, gestureState);\n } else if (gestureState.numberActiveTouches === 1) {\n if (\n this.longPressTimeout &&\n (Math.abs(gestureState.dx) > 5 || Math.abs(gestureState.dy) > 5)\n ) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'shift') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n }\n\n const { dx, dy } = gestureState;\n const isShiftGesture = Math.abs(dx) > 2 || Math.abs(dy) > 2;\n if (isShiftGesture) {\n this.gestureType = 'shift';\n this._handleShifting(gestureState);\n }\n }\n };\n\n /**\n * Handles the pinch movement and zooming\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePinching(\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) {\n if (!this.props.zoomEnabled) return;\n\n const {\n maxZoom,\n minZoom,\n pinchToZoomInSensitivity,\n pinchToZoomOutSensitivity,\n } = this.props;\n\n const distance = calcGestureTouchDistance(e, gestureState);\n\n if (\n this.props.onZoomBefore &&\n this.props.onZoomBefore(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return;\n }\n\n if (!distance) return;\n if (!this.lastGestureTouchDistance) return;\n\n // define the new zoom level and take zoom level sensitivity into consideration\n const zoomGrowthFromLastGestureState =\n distance / this.lastGestureTouchDistance;\n this.lastGestureTouchDistance = distance;\n\n const pinchToZoomSensitivity =\n zoomGrowthFromLastGestureState < 1\n ? pinchToZoomOutSensitivity\n : pinchToZoomInSensitivity;\n\n if (pinchToZoomSensitivity == null) return;\n const deltaGrowth = zoomGrowthFromLastGestureState - 1;\n // 0 - no resistance\n // 10 - 90% resistance\n const deltaGrowthAdjustedBySensitivity =\n deltaGrowth * (1 - (pinchToZoomSensitivity * 9) / 100);\n\n let newZoomLevel = this.zoomLevel * (1 + deltaGrowthAdjustedBySensitivity);\n\n // make sure max and min zoom levels are respected\n if (maxZoom != null && newZoomLevel > maxZoom) {\n newZoomLevel = maxZoom;\n }\n\n if (minZoom != null && newZoomLevel < minZoom) {\n newZoomLevel = minZoom;\n }\n\n const gestureCenterPoint = calcGestureCenterPoint(e, gestureState);\n\n if (!gestureCenterPoint) return;\n\n let zoomCenter = {\n x: gestureCenterPoint.x - this.state.originalPageX,\n y: gestureCenterPoint.y - this.state.originalPageY,\n };\n\n if (this.props.staticPinPosition) {\n // When we use a static pin position, the zoom centre is the same as that position,\n // otherwise the pin moves around way too much while zooming.\n zoomCenter = {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n };\n }\n\n // Uncomment to debug\n this.props.debug && this._setPinchDebugPoints(e, zoomCenter);\n\n const { originalHeight, originalWidth } = this.state;\n\n const oldOffsetX = this.offsetX;\n const oldOffsetY = this.offsetY;\n const oldScale = this.zoomLevel;\n const newScale = newZoomLevel;\n\n if (!originalHeight || !originalWidth) return;\n\n let offsetY = calcNewScaledOffsetForZoomCentering(\n oldOffsetY,\n originalHeight,\n oldScale,\n newScale,\n zoomCenter.y\n );\n let offsetX = calcNewScaledOffsetForZoomCentering(\n oldOffsetX,\n originalWidth,\n oldScale,\n newScale,\n zoomCenter.x\n );\n\n const offsetShift =\n this._calcOffsetShiftSinceLastGestureState(gestureCenterPoint);\n if (offsetShift) {\n offsetX += offsetShift.x;\n offsetY += offsetShift.y;\n }\n\n this.offsetX = offsetX;\n this.offsetY = offsetY;\n this.zoomLevel = newScale;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n this.props.onZoomAfter?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n /**\n * Used to debug pinch events\n * @param gestureResponderEvent\n * @param zoomCenter\n * @param points\n */\n _setPinchDebugPoints(\n gestureResponderEvent: GestureResponderEvent,\n zoomCenter: Vec2D,\n ...points: Vec2D[]\n ) {\n const { touches } = gestureResponderEvent.nativeEvent;\n const { originalPageY, originalPageX } = this.state;\n\n this.setState({\n debugPoints: [\n {\n x: touches[0].pageX - originalPageX,\n y: touches[0].pageY - originalPageY,\n },\n {\n x: touches[1].pageX - originalPageX,\n y: touches[1].pageY - originalPageY,\n },\n zoomCenter,\n ...points,\n ],\n });\n }\n\n /**\n * Calculates the amount the offset should shift since the last position during panning\n *\n * @param {Vec2D} gestureCenterPoint\n *\n * @private\n */\n _calcOffsetShiftSinceLastGestureState(gestureCenterPoint: Vec2D) {\n const { movementSensibility } = this.props;\n\n let shift = null;\n\n if (this.lastGestureCenterPosition && movementSensibility) {\n const dx = gestureCenterPoint.x - this.lastGestureCenterPosition.x;\n const dy = gestureCenterPoint.y - this.lastGestureCenterPosition.y;\n\n const shiftX = dx / this.zoomLevel / movementSensibility;\n const shiftY = dy / this.zoomLevel / movementSensibility;\n\n shift = {\n x: shiftX,\n y: shiftY,\n };\n }\n\n this.lastGestureCenterPosition = gestureCenterPoint;\n\n return shift;\n }\n\n /**\n * Handles movement by tap and move\n *\n * @param gestureState\n *\n * @private\n */\n _handleShifting(gestureState: PanResponderGestureState) {\n // Skips shifting if panEnabled is false or disablePanOnInitialZoom is true and we're on the initial zoom level\n if (\n !this.props.panEnabled ||\n (this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom)\n ) {\n return;\n }\n const shift = this._calcOffsetShiftSinceLastGestureState({\n x: gestureState.moveX,\n y: gestureState.moveY,\n });\n if (!shift) return;\n\n const offsetX = this.offsetX + shift.x;\n const offsetY = this.offsetY + shift.y;\n\n if (\n this.props.debug &&\n this.state.originalPageX &&\n this.state.originalPageY\n ) {\n const x = gestureState.moveX - this.state.originalPageX;\n const y = gestureState.moveY - this.state.originalPageY;\n this.setState({ debugPoints: [{ x, y }] });\n }\n\n this._setNewOffsetPosition(offsetX, offsetY);\n\n this.raisePin();\n }\n\n /**\n * Set the state to offset moved\n *\n * @param {number} newOffsetX\n * @param {number} newOffsetY\n * @returns\n */\n _setNewOffsetPosition(newOffsetX: number, newOffsetY: number) {\n const { onShiftingBefore, onShiftingAfter } = this.props;\n\n if (onShiftingBefore?.(null, null, this._getZoomableViewEventObject())) {\n return;\n }\n\n this.offsetX = newOffsetX;\n this.offsetY = newOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n onShiftingAfter?.(null, null, this._getZoomableViewEventObject());\n }\n\n /**\n * Check whether the press event is double tap\n * or single tap and handle the event accordingly\n *\n * @param e\n *\n * @private\n */\n private _resolveAndHandleTap = (e: GestureResponderEvent) => {\n const now = Date.now();\n if (\n this.doubleTapFirstTapReleaseTimestamp &&\n this.props.doubleTapDelay &&\n now - this.doubleTapFirstTapReleaseTimestamp < this.props.doubleTapDelay\n ) {\n this.doubleTapFirstTap &&\n this._addTouch({\n ...this.doubleTapFirstTap,\n id: now.toString(),\n isSecondTap: true,\n });\n this.singleTapTimeoutId && clearTimeout(this.singleTapTimeoutId);\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n delete this.doubleTapFirstTap;\n this._handleDoubleTap(e);\n } else {\n this.doubleTapFirstTapReleaseTimestamp = now;\n this.doubleTapFirstTap = {\n id: now.toString(),\n x: e.nativeEvent.pageX - this.state.originalPageX,\n y: e.nativeEvent.pageY - this.state.originalPageY,\n };\n this._addTouch(this.doubleTapFirstTap);\n\n // persist event so e.nativeEvent is preserved after a timeout delay\n e.persist();\n this.singleTapTimeoutId = setTimeout(() => {\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n\n // Pan to the tapped location\n if (this.props.staticPinPosition && this.doubleTapFirstTap) {\n const tapX =\n this.props.staticPinPosition.x - this.doubleTapFirstTap.x;\n const tapY =\n this.props.staticPinPosition.y - this.doubleTapFirstTap.y;\n\n Animated.timing(this.panAnim, {\n toValue: {\n x: this.offsetX + tapX / this.zoomLevel,\n y: this.offsetY + tapY / this.zoomLevel,\n },\n useNativeDriver: true,\n duration: 200,\n }).start(() => {\n this._updateStaticPin();\n });\n }\n\n this.props.onSingleTap?.(e, this._getZoomableViewEventObject());\n }, this.props.doubleTapDelay);\n }\n };\n\n moveStaticPinTo = (position: Vec2D, duration?: number) => {\n const { originalWidth, originalHeight } = this.state;\n const { staticPinPosition, contentWidth, contentHeight } = this.props;\n\n if (!staticPinPosition) return;\n if (!originalWidth || !originalHeight) return;\n if (!contentWidth || !contentHeight) return;\n\n // Offset for the static pin\n const pinX = staticPinPosition.x - originalWidth / 2;\n const pinY = staticPinPosition.y - originalHeight / 2;\n\n this.offsetX = contentWidth / 2 - position.x + pinX / this.zoomLevel;\n this.offsetY = contentHeight / 2 - position.y + pinY / this.zoomLevel;\n\n if (duration) {\n Animated.timing(this.panAnim, {\n toValue: { x: this.offsetX, y: this.offsetY },\n useNativeDriver: true,\n duration,\n }).start();\n } else {\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n }\n };\n\n private _staticPinPosition = () => {\n if (!this.props.staticPinPosition) return;\n if (!this.props.contentWidth || !this.props.contentHeight) return;\n\n return viewportPositionToImagePosition({\n viewportPosition: {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n },\n imageSize: {\n height: this.props.contentHeight,\n width: this.props.contentWidth,\n },\n zoomableEvent: {\n ...this._getZoomableViewEventObject(),\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n zoomLevel: this.zoomLevel,\n },\n });\n };\n\n private _updateStaticPin = () => {\n const position = this._staticPinPosition();\n if (!position) return;\n this.props.onStaticPinPositionChange?.(position);\n };\n\n private _addTouch(touch: TouchPoint) {\n this.touches.push(touch);\n this.setState({ touches: [...this.touches] });\n }\n\n private _removeTouch(touch: TouchPoint) {\n this.touches.splice(this.touches.indexOf(touch), 1);\n this.setState({ touches: [...this.touches] });\n }\n\n /**\n * Handles the double tap event\n *\n * @param e\n *\n * @private\n */\n _handleDoubleTap(e: GestureResponderEvent) {\n const { onDoubleTapBefore, onDoubleTapAfter, doubleTapZoomToCenter } =\n this.props;\n\n onDoubleTapBefore?.(e, this._getZoomableViewEventObject());\n\n const nextZoomStep = this._getNextZoomStep();\n if (nextZoomStep == null) return;\n\n const { originalPageX, originalPageY } = this.state;\n\n // define new zoom position coordinates\n const zoomPositionCoordinates = {\n x: e.nativeEvent.pageX - originalPageX,\n y: e.nativeEvent.pageY - originalPageY,\n };\n\n // if doubleTapZoomToCenter enabled -> always zoom to center instead\n if (doubleTapZoomToCenter) {\n zoomPositionCoordinates.x = 0;\n zoomPositionCoordinates.y = 0;\n }\n\n this.zoomTo(nextZoomStep, zoomPositionCoordinates);\n\n onDoubleTapAfter?.(\n e,\n this._getZoomableViewEventObject({ zoomLevel: nextZoomStep })\n );\n }\n\n /**\n * Returns the next zoom step based on current step and zoomStep property.\n * If we are zoomed all the way in -> return to initialzoom\n *\n * @returns {*}\n */\n _getNextZoomStep() {\n const { zoomStep, maxZoom, initialZoom } = this.props;\n const { zoomLevel } = this;\n\n if (maxZoom == null) return;\n\n if (zoomLevel.toFixed(2) === maxZoom.toFixed(2)) {\n return initialZoom;\n }\n\n if (zoomStep == null) return;\n\n const nextZoomStep = zoomLevel * (1 + zoomStep);\n if (nextZoomStep > maxZoom) {\n return maxZoom;\n }\n\n return nextZoomStep;\n }\n\n /**\n * Zooms to a specific level. A \"zoom center\" can be provided, which specifies\n * the point that will remain in the same position on the screen after the zoom.\n * The coordinates of the zoom center is relative to the zoom subject.\n * { x: 0, y: 0 } is the very center of the zoom subject.\n *\n * @param newZoomLevel\n * @param zoomCenter - If not supplied, the container's center is the zoom center\n */\n zoomTo(newZoomLevel: number, zoomCenter?: Vec2D) {\n if (!this.props.zoomEnabled) return false;\n if (this.props.maxZoom && newZoomLevel > this.props.maxZoom) return false;\n if (this.props.minZoom && newZoomLevel < this.props.minZoom) return false;\n\n this.props.onZoomBefore?.(null, null, this._getZoomableViewEventObject());\n\n // == Perform Pan Animation to preserve the zoom center while zooming ==\n let listenerId = '';\n if (zoomCenter) {\n // Calculates panAnim values based on changes in zoomAnim.\n let prevScale = this.zoomLevel;\n // Since zoomAnim is calculated in native driver,\n // it will jitter panAnim once in a while,\n // because here panAnim is being calculated in js.\n // However the jittering should mostly occur in simulator.\n listenerId = this.zoomAnim.addListener(({ value: newScale }) => {\n this.panAnim.setValue({\n x: calcNewScaledOffsetForZoomCentering(\n this.offsetX,\n this.state.originalWidth,\n prevScale,\n newScale,\n zoomCenter.x\n ),\n y: calcNewScaledOffsetForZoomCentering(\n this.offsetY,\n this.state.originalHeight,\n prevScale,\n newScale,\n zoomCenter.y\n ),\n });\n prevScale = newScale;\n });\n }\n\n // == Perform Zoom Animation ==\n getZoomToAnimation(this.zoomAnim, newZoomLevel).start(() => {\n this.zoomAnim.removeListener(listenerId);\n });\n // == Zoom Animation Ends ==\n\n this.props.onZoomAfter?.(null, null, this._getZoomableViewEventObject());\n return true;\n }\n\n /**\n * Zooms in or out by a specified change level\n * Use a positive number for `zoomLevelChange` to zoom in\n * Use a negative number for `zoomLevelChange` to zoom out\n *\n * Returns a promise if everything was updated and a boolean, whether it could be updated or if it exceeded the min/max zoom limits.\n *\n * @param {number | null} zoomLevelChange\n *\n * @return {bool}\n */\n zoomBy(zoomLevelChange: number) {\n // if no zoom level Change given -> just use zoom step\n zoomLevelChange ||= this.props.zoomStep || 0;\n return this.zoomTo(this.zoomLevel + zoomLevelChange);\n }\n\n /**\n * Moves the zoomed view to a specified position\n * Returns a promise when finished\n *\n * @param {number} newOffsetX the new position we want to move it to (x-axis)\n * @param {number} newOffsetY the new position we want to move it to (y-axis)\n *\n * @return {bool}\n */\n moveTo(newOffsetX: number, newOffsetY: number) {\n const { originalWidth, originalHeight } = this.state;\n if (!originalWidth || !originalHeight) return;\n\n const offsetX = (newOffsetX - originalWidth / 2) / this.zoomLevel;\n const offsetY = (newOffsetY - originalHeight / 2) / this.zoomLevel;\n\n this._setNewOffsetPosition(-offsetX, -offsetY);\n }\n\n /**\n * Moves the zoomed view by a certain amount.\n *\n * Returns a promise when finished\n *\n * @param {number} offsetChangeX the amount we want to move the offset by (x-axis)\n * @param {number} offsetChangeY the amount we want to move the offset by (y-axis)\n *\n * @return {bool}\n */\n moveBy(offsetChangeX: number, offsetChangeY: number) {\n const offsetX =\n (this.offsetX * this.zoomLevel - offsetChangeX) / this.zoomLevel;\n const offsetY =\n (this.offsetY * this.zoomLevel - offsetChangeY) / this.zoomLevel;\n\n this._setNewOffsetPosition(offsetX, offsetY);\n }\n\n render() {\n const {\n staticPinIcon,\n children,\n visualTouchFeedbackEnabled,\n doubleTapDelay,\n staticPinPosition,\n onStaticPinLongPress,\n onStaticPinPress,\n pinProps,\n } = this.props;\n const { pinSize, touches, debugPoints = [] } = this.state;\n\n return (\n {\n this.props.onLayout?.(event);\n this.grabZoomSubjectOriginalMeasurements();\n }}\n >\n \n {children}\n \n\n {visualTouchFeedbackEnabled &&\n touches?.map(\n (touch) =>\n doubleTapDelay && (\n {\n this._removeTouch(touch);\n }}\n />\n )\n )}\n\n {/* For Debugging Only */}\n {debugPoints.map(({ x, y }, index) => {\n return ;\n })}\n\n {staticPinPosition && (\n {\n this.setState({ pinSize: size });\n }}\n pinProps={pinProps}\n />\n )}\n \n );\n }\n}\n\nconst styles = StyleSheet.create({\n container: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n overflow: 'hidden',\n position: 'relative',\n },\n zoomSubject: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n width: '100%',\n },\n});\n\nexport default ReactNativeZoomableView;\n\nexport { ReactNativeZoomableView };\n"]} \ No newline at end of file diff --git a/lib/module/ReactNativeZoomableView.js b/lib/module/ReactNativeZoomableView.js index d6b7d44..2b8d901 100644 --- a/lib/module/ReactNativeZoomableView.js +++ b/lib/module/ReactNativeZoomableView.js @@ -959,7 +959,7 @@ class ReactNativeZoomableView extends Component { if (this.props.minZoom && newZoomLevel < this.props.minZoom) return false; (_this$props$onZoomBef = (_this$props17 = this.props).onZoomBefore) === null || _this$props$onZoomBef === void 0 ? void 0 : _this$props$onZoomBef.call(_this$props17, null, null, this._getZoomableViewEventObject()); // == Perform Pan Animation to preserve the zoom center while zooming == - let listenerId; + let listenerId = ''; if (zoomCenter) { // Calculates panAnim values based on changes in zoomAnim. @@ -981,7 +981,6 @@ class ReactNativeZoomableView extends Component { getZoomToAnimation(this.zoomAnim, newZoomLevel).start(() => { - if (!listenerId) return; this.zoomAnim.removeListener(listenerId); }); // == Zoom Animation Ends == diff --git a/lib/module/ReactNativeZoomableView.js.map b/lib/module/ReactNativeZoomableView.js.map index c9d79a8..5e40ffd 100644 --- a/lib/module/ReactNativeZoomableView.js.map +++ b/lib/module/ReactNativeZoomableView.js.map @@ -1 +1 @@ -{"version":3,"sources":["ReactNativeZoomableView.tsx"],"names":["React","Component","createRef","Animated","Easing","PanResponder","StyleSheet","View","AnimatedTouchFeedback","DebugTouchPoint","calcGestureCenterPoint","calcGestureTouchDistance","calcNewScaledOffsetForZoomCentering","applyPanBoundariesToOffset","viewportPositionToImagePosition","StaticPin","debounce","getBoundaryCrossedAnim","getPanMomentumDecayAnim","getZoomToAnimation","initialState","originalWidth","originalHeight","originalPageX","originalPageY","pinSize","width","height","ReactNativeZoomableView","gestureStarted","v","_gestureStarted","constructor","props","ValueXY","x","y","Value","value","boundaryCrossedAnimInEffect","position","onStaticPinPositionChange","requestAnimationFrame","setTimeout","zoomSubjectWrapperRef","current","measureInWindow","state","setState","e","gestureState","onStartShouldSetPanResponder","_getZoomableViewEventObject","onLongPress","longPressTimeout","longPressDuration","onPanResponderGrant","panAnim","stopAnimation","zoomAnim","raisePin","gestureType","_resolveAndHandleTap","debugPoints","lastGestureCenterPosition","disableMomentum","panEnabled","disablePanOnInitialZoom","zoomLevel","initialZoom","vx","vy","start","clearTimeout","onPanResponderEnd","onZoomEnd","onShiftingEnd","staticPinPosition","_updateStaticPin","dropPin","onPanResponderMove","numberActiveTouches","_handlePanResponderGrant","_handlePanResponderEnd","lastGestureTouchDistance","_handlePinching","Math","abs","dx","dy","isShiftGesture","_handleShifting","now","Date","doubleTapFirstTapReleaseTimestamp","doubleTapDelay","doubleTapFirstTap","_addTouch","id","toString","isSecondTap","singleTapTimeoutId","_handleDoubleTap","nativeEvent","pageX","pageY","persist","tapX","tapY","timing","toValue","offsetX","offsetY","useNativeDriver","duration","onSingleTap","contentWidth","contentHeight","pinX","pinY","setValue","viewportPosition","imageSize","zoomableEvent","_staticPinPosition","gestureHandlers","create","_handleStartShouldSetPanResponder","_handlePanResponderMove","onPanResponderRelease","onPanResponderTerminate","evt","onPanResponderTerminationRequest","onShouldBlockNativeResponder","onStartShouldSetPanResponderCapture","onMoveShouldSetPanResponderCapture","zoomAnimatedValue","panAnimatedValueXY","initialOffsetX","initialOffsetY","addListener","animatePin","pinAnim","easing","out","ease","__setOffset","__getOffset","axis","offset","offsetState","__offsets","bindToBorders","containerSize","contentSize","boundOffset","panBoundaryPadding","boundariesApplied","toFixed","componentDidUpdate","prevProps","prevState","zoomEnabled","onTransformInvocationInitialized","_invokeOnTransform","successful","currState","originalMeasurementsChanged","staticPinPositionChanged","componentDidMount","grabZoomSubjectOriginalMeasurements","measureZoomSubjectInterval","setInterval","componentWillUnmount","clearInterval","zoomableViewEvent","onTransform","onStaticPinPositionMove","debouncedOnStaticPinPositionChange","overwriteObj","maxZoom","minZoom","pinchToZoomInSensitivity","pinchToZoomOutSensitivity","distance","onZoomBefore","zoomGrowthFromLastGestureState","pinchToZoomSensitivity","deltaGrowth","deltaGrowthAdjustedBySensitivity","newZoomLevel","gestureCenterPoint","zoomCenter","debug","_setPinchDebugPoints","oldOffsetX","oldOffsetY","oldScale","newScale","offsetShift","_calcOffsetShiftSinceLastGestureState","onZoomAfter","gestureResponderEvent","points","touches","movementSensibility","shift","shiftX","shiftY","moveX","moveY","_setNewOffsetPosition","newOffsetX","newOffsetY","onShiftingBefore","onShiftingAfter","touch","push","_removeTouch","splice","indexOf","onDoubleTapBefore","onDoubleTapAfter","doubleTapZoomToCenter","nextZoomStep","_getNextZoomStep","zoomPositionCoordinates","zoomTo","zoomStep","listenerId","prevScale","removeListener","zoomBy","zoomLevelChange","moveTo","moveBy","offsetChangeX","offsetChangeY","render","staticPinIcon","children","visualTouchFeedbackEnabled","onStaticPinLongPress","onStaticPinPress","pinProps","styles","container","panHandlers","event","onLayout","zoomSubject","style","transform","scale","getTranslateTransform","map","index","size","undefined","alignItems","flex","justifyContent","overflow"],"mappings":"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","sourcesContent":["import React, { Component, createRef, RefObject } from 'react';\nimport {\n Animated,\n Easing,\n GestureResponderEvent,\n PanResponder,\n PanResponderCallbacks,\n PanResponderGestureState,\n PanResponderInstance,\n StyleSheet,\n View,\n} from 'react-native';\n\nimport {\n Vec2D,\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState,\n TouchPoint,\n ZoomableViewEvent,\n Size2D,\n} from './typings';\n\nimport { AnimatedTouchFeedback } from './components';\nimport { DebugTouchPoint } from './debugHelper';\nimport {\n calcGestureCenterPoint,\n calcGestureTouchDistance,\n calcNewScaledOffsetForZoomCentering,\n} from './helper';\nimport { applyPanBoundariesToOffset } from './helper/applyPanBoundariesToOffset';\nimport { viewportPositionToImagePosition } from './helper/coordinateConversion';\nimport { StaticPin } from './components/StaticPin';\nimport { debounce } from 'lodash';\nimport {\n getBoundaryCrossedAnim,\n getPanMomentumDecayAnim,\n getZoomToAnimation,\n} from './animations';\n\nconst initialState: ReactNativeZoomableViewState = {\n originalWidth: 0,\n originalHeight: 0,\n originalPageX: 0,\n originalPageY: 0,\n pinSize: { width: 0, height: 0 },\n};\n\nclass ReactNativeZoomableView extends Component<\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState\n> {\n zoomSubjectWrapperRef: RefObject;\n gestureHandlers: PanResponderInstance;\n doubleTapFirstTapReleaseTimestamp: number | undefined;\n\n static defaultProps = {\n zoomEnabled: true,\n panEnabled: true,\n initialZoom: 1,\n initialOffsetX: 0,\n initialOffsetY: 0,\n maxZoom: 1.5,\n minZoom: 0.5,\n pinchToZoomInSensitivity: 1,\n pinchToZoomOutSensitivity: 1,\n movementSensibility: 1,\n doubleTapDelay: 300,\n bindToBorders: true,\n zoomStep: 0.5,\n onLongPress: null,\n longPressDuration: 700,\n contentWidth: undefined,\n contentHeight: undefined,\n panBoundaryPadding: 0,\n visualTouchFeedbackEnabled: true,\n staticPinPosition: undefined,\n staticPinIcon: undefined,\n onStaticPinPositionChange: undefined,\n onStaticPinPositionMove: undefined,\n animatePin: true,\n disablePanOnInitialZoom: false,\n };\n\n private panAnim = new Animated.ValueXY({ x: 0, y: 0 });\n private zoomAnim = new Animated.Value(1);\n private pinAnim = new Animated.ValueXY({ x: 0, y: 0 });\n\n private __offsets = {\n x: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n y: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n };\n\n private zoomLevel = 1;\n private lastGestureCenterPosition: { x: number; y: number } | null = null;\n private lastGestureTouchDistance: number | null = null;\n private gestureType: 'pinch' | 'shift' | null;\n\n private _gestureStarted = false;\n private set gestureStarted(v: boolean) {\n this._gestureStarted = v;\n }\n\n public get gestureStarted() {\n return this._gestureStarted;\n }\n\n /**\n * Last press time (used to evaluate whether user double tapped)\n * @type {number}\n */\n private longPressTimeout: NodeJS.Timeout | null = null;\n private onTransformInvocationInitialized: boolean | undefined;\n private singleTapTimeoutId: NodeJS.Timeout | undefined;\n private touches: TouchPoint[] = [];\n private doubleTapFirstTap: TouchPoint | undefined;\n private measureZoomSubjectInterval: NodeJS.Timer | undefined;\n\n constructor(props: ReactNativeZoomableViewProps) {\n super(props);\n // This needs to be done before anything else to initialize the state.\n // Otherwise, the logic below may reference the state when it's undefined,\n // causing runtime errors.\n this.state = { ...initialState };\n\n this.gestureHandlers = PanResponder.create({\n onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,\n onPanResponderGrant: this._handlePanResponderGrant,\n onPanResponderMove: this._handlePanResponderMove,\n onPanResponderRelease: this._handlePanResponderEnd,\n onPanResponderTerminate: (evt, gestureState) => {\n // We should also call _handlePanResponderEnd\n // to properly perform cleanups when the gesture is terminated\n // (aka gesture handling responsibility is taken over by another component).\n // This also fixes a weird issue where\n // on real device, sometimes onPanResponderRelease is not called when you lift 2 fingers up,\n // but onPanResponderTerminate is called instead for no apparent reason.\n this._handlePanResponderEnd(evt, gestureState);\n this.props.onPanResponderTerminate?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n );\n },\n onPanResponderTerminationRequest: (evt, gestureState) =>\n !!this.props.onPanResponderTerminationRequest?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ),\n // Defaults to true to prevent parent components, such as React Navigation's tab view, from taking over as responder.\n onShouldBlockNativeResponder: (evt, gestureState) =>\n this.props.onShouldBlockNativeResponder?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ) ?? true,\n onStartShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onStartShouldSetPanResponderCapture?.(evt, gestureState),\n onMoveShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onMoveShouldSetPanResponderCapture?.(evt, gestureState),\n });\n\n this.zoomSubjectWrapperRef = createRef();\n\n if (this.props.zoomAnimatedValue)\n this.zoomAnim = this.props.zoomAnimatedValue;\n if (this.props.panAnimatedValueXY)\n this.panAnim = this.props.panAnimatedValueXY;\n\n if (this.props.initialZoom) this.zoomLevel = this.props.initialZoom;\n if (this.props.initialOffsetX != null)\n this.offsetX = this.props.initialOffsetX;\n if (this.props.initialOffsetY != null)\n this.offsetY = this.props.initialOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n this.panAnim.addListener(({ x, y }) => {\n this.offsetX = x;\n this.offsetY = y;\n });\n this.zoomAnim.addListener(({ value }) => {\n this.zoomLevel = value;\n });\n\n this.lastGestureTouchDistance = 150;\n\n this.gestureType = null;\n }\n\n private raisePin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: -10 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private dropPin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: 0 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private set offsetX(x: number) {\n this.__setOffset('x', x);\n }\n\n private set offsetY(y: number) {\n this.__setOffset('y', y);\n }\n\n private get offsetX() {\n return this.__getOffset('x');\n }\n\n private get offsetY() {\n return this.__getOffset('y');\n }\n\n private __setOffset(axis: 'x' | 'y', offset: number) {\n const offsetState = this.__offsets[axis];\n\n if (this.props.bindToBorders) {\n const containerSize =\n axis === 'x' ? this.state.originalWidth : this.state.originalHeight;\n const contentSize =\n axis === 'x'\n ? this.props.contentWidth || this.state.originalWidth\n : this.props.contentHeight || this.state.originalHeight;\n\n const boundOffset =\n contentSize && containerSize && this.props.panBoundaryPadding != null\n ? applyPanBoundariesToOffset(\n offset,\n containerSize,\n contentSize,\n this.zoomLevel,\n this.props.panBoundaryPadding\n )\n : offset;\n\n if (!this.gestureType && !offsetState.boundaryCrossedAnimInEffect) {\n const boundariesApplied =\n boundOffset !== offset &&\n boundOffset.toFixed(3) !== offset.toFixed(3);\n if (boundariesApplied) {\n offsetState.boundaryCrossedAnimInEffect = true;\n getBoundaryCrossedAnim(this.panAnim[axis], boundOffset).start(() => {\n offsetState.boundaryCrossedAnimInEffect = false;\n });\n return;\n }\n }\n }\n\n offsetState.value = offset;\n }\n\n private __getOffset(axis: 'x' | 'y') {\n return this.__offsets[axis].value;\n }\n\n componentDidUpdate(\n prevProps: ReactNativeZoomableViewProps,\n prevState: ReactNativeZoomableViewState\n ) {\n const { zoomEnabled, initialZoom } = this.props;\n if (prevProps.zoomEnabled && !zoomEnabled && initialZoom) {\n this.zoomLevel = initialZoom;\n this.zoomAnim.setValue(this.zoomLevel);\n }\n if (\n !this.onTransformInvocationInitialized &&\n this._invokeOnTransform().successful\n ) {\n this.panAnim.addListener(() => this._invokeOnTransform());\n this.zoomAnim.addListener(() => this._invokeOnTransform());\n this.onTransformInvocationInitialized = true;\n }\n\n const currState = this.state;\n const originalMeasurementsChanged =\n currState.originalHeight !== prevState.originalHeight ||\n currState.originalWidth !== prevState.originalWidth ||\n currState.originalPageX !== prevState.originalPageX ||\n currState.originalPageY !== prevState.originalPageY;\n\n const staticPinPositionChanged =\n prevProps.staticPinPosition?.x !== this.props.staticPinPosition?.x ||\n prevProps.staticPinPosition?.y !== this.props.staticPinPosition?.y;\n\n if (\n this.onTransformInvocationInitialized &&\n (originalMeasurementsChanged || staticPinPositionChanged)\n ) {\n this._invokeOnTransform();\n }\n }\n\n componentDidMount() {\n this.grabZoomSubjectOriginalMeasurements();\n // We've already run `grabZoomSubjectOriginalMeasurements` at various events\n // to make sure the measurements are promptly updated.\n // However, there might be cases we haven't accounted for, especially when\n // native processes are involved. To account for those cases,\n // we'll use an interval here to ensure we're always up-to-date.\n // The `setState` in `grabZoomSubjectOriginalMeasurements` won't trigger a rerender\n // if the values given haven't changed, so we're not running performance risk here.\n this.measureZoomSubjectInterval = setInterval(\n this.grabZoomSubjectOriginalMeasurements,\n 1e3\n );\n }\n\n componentWillUnmount() {\n this.measureZoomSubjectInterval &&\n clearInterval(this.measureZoomSubjectInterval);\n }\n\n debouncedOnStaticPinPositionChange = debounce(\n (position: Vec2D) => this.props.onStaticPinPositionChange?.(position),\n 100\n );\n\n /**\n * try to invoke onTransform\n * @private\n */\n _invokeOnTransform() {\n const zoomableViewEvent = this._getZoomableViewEventObject();\n const position = this._staticPinPosition();\n\n if (!zoomableViewEvent.originalWidth || !zoomableViewEvent.originalHeight)\n return { successful: false };\n\n this.props.onTransform?.(zoomableViewEvent);\n\n if (position) {\n this.props.onStaticPinPositionMove?.(position);\n this.debouncedOnStaticPinPositionChange(position);\n }\n\n return { successful: true };\n }\n\n /**\n * Returns additional information about components current state for external event hooks\n *\n * @returns {{}}\n * @private\n */\n _getZoomableViewEventObject(overwriteObj = {}): ZoomableViewEvent {\n return {\n zoomLevel: this.zoomLevel,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n originalHeight: this.state.originalHeight,\n originalWidth: this.state.originalWidth,\n originalPageX: this.state.originalPageX,\n originalPageY: this.state.originalPageY,\n ...overwriteObj,\n } as ZoomableViewEvent;\n }\n\n /**\n * Get the original box dimensions and save them for later use.\n * (They will be used to calculate boxBorders)\n *\n * @private\n */\n private grabZoomSubjectOriginalMeasurements = () => {\n // make sure we measure after animations are complete\n requestAnimationFrame(() => {\n // this setTimeout is here to fix a weird issue on iOS where the measurements are all `0`\n // when navigating back (react-navigation stack) from another view\n // while closing the keyboard at the same time\n setTimeout(() => {\n // In normal conditions, we're supposed to measure zoomSubject instead of its wrapper.\n // However, our zoomSubject may have been transformed by an initial zoomLevel or offset,\n // in which case these measurements will not represent the true \"original\" measurements.\n // We just need to make sure the zoomSubjectWrapper perfectly aligns with the zoomSubject\n // (no border, space, or anything between them)\n const zoomSubjectWrapperRef = this.zoomSubjectWrapperRef;\n // we don't wanna measure when zoomSubjectWrapperRef is not yet available or has been unmounted\n zoomSubjectWrapperRef.current?.measureInWindow(\n (x, y, width, height) => {\n // When the component is off-screen, these become all 0s, so we don't set them\n // to avoid messing up calculations, especially ones that are done right after\n // the component transitions from hidden to visible.\n if (!x && !y && !width && !height) return;\n\n // If these values are all the same, don't re-set them in state\n // this way we don't re-render\n if (\n this.state.originalWidth === width &&\n this.state.originalHeight === height &&\n this.state.originalPageX === x &&\n this.state.originalPageY === y\n ) {\n return;\n }\n\n this.setState({\n originalWidth: width,\n originalHeight: height,\n originalPageX: x,\n originalPageY: y,\n });\n }\n );\n });\n });\n };\n\n /**\n * Handles the start of touch events and checks for taps\n *\n * @param e\n * @param gestureState\n * @returns {boolean}\n *\n * @private\n */\n _handleStartShouldSetPanResponder = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onStartShouldSetPanResponder) {\n this.props.onStartShouldSetPanResponder(\n e,\n gestureState,\n this._getZoomableViewEventObject(),\n false\n );\n }\n\n // Always set pan responder on start\n // of gesture so we can handle tap.\n // \"Pan threshold validation\" will be handled\n // in `onPanResponderMove` instead of in `onMoveShouldSetPanResponder`\n return true;\n };\n\n /**\n * Calculates pinch distance\n *\n * @param e\n * @param gestureState\n * @private\n */\n _handlePanResponderGrant: NonNullable<\n PanResponderCallbacks['onPanResponderGrant']\n > = (e, gestureState) => {\n if (this.props.onLongPress) {\n this.longPressTimeout = setTimeout(() => {\n this.props.onLongPress?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n this.longPressTimeout = null;\n }, this.props.longPressDuration);\n }\n\n this.props.onPanResponderGrant?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n this.panAnim.stopAnimation();\n this.zoomAnim.stopAnimation();\n this.gestureStarted = true;\n\n this.raisePin();\n };\n\n /**\n * Handles the end of touch events\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderEnd: NonNullable<\n PanResponderCallbacks['onPanResponderEnd']\n > = (e, gestureState) => {\n if (!this.gestureType) {\n this._resolveAndHandleTap(e);\n }\n\n this.setState({ debugPoints: [] });\n\n this.lastGestureCenterPosition = null;\n\n const disableMomentum =\n this.props.disableMomentum ||\n (this.props.panEnabled &&\n this.gestureType === 'shift' &&\n this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom);\n\n // Trigger final shift animation unless disablePanOnInitialZoom is set and we're on the initial zoom level\n // or disableMomentum\n if (!disableMomentum) {\n getPanMomentumDecayAnim(this.panAnim, {\n x: gestureState.vx / this.zoomLevel,\n y: gestureState.vy / this.zoomLevel,\n }).start();\n }\n\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n this.props.onPanResponderEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n if (this.gestureType === 'pinch') {\n this.props.onZoomEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n } else if (this.gestureType === 'shift') {\n this.props.onShiftingEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n if (this.props.staticPinPosition) {\n this._updateStaticPin();\n }\n\n this.dropPin();\n\n this.gestureType = null;\n this.gestureStarted = false;\n };\n\n /**\n * Handles the actual movement of our pan responder\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderMove = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onPanResponderMove) {\n if (\n this.props.onPanResponderMove(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return false;\n }\n }\n\n // Only supports 2 touches and below,\n // any invalid number will cause the gesture to end.\n if (gestureState.numberActiveTouches <= 2) {\n if (!this.gestureStarted) {\n this._handlePanResponderGrant(e, gestureState);\n }\n } else {\n if (this.gestureStarted) {\n this._handlePanResponderEnd(e, gestureState);\n }\n return true;\n }\n\n if (gestureState.numberActiveTouches === 2) {\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'pinch') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n this.lastGestureTouchDistance = calcGestureTouchDistance(\n e,\n gestureState\n );\n }\n this.gestureType = 'pinch';\n this._handlePinching(e, gestureState);\n } else if (gestureState.numberActiveTouches === 1) {\n if (\n this.longPressTimeout &&\n (Math.abs(gestureState.dx) > 5 || Math.abs(gestureState.dy) > 5)\n ) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'shift') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n }\n\n const { dx, dy } = gestureState;\n const isShiftGesture = Math.abs(dx) > 2 || Math.abs(dy) > 2;\n if (isShiftGesture) {\n this.gestureType = 'shift';\n this._handleShifting(gestureState);\n }\n }\n };\n\n /**\n * Handles the pinch movement and zooming\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePinching(\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) {\n if (!this.props.zoomEnabled) return;\n\n const {\n maxZoom,\n minZoom,\n pinchToZoomInSensitivity,\n pinchToZoomOutSensitivity,\n } = this.props;\n\n const distance = calcGestureTouchDistance(e, gestureState);\n\n if (\n this.props.onZoomBefore &&\n this.props.onZoomBefore(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return;\n }\n\n if (!distance) return;\n if (!this.lastGestureTouchDistance) return;\n\n // define the new zoom level and take zoom level sensitivity into consideration\n const zoomGrowthFromLastGestureState =\n distance / this.lastGestureTouchDistance;\n this.lastGestureTouchDistance = distance;\n\n const pinchToZoomSensitivity =\n zoomGrowthFromLastGestureState < 1\n ? pinchToZoomOutSensitivity\n : pinchToZoomInSensitivity;\n\n if (pinchToZoomSensitivity == null) return;\n const deltaGrowth = zoomGrowthFromLastGestureState - 1;\n // 0 - no resistance\n // 10 - 90% resistance\n const deltaGrowthAdjustedBySensitivity =\n deltaGrowth * (1 - (pinchToZoomSensitivity * 9) / 100);\n\n let newZoomLevel = this.zoomLevel * (1 + deltaGrowthAdjustedBySensitivity);\n\n // make sure max and min zoom levels are respected\n if (maxZoom != null && newZoomLevel > maxZoom) {\n newZoomLevel = maxZoom;\n }\n\n if (minZoom != null && newZoomLevel < minZoom) {\n newZoomLevel = minZoom;\n }\n\n const gestureCenterPoint = calcGestureCenterPoint(e, gestureState);\n\n if (!gestureCenterPoint) return;\n\n let zoomCenter = {\n x: gestureCenterPoint.x - this.state.originalPageX,\n y: gestureCenterPoint.y - this.state.originalPageY,\n };\n\n if (this.props.staticPinPosition) {\n // When we use a static pin position, the zoom centre is the same as that position,\n // otherwise the pin moves around way too much while zooming.\n zoomCenter = {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n };\n }\n\n // Uncomment to debug\n this.props.debug && this._setPinchDebugPoints(e, zoomCenter);\n\n const { originalHeight, originalWidth } = this.state;\n\n const oldOffsetX = this.offsetX;\n const oldOffsetY = this.offsetY;\n const oldScale = this.zoomLevel;\n const newScale = newZoomLevel;\n\n if (!originalHeight || !originalWidth) return;\n\n let offsetY = calcNewScaledOffsetForZoomCentering(\n oldOffsetY,\n originalHeight,\n oldScale,\n newScale,\n zoomCenter.y\n );\n let offsetX = calcNewScaledOffsetForZoomCentering(\n oldOffsetX,\n originalWidth,\n oldScale,\n newScale,\n zoomCenter.x\n );\n\n const offsetShift =\n this._calcOffsetShiftSinceLastGestureState(gestureCenterPoint);\n if (offsetShift) {\n offsetX += offsetShift.x;\n offsetY += offsetShift.y;\n }\n\n this.offsetX = offsetX;\n this.offsetY = offsetY;\n this.zoomLevel = newScale;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n this.props.onZoomAfter?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n /**\n * Used to debug pinch events\n * @param gestureResponderEvent\n * @param zoomCenter\n * @param points\n */\n _setPinchDebugPoints(\n gestureResponderEvent: GestureResponderEvent,\n zoomCenter: Vec2D,\n ...points: Vec2D[]\n ) {\n const { touches } = gestureResponderEvent.nativeEvent;\n const { originalPageY, originalPageX } = this.state;\n\n this.setState({\n debugPoints: [\n {\n x: touches[0].pageX - originalPageX,\n y: touches[0].pageY - originalPageY,\n },\n {\n x: touches[1].pageX - originalPageX,\n y: touches[1].pageY - originalPageY,\n },\n zoomCenter,\n ...points,\n ],\n });\n }\n\n /**\n * Calculates the amount the offset should shift since the last position during panning\n *\n * @param {Vec2D} gestureCenterPoint\n *\n * @private\n */\n _calcOffsetShiftSinceLastGestureState(gestureCenterPoint: Vec2D) {\n const { movementSensibility } = this.props;\n\n let shift = null;\n\n if (this.lastGestureCenterPosition && movementSensibility) {\n const dx = gestureCenterPoint.x - this.lastGestureCenterPosition.x;\n const dy = gestureCenterPoint.y - this.lastGestureCenterPosition.y;\n\n const shiftX = dx / this.zoomLevel / movementSensibility;\n const shiftY = dy / this.zoomLevel / movementSensibility;\n\n shift = {\n x: shiftX,\n y: shiftY,\n };\n }\n\n this.lastGestureCenterPosition = gestureCenterPoint;\n\n return shift;\n }\n\n /**\n * Handles movement by tap and move\n *\n * @param gestureState\n *\n * @private\n */\n _handleShifting(gestureState: PanResponderGestureState) {\n // Skips shifting if panEnabled is false or disablePanOnInitialZoom is true and we're on the initial zoom level\n if (\n !this.props.panEnabled ||\n (this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom)\n ) {\n return;\n }\n const shift = this._calcOffsetShiftSinceLastGestureState({\n x: gestureState.moveX,\n y: gestureState.moveY,\n });\n if (!shift) return;\n\n const offsetX = this.offsetX + shift.x;\n const offsetY = this.offsetY + shift.y;\n\n if (\n this.props.debug &&\n this.state.originalPageX &&\n this.state.originalPageY\n ) {\n const x = gestureState.moveX - this.state.originalPageX;\n const y = gestureState.moveY - this.state.originalPageY;\n this.setState({ debugPoints: [{ x, y }] });\n }\n\n this._setNewOffsetPosition(offsetX, offsetY);\n\n this.raisePin();\n }\n\n /**\n * Set the state to offset moved\n *\n * @param {number} newOffsetX\n * @param {number} newOffsetY\n * @returns\n */\n _setNewOffsetPosition(newOffsetX: number, newOffsetY: number) {\n const { onShiftingBefore, onShiftingAfter } = this.props;\n\n if (onShiftingBefore?.(null, null, this._getZoomableViewEventObject())) {\n return;\n }\n\n this.offsetX = newOffsetX;\n this.offsetY = newOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n onShiftingAfter?.(null, null, this._getZoomableViewEventObject());\n }\n\n /**\n * Check whether the press event is double tap\n * or single tap and handle the event accordingly\n *\n * @param e\n *\n * @private\n */\n private _resolveAndHandleTap = (e: GestureResponderEvent) => {\n const now = Date.now();\n if (\n this.doubleTapFirstTapReleaseTimestamp &&\n this.props.doubleTapDelay &&\n now - this.doubleTapFirstTapReleaseTimestamp < this.props.doubleTapDelay\n ) {\n this.doubleTapFirstTap &&\n this._addTouch({\n ...this.doubleTapFirstTap,\n id: now.toString(),\n isSecondTap: true,\n });\n this.singleTapTimeoutId && clearTimeout(this.singleTapTimeoutId);\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n delete this.doubleTapFirstTap;\n this._handleDoubleTap(e);\n } else {\n this.doubleTapFirstTapReleaseTimestamp = now;\n this.doubleTapFirstTap = {\n id: now.toString(),\n x: e.nativeEvent.pageX - this.state.originalPageX,\n y: e.nativeEvent.pageY - this.state.originalPageY,\n };\n this._addTouch(this.doubleTapFirstTap);\n\n // persist event so e.nativeEvent is preserved after a timeout delay\n e.persist();\n this.singleTapTimeoutId = setTimeout(() => {\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n\n // Pan to the tapped location\n if (this.props.staticPinPosition && this.doubleTapFirstTap) {\n const tapX =\n this.props.staticPinPosition.x - this.doubleTapFirstTap.x;\n const tapY =\n this.props.staticPinPosition.y - this.doubleTapFirstTap.y;\n\n Animated.timing(this.panAnim, {\n toValue: {\n x: this.offsetX + tapX / this.zoomLevel,\n y: this.offsetY + tapY / this.zoomLevel,\n },\n useNativeDriver: true,\n duration: 200,\n }).start(() => {\n this._updateStaticPin();\n });\n }\n\n this.props.onSingleTap?.(e, this._getZoomableViewEventObject());\n }, this.props.doubleTapDelay);\n }\n };\n\n moveStaticPinTo = (position: Vec2D, duration?: number) => {\n const { originalWidth, originalHeight } = this.state;\n const { staticPinPosition, contentWidth, contentHeight } = this.props;\n\n if (!staticPinPosition) return;\n if (!originalWidth || !originalHeight) return;\n if (!contentWidth || !contentHeight) return;\n\n // Offset for the static pin\n const pinX = staticPinPosition.x - originalWidth / 2;\n const pinY = staticPinPosition.y - originalHeight / 2;\n\n this.offsetX = contentWidth / 2 - position.x + pinX / this.zoomLevel;\n this.offsetY = contentHeight / 2 - position.y + pinY / this.zoomLevel;\n\n if (duration) {\n Animated.timing(this.panAnim, {\n toValue: { x: this.offsetX, y: this.offsetY },\n useNativeDriver: true,\n duration,\n }).start();\n } else {\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n }\n };\n\n private _staticPinPosition = () => {\n if (!this.props.staticPinPosition) return;\n if (!this.props.contentWidth || !this.props.contentHeight) return;\n\n return viewportPositionToImagePosition({\n viewportPosition: {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n },\n imageSize: {\n height: this.props.contentHeight,\n width: this.props.contentWidth,\n },\n zoomableEvent: {\n ...this._getZoomableViewEventObject(),\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n zoomLevel: this.zoomLevel,\n },\n });\n };\n\n private _updateStaticPin = () => {\n const position = this._staticPinPosition();\n if (!position) return;\n this.props.onStaticPinPositionChange?.(position);\n };\n\n private _addTouch(touch: TouchPoint) {\n this.touches.push(touch);\n this.setState({ touches: [...this.touches] });\n }\n\n private _removeTouch(touch: TouchPoint) {\n this.touches.splice(this.touches.indexOf(touch), 1);\n this.setState({ touches: [...this.touches] });\n }\n\n /**\n * Handles the double tap event\n *\n * @param e\n *\n * @private\n */\n _handleDoubleTap(e: GestureResponderEvent) {\n const { onDoubleTapBefore, onDoubleTapAfter, doubleTapZoomToCenter } =\n this.props;\n\n onDoubleTapBefore?.(e, this._getZoomableViewEventObject());\n\n const nextZoomStep = this._getNextZoomStep();\n if (nextZoomStep == null) return;\n\n const { originalPageX, originalPageY } = this.state;\n\n // define new zoom position coordinates\n const zoomPositionCoordinates = {\n x: e.nativeEvent.pageX - originalPageX,\n y: e.nativeEvent.pageY - originalPageY,\n };\n\n // if doubleTapZoomToCenter enabled -> always zoom to center instead\n if (doubleTapZoomToCenter) {\n zoomPositionCoordinates.x = 0;\n zoomPositionCoordinates.y = 0;\n }\n\n this.zoomTo(nextZoomStep, zoomPositionCoordinates);\n\n onDoubleTapAfter?.(\n e,\n this._getZoomableViewEventObject({ zoomLevel: nextZoomStep })\n );\n }\n\n /**\n * Returns the next zoom step based on current step and zoomStep property.\n * If we are zoomed all the way in -> return to initialzoom\n *\n * @returns {*}\n */\n _getNextZoomStep() {\n const { zoomStep, maxZoom, initialZoom } = this.props;\n const { zoomLevel } = this;\n\n if (maxZoom == null) return;\n\n if (zoomLevel.toFixed(2) === maxZoom.toFixed(2)) {\n return initialZoom;\n }\n\n if (zoomStep == null) return;\n\n const nextZoomStep = zoomLevel * (1 + zoomStep);\n if (nextZoomStep > maxZoom) {\n return maxZoom;\n }\n\n return nextZoomStep;\n }\n\n /**\n * Zooms to a specific level. A \"zoom center\" can be provided, which specifies\n * the point that will remain in the same position on the screen after the zoom.\n * The coordinates of the zoom center is relative to the zoom subject.\n * { x: 0, y: 0 } is the very center of the zoom subject.\n *\n * @param newZoomLevel\n * @param zoomCenter - If not supplied, the container's center is the zoom center\n */\n zoomTo(newZoomLevel: number, zoomCenter?: Vec2D) {\n if (!this.props.zoomEnabled) return false;\n if (this.props.maxZoom && newZoomLevel > this.props.maxZoom) return false;\n if (this.props.minZoom && newZoomLevel < this.props.minZoom) return false;\n\n this.props.onZoomBefore?.(null, null, this._getZoomableViewEventObject());\n\n // == Perform Pan Animation to preserve the zoom center while zooming ==\n let listenerId: string | undefined;\n if (zoomCenter) {\n // Calculates panAnim values based on changes in zoomAnim.\n let prevScale = this.zoomLevel;\n // Since zoomAnim is calculated in native driver,\n // it will jitter panAnim once in a while,\n // because here panAnim is being calculated in js.\n // However the jittering should mostly occur in simulator.\n listenerId = this.zoomAnim.addListener(({ value: newScale }) => {\n this.panAnim.setValue({\n x: calcNewScaledOffsetForZoomCentering(\n this.offsetX,\n this.state.originalWidth,\n prevScale,\n newScale,\n zoomCenter.x\n ),\n y: calcNewScaledOffsetForZoomCentering(\n this.offsetY,\n this.state.originalHeight,\n prevScale,\n newScale,\n zoomCenter.y\n ),\n });\n prevScale = newScale;\n });\n }\n\n // == Perform Zoom Animation ==\n getZoomToAnimation(this.zoomAnim, newZoomLevel).start(() => {\n if (!listenerId) return;\n this.zoomAnim.removeListener(listenerId);\n });\n // == Zoom Animation Ends ==\n\n this.props.onZoomAfter?.(null, null, this._getZoomableViewEventObject());\n return true;\n }\n\n /**\n * Zooms in or out by a specified change level\n * Use a positive number for `zoomLevelChange` to zoom in\n * Use a negative number for `zoomLevelChange` to zoom out\n *\n * Returns a promise if everything was updated and a boolean, whether it could be updated or if it exceeded the min/max zoom limits.\n *\n * @param {number | null} zoomLevelChange\n *\n * @return {bool}\n */\n zoomBy(zoomLevelChange: number) {\n // if no zoom level Change given -> just use zoom step\n zoomLevelChange ||= this.props.zoomStep || 0;\n return this.zoomTo(this.zoomLevel + zoomLevelChange);\n }\n\n /**\n * Moves the zoomed view to a specified position\n * Returns a promise when finished\n *\n * @param {number} newOffsetX the new position we want to move it to (x-axis)\n * @param {number} newOffsetY the new position we want to move it to (y-axis)\n *\n * @return {bool}\n */\n moveTo(newOffsetX: number, newOffsetY: number) {\n const { originalWidth, originalHeight } = this.state;\n if (!originalWidth || !originalHeight) return;\n\n const offsetX = (newOffsetX - originalWidth / 2) / this.zoomLevel;\n const offsetY = (newOffsetY - originalHeight / 2) / this.zoomLevel;\n\n this._setNewOffsetPosition(-offsetX, -offsetY);\n }\n\n /**\n * Moves the zoomed view by a certain amount.\n *\n * Returns a promise when finished\n *\n * @param {number} offsetChangeX the amount we want to move the offset by (x-axis)\n * @param {number} offsetChangeY the amount we want to move the offset by (y-axis)\n *\n * @return {bool}\n */\n moveBy(offsetChangeX: number, offsetChangeY: number) {\n const offsetX =\n (this.offsetX * this.zoomLevel - offsetChangeX) / this.zoomLevel;\n const offsetY =\n (this.offsetY * this.zoomLevel - offsetChangeY) / this.zoomLevel;\n\n this._setNewOffsetPosition(offsetX, offsetY);\n }\n\n render() {\n const {\n staticPinIcon,\n children,\n visualTouchFeedbackEnabled,\n doubleTapDelay,\n staticPinPosition,\n onStaticPinLongPress,\n onStaticPinPress,\n pinProps,\n } = this.props;\n const { pinSize, touches, debugPoints = [] } = this.state;\n\n return (\n {\n this.props.onLayout?.(event);\n this.grabZoomSubjectOriginalMeasurements();\n }}\n >\n \n {children}\n \n\n {visualTouchFeedbackEnabled &&\n touches?.map(\n (touch) =>\n doubleTapDelay && (\n {\n this._removeTouch(touch);\n }}\n />\n )\n )}\n\n {/* For Debugging Only */}\n {debugPoints.map(({ x, y }, index) => {\n return ;\n })}\n\n {staticPinPosition && (\n {\n this.setState({ pinSize: size });\n }}\n pinProps={pinProps}\n />\n )}\n \n );\n }\n}\n\nconst styles = StyleSheet.create({\n container: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n overflow: 'hidden',\n position: 'relative',\n },\n zoomSubject: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n width: '100%',\n },\n});\n\nexport default ReactNativeZoomableView;\n\nexport { ReactNativeZoomableView };\n"]} \ No newline at end of file +{"version":3,"sources":["ReactNativeZoomableView.tsx"],"names":["React","Component","createRef","Animated","Easing","PanResponder","StyleSheet","View","AnimatedTouchFeedback","DebugTouchPoint","calcGestureCenterPoint","calcGestureTouchDistance","calcNewScaledOffsetForZoomCentering","applyPanBoundariesToOffset","viewportPositionToImagePosition","StaticPin","debounce","getBoundaryCrossedAnim","getPanMomentumDecayAnim","getZoomToAnimation","initialState","originalWidth","originalHeight","originalPageX","originalPageY","pinSize","width","height","ReactNativeZoomableView","gestureStarted","v","_gestureStarted","constructor","props","ValueXY","x","y","Value","value","boundaryCrossedAnimInEffect","position","onStaticPinPositionChange","requestAnimationFrame","setTimeout","zoomSubjectWrapperRef","current","measureInWindow","state","setState","e","gestureState","onStartShouldSetPanResponder","_getZoomableViewEventObject","onLongPress","longPressTimeout","longPressDuration","onPanResponderGrant","panAnim","stopAnimation","zoomAnim","raisePin","gestureType","_resolveAndHandleTap","debugPoints","lastGestureCenterPosition","disableMomentum","panEnabled","disablePanOnInitialZoom","zoomLevel","initialZoom","vx","vy","start","clearTimeout","onPanResponderEnd","onZoomEnd","onShiftingEnd","staticPinPosition","_updateStaticPin","dropPin","onPanResponderMove","numberActiveTouches","_handlePanResponderGrant","_handlePanResponderEnd","lastGestureTouchDistance","_handlePinching","Math","abs","dx","dy","isShiftGesture","_handleShifting","now","Date","doubleTapFirstTapReleaseTimestamp","doubleTapDelay","doubleTapFirstTap","_addTouch","id","toString","isSecondTap","singleTapTimeoutId","_handleDoubleTap","nativeEvent","pageX","pageY","persist","tapX","tapY","timing","toValue","offsetX","offsetY","useNativeDriver","duration","onSingleTap","contentWidth","contentHeight","pinX","pinY","setValue","viewportPosition","imageSize","zoomableEvent","_staticPinPosition","gestureHandlers","create","_handleStartShouldSetPanResponder","_handlePanResponderMove","onPanResponderRelease","onPanResponderTerminate","evt","onPanResponderTerminationRequest","onShouldBlockNativeResponder","onStartShouldSetPanResponderCapture","onMoveShouldSetPanResponderCapture","zoomAnimatedValue","panAnimatedValueXY","initialOffsetX","initialOffsetY","addListener","animatePin","pinAnim","easing","out","ease","__setOffset","__getOffset","axis","offset","offsetState","__offsets","bindToBorders","containerSize","contentSize","boundOffset","panBoundaryPadding","boundariesApplied","toFixed","componentDidUpdate","prevProps","prevState","zoomEnabled","onTransformInvocationInitialized","_invokeOnTransform","successful","currState","originalMeasurementsChanged","staticPinPositionChanged","componentDidMount","grabZoomSubjectOriginalMeasurements","measureZoomSubjectInterval","setInterval","componentWillUnmount","clearInterval","zoomableViewEvent","onTransform","onStaticPinPositionMove","debouncedOnStaticPinPositionChange","overwriteObj","maxZoom","minZoom","pinchToZoomInSensitivity","pinchToZoomOutSensitivity","distance","onZoomBefore","zoomGrowthFromLastGestureState","pinchToZoomSensitivity","deltaGrowth","deltaGrowthAdjustedBySensitivity","newZoomLevel","gestureCenterPoint","zoomCenter","debug","_setPinchDebugPoints","oldOffsetX","oldOffsetY","oldScale","newScale","offsetShift","_calcOffsetShiftSinceLastGestureState","onZoomAfter","gestureResponderEvent","points","touches","movementSensibility","shift","shiftX","shiftY","moveX","moveY","_setNewOffsetPosition","newOffsetX","newOffsetY","onShiftingBefore","onShiftingAfter","touch","push","_removeTouch","splice","indexOf","onDoubleTapBefore","onDoubleTapAfter","doubleTapZoomToCenter","nextZoomStep","_getNextZoomStep","zoomPositionCoordinates","zoomTo","zoomStep","listenerId","prevScale","removeListener","zoomBy","zoomLevelChange","moveTo","moveBy","offsetChangeX","offsetChangeY","render","staticPinIcon","children","visualTouchFeedbackEnabled","onStaticPinLongPress","onStaticPinPress","pinProps","styles","container","panHandlers","event","onLayout","zoomSubject","style","transform","scale","getTranslateTransform","map","index","size","undefined","alignItems","flex","justifyContent","overflow"],"mappings":"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","sourcesContent":["import React, { Component, createRef, RefObject } from 'react';\nimport {\n Animated,\n Easing,\n GestureResponderEvent,\n PanResponder,\n PanResponderCallbacks,\n PanResponderGestureState,\n PanResponderInstance,\n StyleSheet,\n View,\n} from 'react-native';\n\nimport {\n Vec2D,\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState,\n TouchPoint,\n ZoomableViewEvent,\n Size2D,\n} from './typings';\n\nimport { AnimatedTouchFeedback } from './components';\nimport { DebugTouchPoint } from './debugHelper';\nimport {\n calcGestureCenterPoint,\n calcGestureTouchDistance,\n calcNewScaledOffsetForZoomCentering,\n} from './helper';\nimport { applyPanBoundariesToOffset } from './helper/applyPanBoundariesToOffset';\nimport { viewportPositionToImagePosition } from './helper/coordinateConversion';\nimport { StaticPin } from './components/StaticPin';\nimport { debounce } from 'lodash';\nimport {\n getBoundaryCrossedAnim,\n getPanMomentumDecayAnim,\n getZoomToAnimation,\n} from './animations';\n\nconst initialState: ReactNativeZoomableViewState = {\n originalWidth: 0,\n originalHeight: 0,\n originalPageX: 0,\n originalPageY: 0,\n pinSize: { width: 0, height: 0 },\n};\n\nclass ReactNativeZoomableView extends Component<\n ReactNativeZoomableViewProps,\n ReactNativeZoomableViewState\n> {\n zoomSubjectWrapperRef: RefObject;\n gestureHandlers: PanResponderInstance;\n doubleTapFirstTapReleaseTimestamp: number | undefined;\n\n static defaultProps = {\n zoomEnabled: true,\n panEnabled: true,\n initialZoom: 1,\n initialOffsetX: 0,\n initialOffsetY: 0,\n maxZoom: 1.5,\n minZoom: 0.5,\n pinchToZoomInSensitivity: 1,\n pinchToZoomOutSensitivity: 1,\n movementSensibility: 1,\n doubleTapDelay: 300,\n bindToBorders: true,\n zoomStep: 0.5,\n onLongPress: null,\n longPressDuration: 700,\n contentWidth: undefined,\n contentHeight: undefined,\n panBoundaryPadding: 0,\n visualTouchFeedbackEnabled: true,\n staticPinPosition: undefined,\n staticPinIcon: undefined,\n onStaticPinPositionChange: undefined,\n onStaticPinPositionMove: undefined,\n animatePin: true,\n disablePanOnInitialZoom: false,\n };\n\n private panAnim = new Animated.ValueXY({ x: 0, y: 0 });\n private zoomAnim = new Animated.Value(1);\n private pinAnim = new Animated.ValueXY({ x: 0, y: 0 });\n\n private __offsets = {\n x: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n y: {\n value: 0,\n boundaryCrossedAnimInEffect: false,\n },\n };\n\n private zoomLevel = 1;\n private lastGestureCenterPosition: { x: number; y: number } | null = null;\n private lastGestureTouchDistance: number | null = null;\n private gestureType: 'pinch' | 'shift' | null;\n\n private _gestureStarted = false;\n private set gestureStarted(v: boolean) {\n this._gestureStarted = v;\n }\n\n public get gestureStarted() {\n return this._gestureStarted;\n }\n\n /**\n * Last press time (used to evaluate whether user double tapped)\n * @type {number}\n */\n private longPressTimeout: NodeJS.Timeout | null = null;\n private onTransformInvocationInitialized: boolean | undefined;\n private singleTapTimeoutId: NodeJS.Timeout | undefined;\n private touches: TouchPoint[] = [];\n private doubleTapFirstTap: TouchPoint | undefined;\n private measureZoomSubjectInterval: NodeJS.Timer | undefined;\n\n constructor(props: ReactNativeZoomableViewProps) {\n super(props);\n // This needs to be done before anything else to initialize the state.\n // Otherwise, the logic below may reference the state when it's undefined,\n // causing runtime errors.\n this.state = { ...initialState };\n\n this.gestureHandlers = PanResponder.create({\n onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,\n onPanResponderGrant: this._handlePanResponderGrant,\n onPanResponderMove: this._handlePanResponderMove,\n onPanResponderRelease: this._handlePanResponderEnd,\n onPanResponderTerminate: (evt, gestureState) => {\n // We should also call _handlePanResponderEnd\n // to properly perform cleanups when the gesture is terminated\n // (aka gesture handling responsibility is taken over by another component).\n // This also fixes a weird issue where\n // on real device, sometimes onPanResponderRelease is not called when you lift 2 fingers up,\n // but onPanResponderTerminate is called instead for no apparent reason.\n this._handlePanResponderEnd(evt, gestureState);\n this.props.onPanResponderTerminate?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n );\n },\n onPanResponderTerminationRequest: (evt, gestureState) =>\n !!this.props.onPanResponderTerminationRequest?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ),\n // Defaults to true to prevent parent components, such as React Navigation's tab view, from taking over as responder.\n onShouldBlockNativeResponder: (evt, gestureState) =>\n this.props.onShouldBlockNativeResponder?.(\n evt,\n gestureState,\n this._getZoomableViewEventObject()\n ) ?? true,\n onStartShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onStartShouldSetPanResponderCapture?.(evt, gestureState),\n onMoveShouldSetPanResponderCapture: (evt, gestureState) =>\n !!this.props.onMoveShouldSetPanResponderCapture?.(evt, gestureState),\n });\n\n this.zoomSubjectWrapperRef = createRef();\n\n if (this.props.zoomAnimatedValue)\n this.zoomAnim = this.props.zoomAnimatedValue;\n if (this.props.panAnimatedValueXY)\n this.panAnim = this.props.panAnimatedValueXY;\n\n if (this.props.initialZoom) this.zoomLevel = this.props.initialZoom;\n if (this.props.initialOffsetX != null)\n this.offsetX = this.props.initialOffsetX;\n if (this.props.initialOffsetY != null)\n this.offsetY = this.props.initialOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n this.panAnim.addListener(({ x, y }) => {\n this.offsetX = x;\n this.offsetY = y;\n });\n this.zoomAnim.addListener(({ value }) => {\n this.zoomLevel = value;\n });\n\n this.lastGestureTouchDistance = 150;\n\n this.gestureType = null;\n }\n\n private raisePin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: -10 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private dropPin() {\n if (!this.props.animatePin) return;\n Animated.timing(this.pinAnim, {\n toValue: { x: 0, y: 0 },\n useNativeDriver: true,\n easing: Easing.out(Easing.ease),\n duration: 100,\n }).start();\n }\n\n private set offsetX(x: number) {\n this.__setOffset('x', x);\n }\n\n private set offsetY(y: number) {\n this.__setOffset('y', y);\n }\n\n private get offsetX() {\n return this.__getOffset('x');\n }\n\n private get offsetY() {\n return this.__getOffset('y');\n }\n\n private __setOffset(axis: 'x' | 'y', offset: number) {\n const offsetState = this.__offsets[axis];\n\n if (this.props.bindToBorders) {\n const containerSize =\n axis === 'x' ? this.state.originalWidth : this.state.originalHeight;\n const contentSize =\n axis === 'x'\n ? this.props.contentWidth || this.state.originalWidth\n : this.props.contentHeight || this.state.originalHeight;\n\n const boundOffset =\n contentSize && containerSize && this.props.panBoundaryPadding != null\n ? applyPanBoundariesToOffset(\n offset,\n containerSize,\n contentSize,\n this.zoomLevel,\n this.props.panBoundaryPadding\n )\n : offset;\n\n if (!this.gestureType && !offsetState.boundaryCrossedAnimInEffect) {\n const boundariesApplied =\n boundOffset !== offset &&\n boundOffset.toFixed(3) !== offset.toFixed(3);\n if (boundariesApplied) {\n offsetState.boundaryCrossedAnimInEffect = true;\n getBoundaryCrossedAnim(this.panAnim[axis], boundOffset).start(() => {\n offsetState.boundaryCrossedAnimInEffect = false;\n });\n return;\n }\n }\n }\n\n offsetState.value = offset;\n }\n\n private __getOffset(axis: 'x' | 'y') {\n return this.__offsets[axis].value;\n }\n\n componentDidUpdate(\n prevProps: ReactNativeZoomableViewProps,\n prevState: ReactNativeZoomableViewState\n ) {\n const { zoomEnabled, initialZoom } = this.props;\n if (prevProps.zoomEnabled && !zoomEnabled && initialZoom) {\n this.zoomLevel = initialZoom;\n this.zoomAnim.setValue(this.zoomLevel);\n }\n if (\n !this.onTransformInvocationInitialized &&\n this._invokeOnTransform().successful\n ) {\n this.panAnim.addListener(() => this._invokeOnTransform());\n this.zoomAnim.addListener(() => this._invokeOnTransform());\n this.onTransformInvocationInitialized = true;\n }\n\n const currState = this.state;\n const originalMeasurementsChanged =\n currState.originalHeight !== prevState.originalHeight ||\n currState.originalWidth !== prevState.originalWidth ||\n currState.originalPageX !== prevState.originalPageX ||\n currState.originalPageY !== prevState.originalPageY;\n\n const staticPinPositionChanged =\n prevProps.staticPinPosition?.x !== this.props.staticPinPosition?.x ||\n prevProps.staticPinPosition?.y !== this.props.staticPinPosition?.y;\n\n if (\n this.onTransformInvocationInitialized &&\n (originalMeasurementsChanged || staticPinPositionChanged)\n ) {\n this._invokeOnTransform();\n }\n }\n\n componentDidMount() {\n this.grabZoomSubjectOriginalMeasurements();\n // We've already run `grabZoomSubjectOriginalMeasurements` at various events\n // to make sure the measurements are promptly updated.\n // However, there might be cases we haven't accounted for, especially when\n // native processes are involved. To account for those cases,\n // we'll use an interval here to ensure we're always up-to-date.\n // The `setState` in `grabZoomSubjectOriginalMeasurements` won't trigger a rerender\n // if the values given haven't changed, so we're not running performance risk here.\n this.measureZoomSubjectInterval = setInterval(\n this.grabZoomSubjectOriginalMeasurements,\n 1e3\n );\n }\n\n componentWillUnmount() {\n this.measureZoomSubjectInterval &&\n clearInterval(this.measureZoomSubjectInterval);\n }\n\n debouncedOnStaticPinPositionChange = debounce(\n (position: Vec2D) => this.props.onStaticPinPositionChange?.(position),\n 100\n );\n\n /**\n * try to invoke onTransform\n * @private\n */\n _invokeOnTransform() {\n const zoomableViewEvent = this._getZoomableViewEventObject();\n const position = this._staticPinPosition();\n\n if (!zoomableViewEvent.originalWidth || !zoomableViewEvent.originalHeight)\n return { successful: false };\n\n this.props.onTransform?.(zoomableViewEvent);\n\n if (position) {\n this.props.onStaticPinPositionMove?.(position);\n this.debouncedOnStaticPinPositionChange(position);\n }\n\n return { successful: true };\n }\n\n /**\n * Returns additional information about components current state for external event hooks\n *\n * @returns {{}}\n * @private\n */\n _getZoomableViewEventObject(overwriteObj = {}): ZoomableViewEvent {\n return {\n zoomLevel: this.zoomLevel,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n originalHeight: this.state.originalHeight,\n originalWidth: this.state.originalWidth,\n originalPageX: this.state.originalPageX,\n originalPageY: this.state.originalPageY,\n ...overwriteObj,\n } as ZoomableViewEvent;\n }\n\n /**\n * Get the original box dimensions and save them for later use.\n * (They will be used to calculate boxBorders)\n *\n * @private\n */\n private grabZoomSubjectOriginalMeasurements = () => {\n // make sure we measure after animations are complete\n requestAnimationFrame(() => {\n // this setTimeout is here to fix a weird issue on iOS where the measurements are all `0`\n // when navigating back (react-navigation stack) from another view\n // while closing the keyboard at the same time\n setTimeout(() => {\n // In normal conditions, we're supposed to measure zoomSubject instead of its wrapper.\n // However, our zoomSubject may have been transformed by an initial zoomLevel or offset,\n // in which case these measurements will not represent the true \"original\" measurements.\n // We just need to make sure the zoomSubjectWrapper perfectly aligns with the zoomSubject\n // (no border, space, or anything between them)\n const zoomSubjectWrapperRef = this.zoomSubjectWrapperRef;\n // we don't wanna measure when zoomSubjectWrapperRef is not yet available or has been unmounted\n zoomSubjectWrapperRef.current?.measureInWindow(\n (x, y, width, height) => {\n // When the component is off-screen, these become all 0s, so we don't set them\n // to avoid messing up calculations, especially ones that are done right after\n // the component transitions from hidden to visible.\n if (!x && !y && !width && !height) return;\n\n // If these values are all the same, don't re-set them in state\n // this way we don't re-render\n if (\n this.state.originalWidth === width &&\n this.state.originalHeight === height &&\n this.state.originalPageX === x &&\n this.state.originalPageY === y\n ) {\n return;\n }\n\n this.setState({\n originalWidth: width,\n originalHeight: height,\n originalPageX: x,\n originalPageY: y,\n });\n }\n );\n });\n });\n };\n\n /**\n * Handles the start of touch events and checks for taps\n *\n * @param e\n * @param gestureState\n * @returns {boolean}\n *\n * @private\n */\n _handleStartShouldSetPanResponder = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onStartShouldSetPanResponder) {\n this.props.onStartShouldSetPanResponder(\n e,\n gestureState,\n this._getZoomableViewEventObject(),\n false\n );\n }\n\n // Always set pan responder on start\n // of gesture so we can handle tap.\n // \"Pan threshold validation\" will be handled\n // in `onPanResponderMove` instead of in `onMoveShouldSetPanResponder`\n return true;\n };\n\n /**\n * Calculates pinch distance\n *\n * @param e\n * @param gestureState\n * @private\n */\n _handlePanResponderGrant: NonNullable<\n PanResponderCallbacks['onPanResponderGrant']\n > = (e, gestureState) => {\n if (this.props.onLongPress) {\n this.longPressTimeout = setTimeout(() => {\n this.props.onLongPress?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n this.longPressTimeout = null;\n }, this.props.longPressDuration);\n }\n\n this.props.onPanResponderGrant?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n this.panAnim.stopAnimation();\n this.zoomAnim.stopAnimation();\n this.gestureStarted = true;\n\n this.raisePin();\n };\n\n /**\n * Handles the end of touch events\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderEnd: NonNullable<\n PanResponderCallbacks['onPanResponderEnd']\n > = (e, gestureState) => {\n if (!this.gestureType) {\n this._resolveAndHandleTap(e);\n }\n\n this.setState({ debugPoints: [] });\n\n this.lastGestureCenterPosition = null;\n\n const disableMomentum =\n this.props.disableMomentum ||\n (this.props.panEnabled &&\n this.gestureType === 'shift' &&\n this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom);\n\n // Trigger final shift animation unless disablePanOnInitialZoom is set and we're on the initial zoom level\n // or disableMomentum\n if (!disableMomentum) {\n getPanMomentumDecayAnim(this.panAnim, {\n x: gestureState.vx / this.zoomLevel,\n y: gestureState.vy / this.zoomLevel,\n }).start();\n }\n\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n this.props.onPanResponderEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n\n if (this.gestureType === 'pinch') {\n this.props.onZoomEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n } else if (this.gestureType === 'shift') {\n this.props.onShiftingEnd?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n if (this.props.staticPinPosition) {\n this._updateStaticPin();\n }\n\n this.dropPin();\n\n this.gestureType = null;\n this.gestureStarted = false;\n };\n\n /**\n * Handles the actual movement of our pan responder\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePanResponderMove = (\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) => {\n if (this.props.onPanResponderMove) {\n if (\n this.props.onPanResponderMove(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return false;\n }\n }\n\n // Only supports 2 touches and below,\n // any invalid number will cause the gesture to end.\n if (gestureState.numberActiveTouches <= 2) {\n if (!this.gestureStarted) {\n this._handlePanResponderGrant(e, gestureState);\n }\n } else {\n if (this.gestureStarted) {\n this._handlePanResponderEnd(e, gestureState);\n }\n return true;\n }\n\n if (gestureState.numberActiveTouches === 2) {\n if (this.longPressTimeout) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'pinch') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n this.lastGestureTouchDistance = calcGestureTouchDistance(\n e,\n gestureState\n );\n }\n this.gestureType = 'pinch';\n this._handlePinching(e, gestureState);\n } else if (gestureState.numberActiveTouches === 1) {\n if (\n this.longPressTimeout &&\n (Math.abs(gestureState.dx) > 5 || Math.abs(gestureState.dy) > 5)\n ) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = null;\n }\n // change some measurement states when switching gesture to ensure a smooth transition\n if (this.gestureType !== 'shift') {\n this.lastGestureCenterPosition = calcGestureCenterPoint(\n e,\n gestureState\n );\n }\n\n const { dx, dy } = gestureState;\n const isShiftGesture = Math.abs(dx) > 2 || Math.abs(dy) > 2;\n if (isShiftGesture) {\n this.gestureType = 'shift';\n this._handleShifting(gestureState);\n }\n }\n };\n\n /**\n * Handles the pinch movement and zooming\n *\n * @param e\n * @param gestureState\n *\n * @private\n */\n _handlePinching(\n e: GestureResponderEvent,\n gestureState: PanResponderGestureState\n ) {\n if (!this.props.zoomEnabled) return;\n\n const {\n maxZoom,\n minZoom,\n pinchToZoomInSensitivity,\n pinchToZoomOutSensitivity,\n } = this.props;\n\n const distance = calcGestureTouchDistance(e, gestureState);\n\n if (\n this.props.onZoomBefore &&\n this.props.onZoomBefore(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n )\n ) {\n return;\n }\n\n if (!distance) return;\n if (!this.lastGestureTouchDistance) return;\n\n // define the new zoom level and take zoom level sensitivity into consideration\n const zoomGrowthFromLastGestureState =\n distance / this.lastGestureTouchDistance;\n this.lastGestureTouchDistance = distance;\n\n const pinchToZoomSensitivity =\n zoomGrowthFromLastGestureState < 1\n ? pinchToZoomOutSensitivity\n : pinchToZoomInSensitivity;\n\n if (pinchToZoomSensitivity == null) return;\n const deltaGrowth = zoomGrowthFromLastGestureState - 1;\n // 0 - no resistance\n // 10 - 90% resistance\n const deltaGrowthAdjustedBySensitivity =\n deltaGrowth * (1 - (pinchToZoomSensitivity * 9) / 100);\n\n let newZoomLevel = this.zoomLevel * (1 + deltaGrowthAdjustedBySensitivity);\n\n // make sure max and min zoom levels are respected\n if (maxZoom != null && newZoomLevel > maxZoom) {\n newZoomLevel = maxZoom;\n }\n\n if (minZoom != null && newZoomLevel < minZoom) {\n newZoomLevel = minZoom;\n }\n\n const gestureCenterPoint = calcGestureCenterPoint(e, gestureState);\n\n if (!gestureCenterPoint) return;\n\n let zoomCenter = {\n x: gestureCenterPoint.x - this.state.originalPageX,\n y: gestureCenterPoint.y - this.state.originalPageY,\n };\n\n if (this.props.staticPinPosition) {\n // When we use a static pin position, the zoom centre is the same as that position,\n // otherwise the pin moves around way too much while zooming.\n zoomCenter = {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n };\n }\n\n // Uncomment to debug\n this.props.debug && this._setPinchDebugPoints(e, zoomCenter);\n\n const { originalHeight, originalWidth } = this.state;\n\n const oldOffsetX = this.offsetX;\n const oldOffsetY = this.offsetY;\n const oldScale = this.zoomLevel;\n const newScale = newZoomLevel;\n\n if (!originalHeight || !originalWidth) return;\n\n let offsetY = calcNewScaledOffsetForZoomCentering(\n oldOffsetY,\n originalHeight,\n oldScale,\n newScale,\n zoomCenter.y\n );\n let offsetX = calcNewScaledOffsetForZoomCentering(\n oldOffsetX,\n originalWidth,\n oldScale,\n newScale,\n zoomCenter.x\n );\n\n const offsetShift =\n this._calcOffsetShiftSinceLastGestureState(gestureCenterPoint);\n if (offsetShift) {\n offsetX += offsetShift.x;\n offsetY += offsetShift.y;\n }\n\n this.offsetX = offsetX;\n this.offsetY = offsetY;\n this.zoomLevel = newScale;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n this.props.onZoomAfter?.(\n e,\n gestureState,\n this._getZoomableViewEventObject()\n );\n }\n\n /**\n * Used to debug pinch events\n * @param gestureResponderEvent\n * @param zoomCenter\n * @param points\n */\n _setPinchDebugPoints(\n gestureResponderEvent: GestureResponderEvent,\n zoomCenter: Vec2D,\n ...points: Vec2D[]\n ) {\n const { touches } = gestureResponderEvent.nativeEvent;\n const { originalPageY, originalPageX } = this.state;\n\n this.setState({\n debugPoints: [\n {\n x: touches[0].pageX - originalPageX,\n y: touches[0].pageY - originalPageY,\n },\n {\n x: touches[1].pageX - originalPageX,\n y: touches[1].pageY - originalPageY,\n },\n zoomCenter,\n ...points,\n ],\n });\n }\n\n /**\n * Calculates the amount the offset should shift since the last position during panning\n *\n * @param {Vec2D} gestureCenterPoint\n *\n * @private\n */\n _calcOffsetShiftSinceLastGestureState(gestureCenterPoint: Vec2D) {\n const { movementSensibility } = this.props;\n\n let shift = null;\n\n if (this.lastGestureCenterPosition && movementSensibility) {\n const dx = gestureCenterPoint.x - this.lastGestureCenterPosition.x;\n const dy = gestureCenterPoint.y - this.lastGestureCenterPosition.y;\n\n const shiftX = dx / this.zoomLevel / movementSensibility;\n const shiftY = dy / this.zoomLevel / movementSensibility;\n\n shift = {\n x: shiftX,\n y: shiftY,\n };\n }\n\n this.lastGestureCenterPosition = gestureCenterPoint;\n\n return shift;\n }\n\n /**\n * Handles movement by tap and move\n *\n * @param gestureState\n *\n * @private\n */\n _handleShifting(gestureState: PanResponderGestureState) {\n // Skips shifting if panEnabled is false or disablePanOnInitialZoom is true and we're on the initial zoom level\n if (\n !this.props.panEnabled ||\n (this.props.disablePanOnInitialZoom &&\n this.zoomLevel === this.props.initialZoom)\n ) {\n return;\n }\n const shift = this._calcOffsetShiftSinceLastGestureState({\n x: gestureState.moveX,\n y: gestureState.moveY,\n });\n if (!shift) return;\n\n const offsetX = this.offsetX + shift.x;\n const offsetY = this.offsetY + shift.y;\n\n if (\n this.props.debug &&\n this.state.originalPageX &&\n this.state.originalPageY\n ) {\n const x = gestureState.moveX - this.state.originalPageX;\n const y = gestureState.moveY - this.state.originalPageY;\n this.setState({ debugPoints: [{ x, y }] });\n }\n\n this._setNewOffsetPosition(offsetX, offsetY);\n\n this.raisePin();\n }\n\n /**\n * Set the state to offset moved\n *\n * @param {number} newOffsetX\n * @param {number} newOffsetY\n * @returns\n */\n _setNewOffsetPosition(newOffsetX: number, newOffsetY: number) {\n const { onShiftingBefore, onShiftingAfter } = this.props;\n\n if (onShiftingBefore?.(null, null, this._getZoomableViewEventObject())) {\n return;\n }\n\n this.offsetX = newOffsetX;\n this.offsetY = newOffsetY;\n\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n this.zoomAnim.setValue(this.zoomLevel);\n\n onShiftingAfter?.(null, null, this._getZoomableViewEventObject());\n }\n\n /**\n * Check whether the press event is double tap\n * or single tap and handle the event accordingly\n *\n * @param e\n *\n * @private\n */\n private _resolveAndHandleTap = (e: GestureResponderEvent) => {\n const now = Date.now();\n if (\n this.doubleTapFirstTapReleaseTimestamp &&\n this.props.doubleTapDelay &&\n now - this.doubleTapFirstTapReleaseTimestamp < this.props.doubleTapDelay\n ) {\n this.doubleTapFirstTap &&\n this._addTouch({\n ...this.doubleTapFirstTap,\n id: now.toString(),\n isSecondTap: true,\n });\n this.singleTapTimeoutId && clearTimeout(this.singleTapTimeoutId);\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n delete this.doubleTapFirstTap;\n this._handleDoubleTap(e);\n } else {\n this.doubleTapFirstTapReleaseTimestamp = now;\n this.doubleTapFirstTap = {\n id: now.toString(),\n x: e.nativeEvent.pageX - this.state.originalPageX,\n y: e.nativeEvent.pageY - this.state.originalPageY,\n };\n this._addTouch(this.doubleTapFirstTap);\n\n // persist event so e.nativeEvent is preserved after a timeout delay\n e.persist();\n this.singleTapTimeoutId = setTimeout(() => {\n delete this.doubleTapFirstTapReleaseTimestamp;\n delete this.singleTapTimeoutId;\n\n // Pan to the tapped location\n if (this.props.staticPinPosition && this.doubleTapFirstTap) {\n const tapX =\n this.props.staticPinPosition.x - this.doubleTapFirstTap.x;\n const tapY =\n this.props.staticPinPosition.y - this.doubleTapFirstTap.y;\n\n Animated.timing(this.panAnim, {\n toValue: {\n x: this.offsetX + tapX / this.zoomLevel,\n y: this.offsetY + tapY / this.zoomLevel,\n },\n useNativeDriver: true,\n duration: 200,\n }).start(() => {\n this._updateStaticPin();\n });\n }\n\n this.props.onSingleTap?.(e, this._getZoomableViewEventObject());\n }, this.props.doubleTapDelay);\n }\n };\n\n moveStaticPinTo = (position: Vec2D, duration?: number) => {\n const { originalWidth, originalHeight } = this.state;\n const { staticPinPosition, contentWidth, contentHeight } = this.props;\n\n if (!staticPinPosition) return;\n if (!originalWidth || !originalHeight) return;\n if (!contentWidth || !contentHeight) return;\n\n // Offset for the static pin\n const pinX = staticPinPosition.x - originalWidth / 2;\n const pinY = staticPinPosition.y - originalHeight / 2;\n\n this.offsetX = contentWidth / 2 - position.x + pinX / this.zoomLevel;\n this.offsetY = contentHeight / 2 - position.y + pinY / this.zoomLevel;\n\n if (duration) {\n Animated.timing(this.panAnim, {\n toValue: { x: this.offsetX, y: this.offsetY },\n useNativeDriver: true,\n duration,\n }).start();\n } else {\n this.panAnim.setValue({ x: this.offsetX, y: this.offsetY });\n }\n };\n\n private _staticPinPosition = () => {\n if (!this.props.staticPinPosition) return;\n if (!this.props.contentWidth || !this.props.contentHeight) return;\n\n return viewportPositionToImagePosition({\n viewportPosition: {\n x: this.props.staticPinPosition.x,\n y: this.props.staticPinPosition.y,\n },\n imageSize: {\n height: this.props.contentHeight,\n width: this.props.contentWidth,\n },\n zoomableEvent: {\n ...this._getZoomableViewEventObject(),\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n zoomLevel: this.zoomLevel,\n },\n });\n };\n\n private _updateStaticPin = () => {\n const position = this._staticPinPosition();\n if (!position) return;\n this.props.onStaticPinPositionChange?.(position);\n };\n\n private _addTouch(touch: TouchPoint) {\n this.touches.push(touch);\n this.setState({ touches: [...this.touches] });\n }\n\n private _removeTouch(touch: TouchPoint) {\n this.touches.splice(this.touches.indexOf(touch), 1);\n this.setState({ touches: [...this.touches] });\n }\n\n /**\n * Handles the double tap event\n *\n * @param e\n *\n * @private\n */\n _handleDoubleTap(e: GestureResponderEvent) {\n const { onDoubleTapBefore, onDoubleTapAfter, doubleTapZoomToCenter } =\n this.props;\n\n onDoubleTapBefore?.(e, this._getZoomableViewEventObject());\n\n const nextZoomStep = this._getNextZoomStep();\n if (nextZoomStep == null) return;\n\n const { originalPageX, originalPageY } = this.state;\n\n // define new zoom position coordinates\n const zoomPositionCoordinates = {\n x: e.nativeEvent.pageX - originalPageX,\n y: e.nativeEvent.pageY - originalPageY,\n };\n\n // if doubleTapZoomToCenter enabled -> always zoom to center instead\n if (doubleTapZoomToCenter) {\n zoomPositionCoordinates.x = 0;\n zoomPositionCoordinates.y = 0;\n }\n\n this.zoomTo(nextZoomStep, zoomPositionCoordinates);\n\n onDoubleTapAfter?.(\n e,\n this._getZoomableViewEventObject({ zoomLevel: nextZoomStep })\n );\n }\n\n /**\n * Returns the next zoom step based on current step and zoomStep property.\n * If we are zoomed all the way in -> return to initialzoom\n *\n * @returns {*}\n */\n _getNextZoomStep() {\n const { zoomStep, maxZoom, initialZoom } = this.props;\n const { zoomLevel } = this;\n\n if (maxZoom == null) return;\n\n if (zoomLevel.toFixed(2) === maxZoom.toFixed(2)) {\n return initialZoom;\n }\n\n if (zoomStep == null) return;\n\n const nextZoomStep = zoomLevel * (1 + zoomStep);\n if (nextZoomStep > maxZoom) {\n return maxZoom;\n }\n\n return nextZoomStep;\n }\n\n /**\n * Zooms to a specific level. A \"zoom center\" can be provided, which specifies\n * the point that will remain in the same position on the screen after the zoom.\n * The coordinates of the zoom center is relative to the zoom subject.\n * { x: 0, y: 0 } is the very center of the zoom subject.\n *\n * @param newZoomLevel\n * @param zoomCenter - If not supplied, the container's center is the zoom center\n */\n zoomTo(newZoomLevel: number, zoomCenter?: Vec2D) {\n if (!this.props.zoomEnabled) return false;\n if (this.props.maxZoom && newZoomLevel > this.props.maxZoom) return false;\n if (this.props.minZoom && newZoomLevel < this.props.minZoom) return false;\n\n this.props.onZoomBefore?.(null, null, this._getZoomableViewEventObject());\n\n // == Perform Pan Animation to preserve the zoom center while zooming ==\n let listenerId = '';\n if (zoomCenter) {\n // Calculates panAnim values based on changes in zoomAnim.\n let prevScale = this.zoomLevel;\n // Since zoomAnim is calculated in native driver,\n // it will jitter panAnim once in a while,\n // because here panAnim is being calculated in js.\n // However the jittering should mostly occur in simulator.\n listenerId = this.zoomAnim.addListener(({ value: newScale }) => {\n this.panAnim.setValue({\n x: calcNewScaledOffsetForZoomCentering(\n this.offsetX,\n this.state.originalWidth,\n prevScale,\n newScale,\n zoomCenter.x\n ),\n y: calcNewScaledOffsetForZoomCentering(\n this.offsetY,\n this.state.originalHeight,\n prevScale,\n newScale,\n zoomCenter.y\n ),\n });\n prevScale = newScale;\n });\n }\n\n // == Perform Zoom Animation ==\n getZoomToAnimation(this.zoomAnim, newZoomLevel).start(() => {\n this.zoomAnim.removeListener(listenerId);\n });\n // == Zoom Animation Ends ==\n\n this.props.onZoomAfter?.(null, null, this._getZoomableViewEventObject());\n return true;\n }\n\n /**\n * Zooms in or out by a specified change level\n * Use a positive number for `zoomLevelChange` to zoom in\n * Use a negative number for `zoomLevelChange` to zoom out\n *\n * Returns a promise if everything was updated and a boolean, whether it could be updated or if it exceeded the min/max zoom limits.\n *\n * @param {number | null} zoomLevelChange\n *\n * @return {bool}\n */\n zoomBy(zoomLevelChange: number) {\n // if no zoom level Change given -> just use zoom step\n zoomLevelChange ||= this.props.zoomStep || 0;\n return this.zoomTo(this.zoomLevel + zoomLevelChange);\n }\n\n /**\n * Moves the zoomed view to a specified position\n * Returns a promise when finished\n *\n * @param {number} newOffsetX the new position we want to move it to (x-axis)\n * @param {number} newOffsetY the new position we want to move it to (y-axis)\n *\n * @return {bool}\n */\n moveTo(newOffsetX: number, newOffsetY: number) {\n const { originalWidth, originalHeight } = this.state;\n if (!originalWidth || !originalHeight) return;\n\n const offsetX = (newOffsetX - originalWidth / 2) / this.zoomLevel;\n const offsetY = (newOffsetY - originalHeight / 2) / this.zoomLevel;\n\n this._setNewOffsetPosition(-offsetX, -offsetY);\n }\n\n /**\n * Moves the zoomed view by a certain amount.\n *\n * Returns a promise when finished\n *\n * @param {number} offsetChangeX the amount we want to move the offset by (x-axis)\n * @param {number} offsetChangeY the amount we want to move the offset by (y-axis)\n *\n * @return {bool}\n */\n moveBy(offsetChangeX: number, offsetChangeY: number) {\n const offsetX =\n (this.offsetX * this.zoomLevel - offsetChangeX) / this.zoomLevel;\n const offsetY =\n (this.offsetY * this.zoomLevel - offsetChangeY) / this.zoomLevel;\n\n this._setNewOffsetPosition(offsetX, offsetY);\n }\n\n render() {\n const {\n staticPinIcon,\n children,\n visualTouchFeedbackEnabled,\n doubleTapDelay,\n staticPinPosition,\n onStaticPinLongPress,\n onStaticPinPress,\n pinProps,\n } = this.props;\n const { pinSize, touches, debugPoints = [] } = this.state;\n\n return (\n {\n this.props.onLayout?.(event);\n this.grabZoomSubjectOriginalMeasurements();\n }}\n >\n \n {children}\n \n\n {visualTouchFeedbackEnabled &&\n touches?.map(\n (touch) =>\n doubleTapDelay && (\n {\n this._removeTouch(touch);\n }}\n />\n )\n )}\n\n {/* For Debugging Only */}\n {debugPoints.map(({ x, y }, index) => {\n return ;\n })}\n\n {staticPinPosition && (\n {\n this.setState({ pinSize: size });\n }}\n pinProps={pinProps}\n />\n )}\n \n );\n }\n}\n\nconst styles = StyleSheet.create({\n container: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n overflow: 'hidden',\n position: 'relative',\n },\n zoomSubject: {\n alignItems: 'center',\n flex: 1,\n justifyContent: 'center',\n width: '100%',\n },\n});\n\nexport default ReactNativeZoomableView;\n\nexport { ReactNativeZoomableView };\n"]} \ No newline at end of file diff --git a/src/ReactNativeZoomableView.tsx b/src/ReactNativeZoomableView.tsx index 8e7e60c..6291149 100644 --- a/src/ReactNativeZoomableView.tsx +++ b/src/ReactNativeZoomableView.tsx @@ -1103,7 +1103,7 @@ class ReactNativeZoomableView extends Component< this.props.onZoomBefore?.(null, null, this._getZoomableViewEventObject()); // == Perform Pan Animation to preserve the zoom center while zooming == - let listenerId: string | undefined; + let listenerId = ''; if (zoomCenter) { // Calculates panAnim values based on changes in zoomAnim. let prevScale = this.zoomLevel; @@ -1134,7 +1134,6 @@ class ReactNativeZoomableView extends Component< // == Perform Zoom Animation == getZoomToAnimation(this.zoomAnim, newZoomLevel).start(() => { - if (!listenerId) return; this.zoomAnim.removeListener(listenerId); }); // == Zoom Animation Ends ==