Skip to content

Commit

Permalink
Allow changing zoom level without interfering with pan offsets (#130)
Browse files Browse the repository at this point in the history
* fix

* doc

* version

* simpler

---------

Co-authored-by: thomasvo <[email protected]>
  • Loading branch information
thomasttvo and thomasvo authored Jan 10, 2025
1 parent be3572b commit b175c42
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 73 deletions.
41 changes: 22 additions & 19 deletions lib/commonjs/ReactNativeZoomableView.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/commonjs/ReactNativeZoomableView.js.map

Large diffs are not rendered by default.

41 changes: 22 additions & 19 deletions lib/module/ReactNativeZoomableView.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/module/ReactNativeZoomableView.js.map

Large diffs are not rendered by default.

7 changes: 2 additions & 5 deletions lib/typescript/ReactNativeZoomableView.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,9 @@ declare class ReactNativeZoomableView extends Component<ReactNativeZoomableViewP
* { 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 - If not supplied, the container's center is the zoom center
*/
zoomTo(newZoomLevel: number, zoomCenter?: {
x: number;
y: number;
}): boolean;
zoomTo(newZoomLevel: number, zoomCenter?: Vec2D): boolean;
/**
* Zooms in or out by a specified change level
* Use a positive number for `zoomLevelChange` to zoom in
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
59 changes: 32 additions & 27 deletions src/ReactNativeZoomableView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1093,41 +1093,46 @@ 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 - If not supplied, the container's center is the zoom center
*/
zoomTo(newZoomLevel: number, zoomCenter = { x: 0, y: 0 }) {
zoomTo(newZoomLevel: number, zoomCenter?: Vec2D) {
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.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 = '';
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(() => {
this.zoomAnim.removeListener(listenerId);
});
Expand Down

0 comments on commit b175c42

Please sign in to comment.