Pan and zoom elements in React using gestures, mouse, touchpad, keyboard shortcuts and UI buttons.
npm install react-viewer-pan-zoom> Pan and zoom elements in React using gestures, mouse, touchpad, keyboard shortcuts and UI buttons.

* 💡 Designed to pan and zoom elements via react-inlinesvg, , , and other html elements.
* 🧭 Supports minimap, spring animation, rubberband, responsive design, etc.
* 🛠️ Written in Typescript. Built on top of use-gesture and CSS transitions.
* 🚀 Using fast build tools (Vite / Rollup).
``bash`
npm install react-viewer-pan-zoom

Check out this live example.
The layout size of the viewer must be specified via CSS!
Two variants of the viewer (full-window and fixed-size) are shown in example/src/App.tsx.
⚠️ IMPORTANT: For the full-window viewer, make sure that the main CSS file contains the following:
`css`
html, html body, #root { height: 100%; margin: 0; padding: 0; }
⚡️ Jump Start
`jsx
import { useContext } from 'react'
import { Viewer, ViewerContext, ViewerProvider } from 'react-viewer-pan-zoom'
const App = () => {
// // Example Layout #1: Full-window viewer
// const layoutStyle = {
// display: 'flex',
// flexDirection: 'column',
// userSelect: 'none',
// height: '100vh',
// // ⚠️ IMPORTANT: make sure that the main CSS file contains the following:
// // html, html body, #root { height: 100%; margin: 0; padding: 0; }
// }
// Example Layout #2: Fixed-size viewer
const layoutStyle = {
display: 'flex',
flexDirection: 'column',
userSelect: 'none',
width: '800px',
height: '600px'
}
const contentStyle = {
width: '100%',
height: '100%',
objectFit: 'contain', // 'contain', 'cover', 'fill', 'scale-down', ...
objectPosition: 'center', // 'center', 'left', 'right', ...
border: '1px solid #ccc',
}
const content =
return (
const Toolbar = () => {
const { settings, zoomOut, zoomIn, resetView, centerView, toggleMinimap, crop } = useContext(ViewerContext)
return (
<>
{settings.zoom.enabled && (
<>
{{(crop.zoom * 100).toFixed(0)}%}
{(settings.resetView.enabled) && }
{(settings.centerView.enabled) && }
{(settings.minimap.enabled) && }
>
)}
>
)
}
export default App
`
Default settings:
`jsxfalse
{
pan: { enabled: true }, // Enable or disable panning functionality.
zoom: {
enabled: true, // Enable or disable zoom functionality.
default: 1, // Default zoom level when the viewer is loaded.
min: 1, // Minimum zoom level.
max: 4, // Maximum zoom level.
mouseWheelStep: 0.5, // How much zoom per mouse wheel step.
zoomButtonStep: 0.5, // How much zoom per zoom button click.
},
resetView: {
enabled: true, // Enable or disable the "reset view" feature.
keyboardShortcut: 'r', // The keyboard shortcut to trigger the reset view (set to to disable).false
},
centerView: {
enabled: false, // Enable or disable the "center view" feature.
keyboardShortcut: 'c', // The keyboard shortcut to center the view (set to to disable).false
},
minimap: {
enabled: true, // Enable or disable the minimap.
width: '160px', // Width of the minimap.
keyboardShortcut: 'm', // The keyboard shortcut to toggle the minimap (set to to disable).true
outlineStyle: '1px solid #ccc', // Outline style for the minimap.
viewportAreaOutlineStyle: '2px solid #333', // Outline style for the viewport area on the minimap.
},
spring: {
enabled: true, // Enable or disable spring animations for smooth transitions.
rubberband: true, // Enable or disable rubberband effect when zooming or panning.
rubberbandDistance: 100, // Distance to trigger the rubberband effect.
transition: 'transform 0.1s ease-out', // Spring CSS Transition
},
guides: {
enabled: false, // Enable or disable guides.
},
fillHeight: true, // Set to to make the viewer fill all available height in the parent container.``
}
MIT © michelesandroni