react-easy-panzoom
React components that enables pan and zoom features for any component. Try out the live demo here
Installation
react-panzoom requires React 16 or later.
Using npm
:
npm install --save react-easy-panzoom
Using yarn
:
yarn add react-easy-panzoom
Usage
// ... { return <PanZoom> 'This content can be panned and zoomed' </PanZoom> }
Key mapping
PanZoom
component natively supports keyboard interactions with arrow keys and -
/ +
keys. This mapping can be extends using the keyMapping
prop.
e.g. Mapping w
, a
, s
, d
:
// ... { return <PanZoom keyMapping= '87': x: 0 y: -1 z: 0 '83': x: 0 y: 1 z: 0 '65': x: -1 y: 0 z: 0 '68': x: 1 y: 0 z: 0 > 'This content can be panned and zoomed' </PanZoom> }
Prevent pan
Sometimes it can be useful to prevent the view from panning, for example if the pan start is done on a clickable element.
PanZoom
provides the preventPan
prop that let you define a function to prevent panning.
e.g. prevent panning when starting the pan on a specific div
content = null // preventPan gives access to the event, as well as the // mouse coordinates in the coordinate system of the PanZoom container { // if the target is the content container then prevent panning if etarget === content return true // in the case the target is not the content container // use the coordinates to determine if the click happened // on the content container const contentRect = content const x1 = contentRectleft const x2 = contentRectright const y1 = contentRecttop const y2 = contentRectbottom return x >= x1 && x <= x2 && y >= y1 && y <= y2} { return <PanZoom preventPan=thispreventPan > <div> 'This content can be panned and zoomed' </div> <div ref= thiscontent = ref> 'This content can be panned and zoomed only outside of its container' </div> </PanZoom> }
Boundaries
PanZoom
supports the enableBoundingBox
prop to restrict panning. The box is calculated based on the width and height of the inner content.
A ratio is applied so that the bounding box allows panning up to a specific percentage of the inner content.
By default this ratio is 0.8
but can be modified with boundaryRatioVertical
and boundaryRatioHorizontal
. In this case the pan content will be able to pan outside the parent container up to 80% of its size (the 20% remaining will always be visible).
A negative ratio will create a padding, but combined with zooming it can produce strange behaviour. A ratio above 1 will allow the pan content to pan outside the parent container more than its size.
To use the bounding box:
// ... { return <PanZoom boundaryRatioVertical=08 boundaryRatioHorizontal=08 enableBoundingBox > <div> 'This content can be panned and zoomed' </div> </PanZoom> }
Properties
Name | Type | Default | Description |
---|---|---|---|
autoCenter | bool |
false | Auto-center the view when mounting |
autoCenterZoomLevel | number |
Specify the initial zoom level for auto-center | |
zoomSpeed | number |
1 | Sets the zoom speed |
doubleZoomSpeed | number |
1.75 | Sets the zoom speed for double click |
disabled | bool |
false | Disable pan and zoom |
disableKeyInteraction | bool |
false | Disable keyboard interaction |
disableDoubleClickZoom | bool |
false | Disable zoom when performing a double click |
disableScrollZoom | bool |
false | Disable zoom when performing a scroll |
realPinch | bool |
false | Enable real pinch interaction for touch events |
keyMapping | object |
false | Define specific key mapping for keyboard interaction (e.g. { '<keyCode>': { x: 0, y: 1, z: 0 } } , with <keyCode> being the key code to map) |
minZoom | number |
Sets the minimum zoom value | |
maxZoom | number |
Sets the maximum zoom value | |
enableBoundingBox | boolean |
false | Enable bounding box for the panzoom element. The bounding box will contain the element based on a ratio of its size |
boundaryRatioVertical | number |
0.8 | Vertical ratio for the bounding box |
boundaryRatioHorizontal | number |
0.8 | Horizontal ratio for the bounding box |
noStateUpdate | bool |
true | Disable state update for each new x, y, z transform value while panning. Enabling it drastically increases the performances |
onPanStart | func |
Fired on pan start | |
onPan | func |
Fired on pan | |
onPanEnd | func |
Fired on pan end | |
preventPan | func |
Defines a function to prevent pan | |
style | object |
Override the inline-styles of the root element | |
onStateChange | func |
Called after the state of the component has changed |
You can also pass in every other props you would pass to a div
element. Those will be passed through to the container component. This is helpful for adding custom event handlers.
Methods
By using ref
, methods from PanZoom
can be accessed and called to trigger manipulation functions.
Available methods are listed below:
Name | Parameters | Description |
---|---|---|
zoomIn | (zoomSpeed?: number) |
Zoom in from the center of the PanZoom container |
zoomOut | (zoomSpeed?: number) |
Zoom out from the center of the PanZoom container |
autoCenter | (zoom: number, animate?: boolean = true) |
Center and resize the view to fit the PanZoom container |
reset | Reset the view to it's original state (will not auto center if autoCenter is enabled) |
|
moveByRatio | (x: number, y: number, moveSpeedRatio?: number) |
Move the view along x or/and y axis |
rotate | (angle: number \| (prevAngle) => newAngle) |
Rotate the view by the specified angle |
Thanks
This react library is based on the awesome panzoom by @anvaka.
License
The files included in this repository are licensed under the MIT license.