Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Might it be possible to use Panzoom with React components? #212

Open
ZenBerry opened this issue Sep 10, 2020 · 5 comments
Open

Might it be possible to use Panzoom with React components? #212

ZenBerry opened this issue Sep 10, 2020 · 5 comments

Comments

@ZenBerry
Copy link

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!

@blarfoon
Copy link

up. I would be interested too

@acmertz
Copy link

acmertz commented Sep 17, 2020

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!

@ZenBerry
Copy link
Author

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!

@cgpro
Copy link

cgpro commented Nov 21, 2020

Saved my day! :)

@dguari1
Copy link

dguari1 commented Dec 11, 2022

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 ;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants