panzoom icon indicating copy to clipboard operation
panzoom copied to clipboard

Might it be possible to use Panzoom with React components?

Open ZenBerry opened this issue 4 years ago • 5 comments

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!

ZenBerry avatar Sep 10 '20 14:09 ZenBerry

up. I would be interested too

blarfoon avatar Sep 10 '20 16:09 blarfoon

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!

acmertz avatar Sep 17 '20 02:09 acmertz

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!

Oh, thanks a million, dear Aaron! I'll try this out!

ZenBerry avatar Sep 19 '20 17:09 ZenBerry

Saved my day! :)

cgpro avatar Nov 21 '20 09:11 cgpro

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 ;

dguari1 avatar Dec 11 '22 22:12 dguari1