Skip to content

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]);