panzoom
panzoom copied to clipboard
Might it be possible to use Panzoom with React components?
Hi and thanks for a great library! Unfortunately, I can select only html divs for Panzooming, but not React elements. Is there a way to use it with React? Many thanks!
up. I would be interested too
Since panzoom is a vanilla JS library, it just needs an HTML element to attach to. I've been able to use it with React by using useRef()
to get a reference to an actual HTML element, and then initializing panzoom itself in a useLayoutEffect()
callback.
Something like this should work:
import React, { useRef, useLayoutEffect } from 'react';
import panzoom from 'panzoom';
export const PanZoom = props => {
const elementRef = useRef(null);
const panzoomRef = useRef(null);
// Set up panzoom on mount, and dispose on unmount
useLayoutEffect(() => {
panzoomRef.current = panzoom(elementRef.current, {
minZoom: .25,
maxZoom: 4
});
panzoomRef.current.on('pan', () => console.log('Pan!'));
panzoomRef.current.on('zoom', () => console.log('Zoom!'));
return () => {
panzoomRef.current.dispose();
}
}, []);
return <div ref={elementRef}>
{/* Anything here */}
</div>
}
There might be some edge cases this doesn't handle, but it should at least be a starting point.
Hope this helps!
Since panzoom is a vanilla JS library, it just needs an HTML element to attach to. I've been able to use it with React by using
useRef()
to get a reference to an actual HTML element, and then initializing panzoom itself in auseLayoutEffect()
callback.Something like this should work:
import React, { useRef, useLayoutEffect } from 'react'; import panzoom from 'panzoom'; export const PanZoom = props => { const elementRef = useRef(null); const panzoomRef = useRef(null); // Set up panzoom on mount, and dispose on unmount useLayoutEffect(() => { panzoomRef.current = panzoom(elementRef.current, { minZoom: .25, maxZoom: 4 }); panzoomRef.current.on('pan', () => console.log('Pan!')); panzoomRef.current.on('zoom', () => console.log('Zoom!')); return () => { panzoomRef.current.dispose(); } }, []); return <div ref={elementRef}> {/* Anything here */} </div> }
There might be some edge cases this doesn't handle, but it should at least be a starting point.
Hope this helps!
Oh, thanks a million, dear Aaron! I'll try this out!
Saved my day! :)
If you want to do this in a class component, this might work :
import React, { Component, createRef} from 'react';
import panzoom from 'panzoom';
import image from './my-image.jpeg'; //use your custom image here
// const panzoom = require('./showImage.js')
class ShowImage extends Component {
constructor(props) {
super(props);
this.state = {
zoom : 0,
}
this.imageRef = createRef();
this.panZoomRef = createRef();
this.divPanZoomRef = createRef();
this.elementRef = createRef();
}
componentDidMount = () => {
this.panZoomRef.current = panzoom(this.elementRef.current, {
minZoom: .25,
maxZoom: 4
});
this.panZoomRef.current.on('pan', () => console.log('Pan!'));
this.panZoomRef.current.on('zoom', () => console.log('Zoom!'));
}
componentWillUnmount = () => {
this.panZoomRef.current.dispose();
}
render() {
return (
<div>
<div ref={this.elementRef}>
<img ref={this.imageRef} src={image} alt="My Photo" />
</div>
</div>
);
}
}
export default ShowImage ;