@wokwi/react-easy-panzoom
v0.6.0
Published
Wrapper to enable pan and zoom for any React component
Downloads
27
Readme
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
import { PanZoom } from 'react-easy-panzoom'
// ...
render() {
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
:
import { PanZoom } from 'react-easy-panzoom'
// ...
render() {
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
preventPan = (event, x, y) => {
// if the target is the content container then prevent panning
if (e.target === 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.getBoundingClientRect()
const x1 = contentRect.left
const x2 = contentRect.right
const y1 = contentRect.top
const y2 = contentRect.bottom
return (x >= x1 && x <= x2) && (y >= y1 && y <= y2)
}
render() {
return (
<PanZoom
preventPan={this.preventPan}
>
<div>{ 'This content can be panned and zoomed' }</div>
<div ref={ref => this.content = 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:
import { PanZoom } from 'react-easy-panzoom'
// ...
render() {
return (
<PanZoom
boundaryRatioVertical={0.8}
boundaryRatioHorizontal={0.8}
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.