Skip to content
This repository was archived by the owner on Nov 30, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"printWidth": 120,
"endOfLine": "crlf",
"endOfLine": "lf",
"quoteProps": "consistent",
"singleQuote": true,
"trailingComma": "all"
}
}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ These options can be used to limit and change the zoom behavior.
| movementSensibility | number | how resistant should shifting the view around be? (0.5 - 5) - higher is less sensitive | 1.9 |
| initialOffsetX | number | The horizontal offset the image should start at | 0 |
| initialOffsetY | number | The vertical offset the image should start at | 0 |
| contentAspectRatio | number | To provide if the children does not have the same aspect ratio as ReactNativeZoomableView | ReactNativeZoomableView onMount's aspect ratio |
| longPressDuration | number | Duration in ms until a press is considered a long press | 700 |
| captureEvent | boolean | Defines whether the pan responder of the parent element should be captured. (useful for react-native modals, set it to true) | false |

Expand Down
29 changes: 28 additions & 1 deletion src/ReactNativeZoomableView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -267,12 +267,13 @@ class ReactNativeZoomableView extends Component<ReactNativeZoomableViewProps, Re
containerSize: number,
elementSize: number,
zoomLevel: number,
startOffset: number,
) {
const zoomLevelOffsetValue = zoomLevel * offsetValue;

const containerToScaledElementRatioSub = 1 - containerSize / elementSize;
const halfLengthPlusScaledHalf = 0.5 + 0.5 / zoomLevel;
const startBorder = containerSize * containerToScaledElementRatioSub * halfLengthPlusScaledHalf;
const startBorder = containerSize * containerToScaledElementRatioSub * halfLengthPlusScaledHalf + startOffset;
const endBorder = (containerSize + startBorder - containerSize) * -1;

// calculate distance to start and end borders
Expand Down Expand Up @@ -342,6 +343,8 @@ class ReactNativeZoomableView extends Component<ReactNativeZoomableViewProps, Re
* @private
*/
_bindOffsetValuesToBorders(changeObj, bindToBorders = null) {
const { contentAspectRatio } = this.props;

// if bindToBorders is disabled -> nothing do here
if (bindToBorders === false || (bindToBorders === null && !this.props.bindToBorders)) {
return changeObj;
Expand All @@ -352,13 +355,36 @@ class ReactNativeZoomableView extends Component<ReactNativeZoomableViewProps, Re
const currentElementWidth = originalWidth * changeObj.zoomLevel;
const currentElementHeight = originalHeight * changeObj.zoomLevel;

let croppedWidthInPx = 0;
let croppedHeightInPx = 0;

// if the content and container doesn't have the same aspect ratio,
// we must allow a pan movement toward the part of the content that was truncated originally
if (contentAspectRatio) {
// gentle reminder for the following logic:
// RATIO = W / H
// H = W / RATIO
// W = H * RATIO

const aspectRatioOnMount = originalHeight && originalWidth ? originalWidth / originalHeight : 1;

const wasWidthCroppedOnMount = aspectRatioOnMount < contentAspectRatio;

if (wasWidthCroppedOnMount) {
croppedWidthInPx = originalHeight * contentAspectRatio - originalWidth;
} else {
croppedHeightInPx = originalWidth / contentAspectRatio - originalHeight;
}
}

// make sure that view doesn't go out of borders
const offsetXBound = this._getBoundOffsetValue(
'x',
changeObj.offsetX,
originalWidth,
currentElementWidth,
changeObj.zoomLevel,
croppedWidthInPx / 2,
);
changeObj.offsetX = offsetXBound;

Expand All @@ -368,6 +394,7 @@ class ReactNativeZoomableView extends Component<ReactNativeZoomableViewProps, Re
originalHeight,
currentElementHeight,
changeObj.zoomLevel,
croppedHeightInPx / 2,
);
changeObj.offsetY = offsetYBound;

Expand Down
1 change: 1 addition & 0 deletions src/typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ declare module '@dudigital/react-native-zoomable-view' {
initialZoom?: number;
initialOffsetX?: number;
initialOffsetY?: number;
contentAspectRatio?: number;
maxZoom?: number;
minZoom?: number;
doubleTapDelay?: number;
Expand Down