React
First, follow the installation instructions to add the NPM package @fancyapps/ui.
Use the usePanzoom hook sample code or create your own wrapper based on it:
js
import { useRef, useState, useCallback, useEffect } from "react"; import { Panzoom } from "@fancyapps/ui/dist/panzoom/"; import "@fancyapps/ui/dist/panzoom/panzoom.css"; import { canUseDOM } from "@fancyapps/ui/dist/utils/canUseDOM.js"; import { isEqual } from "@fancyapps/ui/dist/utils/isEqual.js"; export default function usePanzoom(options = {}) { const storedOptions = useRef(options); const [container, setContainer] = useState(null); const [panzoomInstance, setPanzoomInstance] = useState(undefined); const reInit = useCallback(() => { if (panzoomInstance) { panzoomInstance.destroy().init(); } }, [panzoomInstance]); useEffect(() => { if (!isEqual(options, storedOptions.current)) { storedOptions.current = options; reInit(); } }, [options, reInit]); useEffect(() => { if (canUseDOM() && container) { const newPanzoomInstance = Panzoom( container, storedOptions.current ).init(); setPanzoomInstance(newPanzoomInstance); return () => { newPanzoomInstance.destroy(); }; } else { setPanzoomInstance(undefined); } }, [container]); return [setContainer, panzoomInstance]; }ts
import { useRef, useState, useCallback, useEffect } from "react"; import { type PanzoomOptions, type PanzoomInstance, Panzoom, } from "@fancyapps/ui/dist/panzoom/"; import "@fancyapps/ui/dist/panzoom/panzoom.css"; import { canUseDOM } from "@fancyapps/ui/dist/utils/canUseDOM.js"; import { isEqual } from "@fancyapps/ui/dist/utils/isEqual.js"; export type PanzoomContainerRefType = <ContainerElement extends HTMLElement>( el: ContainerElement | null ) => void; export type usePanzoom = [PanzoomContainerRefType, PanzoomInstance | undefined]; export default function usePanzoom( options: Partial<PanzoomOptions> = {} ): usePanzoom { const storedOptions = useRef(options); const [container, setContainer] = useState<HTMLElement | null>(null); const [panzoomInstance, setPanzoomInstance] = useState< PanzoomInstance | undefined >(undefined); const reInit = useCallback(() => { if (panzoomInstance) { panzoomInstance.destroy().init(); } }, [panzoomInstance]); useEffect(() => { if (!isEqual(options, storedOptions.current)) { storedOptions.current = options; reInit(); } }, [options, reInit]); useEffect(() => { if (canUseDOM() && container) { const newPanzoomInstance = Panzoom( container, storedOptions.current ).init(); setPanzoomInstance(newPanzoomInstance); return () => { newPanzoomInstance.destroy(); }; } else { setPanzoomInstance(undefined); } }, [container]); return [setContainer, panzoomInstance]; }Usage:
ts
function App() { const [panzoomRef] = usePanzoom({ // Your custom options }); return ( <div ref={panzoomRef} style={{ height: "400px" }}> <img className="f-panzoom__content" src="https://lipsum.app/id/60/2000x1500" width="2000" height="1500" alt="Sample image" /> </div> ); }Here is a sample of how to access the Panzoom API:
ts
const [panzoomRef, panzoomInstance] = usePanzoom({ // Your custom options }); useEffect(() => { if (panzoomInstance) { // Access API console.log(panzoomInstance.getContainer()); } }, [panzoomInstance]);