Image Pan and Zoom with Commenting in React

React Image Pan And Zoom With Commenting

Screenshot

Nifty Gateway has developed a React component for image pan and zoom, allowing users to comment on any part of an image. This component was recently utilized in a project with Sam Spratt called the Monument Game. It enables users to zoom and pan around a 20,000-pixel-wide image, creating a more interactive and immersive user experience.

The component can function independently as a standalone image pan and zoom viewer. However, if you aim to support commenting, the component offers the necessary properties for integration with your custom backend. Moreover, if commenting is enabled, and comments are persisted to your backend, you can deep-link to a specific comment via query parameters in the URL (?x=0.6016064257028112&y=0.6058201058201058). Simply provide the x and y coordinates, and the component will load the pan and zoom experience, highlighting the specified comment at those coordinates.

Why Do I Need to Provide A Src and SmallerSrc?

For desktop use, if you’re employing an image with a width equal to or less than 10,000 pixels, props.smallerSrc can be left undefined. However, for larger images, providing an image for props.smallerSrc may enhance zoom performance. The image specified for props.smallerSrc will only be displayed when a user zooms in and if the current zoom width of an image is less than or equal to the intrinsic width of props.smallerSrc. During development, we discovered that the Chrome browser struggles to provide a smooth zooming experience for images beyond 10,000 pixels in width. To address this issue, we introduced the option to supply a lower resolution image for display during zoom, significantly improving performance in Chrome browsers.

For mobile use, it’s advisable to limit the maximum width of an image to 10,000 pixels. During development, we found that using an image exceeding 10,000 pixels could randomly crash the browser or refresh the page. You can leave props.smallerSrc undefined, especially for images equal to or less than 5,000 pixels in width, but results may vary.


In the future, we plan to explore a version that supports image tiling. If you’d like to initiate work on this feature, feel free to open a pull request!

Data Flow Diagram on Commenting Flow

You can also take a look at the usage example below titled, Advanced Usage Showing How You can Tie in With A Custom Backend To Persist Comments

Screenshot

React Props

Prop NameDescriptionIs Required?Default ValueTypesrcURL of main image to use for pan and zoomYesstringsmallerSrcURL of the main image on a smaller scale, used for pan and zoom. Displayed during zoom and after zoom if the current zoom width is <= intrinsic width of the provided imageOptionalundefinedstring OR undefinedpreviewBoxSrcURL of the image displayed in the pan and zoom preview box. Image width should be no larger than 100 pixelsYesstringcommentsList of comments and their coordinatesOptionalundefined{ x: number, y: number, comment: string}[] OR undefinedisLoadingFlag to indicate whether we are some loading stateOptionalFALSEbooleanisCommentSubmitLoadingFlag to indicate whether we are in loading state for submitting a new commentOptionalFALSEbooleanenableCommentDropFlag to toggle whether we allow comments to be dropped when pan and zoom is activeOptionalTRUEbooleanenablePanAndZoomControlsFlag to toggle display of pan and zoom controls (ie. zoom in/out button and reset zoom button)OptionalTRUEbooleanenablePanAndZoomPreviewFlag to toggle the display of a smaller version of the image indicating your current pan location locationOptionalTRUEbooleanpersistCommentDrawerWhenOpenFlag to toggle whether the Comment Drawer stays open while the user interacts with pan and zoom. Recommended to set to false for better mobile user experienceOptionalTRUEbooleanaddingCommentsToTheFrontFlag to indicate whether new comments are being added to the front of the comments array or at the endOptionalFALSEbooleanzoomToPercentNumeric value between 25-50 to indicate what percent value to set when a user clicks on a comment within the Comment DrawerOptional50numberdotSizeNumeric value to indicate comment dot size in pixelsOptional20numberbuttonEnablePanZoomTextText on button to enable pan and zoomOptionalObservestringmakeObservationTextText when pan and zoom is enabled and commenting is allowed to indicate a user can leave a commentOptionalMake ObservationstringcommentDialogHeadingTextText for Comment Dialog headingOptionalWhat Do You See?stringcommentDialogSecondaryHeadingTextText for Comment Dialog secondary headingOptionalMake an observation.stringcommentDialogConfirmHeadingTextText for Comment Dialog confirmation headingOptionalConfirmationstringcommentDialogConfirmSecondaryHeadingTextText for Comment Dialog confirmation secondary headingOptionalAs a last step please confirm your submission. Once it’s submitted, it can’t be undone.stringcommentDialogConfirmCheckboxTextText to accompany Comment Dialog checkboxOptionalI understand this can’t be undonestringcommentDialogTextAreaPlaceholderTextPlaceholder text for Comment Dialog textareaOptionalstringcommentDialogCancelButtonTextText for Comment Dialog Cancel button when user is in pre-confirmation stateOptionalCancelstringcommentDialogBackButtonTextText for Comment Dialog Back button when user is in confirmation stateOptionalBackstringcommentDialogReviewButtonTextText for Comment Dialog Review button when user is in pre-confirmation stateOptionalReviewstringcommentDialogSubmitButtonTextText for Comment Dialog Submit button when user is in confirmation stateOptionalSubmitstringprimaryColorPrimary color (hex or rgba)Optional#fffstringsecondaryColorSecondary color (hex or rgba)Optional#000stringtertiaryColorTertiary color (hex or rgba)Optional#aaastringdotColorComment dot color (hex or rgba)OptionalredstringactiveDotColorActive comment dot color (hex or rgba)OptionalorangestringimgLoaderReact component or string to display when main image is loadingOptionalundefinedReact.ReactElement OR string OR undefinedzoomSupportLoaderReact component or string to display when zoom support image is being loaded. This will only come into play if you are using a very large image (10,000+ pixels in width) for props.srcOptionalundefinedReact.ReactElement OR string OR undefinederrorDisplayReact component or string to display when an error is encountered during main image loadOptionalundefinedReact.ReactElement OR string OR undefinedonCommentSubmitCallback function called when a new comment is submittedOptionalundefinedFunction OR undefinedonImageLoadCallback function called when the main image has loadedOptionalundefinedFunction OR undefinedonTogglePanAndZoomCallback function called when pan and zoom is toggled on/offOptionalundefinedFunction OR undefined

Demo

https://gemini-oss.github.io/react-image-pan-and-zoom-with-commenting/

Installation

yarn add react-image-pan-and-zoom-with-commenting
npm i react-image-pan-and-zoom-with-commenting

Basic Usage Image Pan And Zoom With Commenting

import ImagePanAndZoom from 'react-image-pan-and-zoom-with-commenting';

const App = () => {
    return (
        <App src='LINK_TO_IMAGE' previewSrc='LINK_TO_PREVIEW_IMAGE' />
    )
}

export default App

Basic Usage Image Pan And Zoom Only

import ImagePanAndZoom from 'react-image-pan-and-zoom-with-commenting';

const App = () => {
    return (
        <App src='LINK_TO_IMAGE' previewSrc='LINK_TO_PREVIEW_IMAGE' enableCommentDrop={false} />
    )
}

export default App

Advanced Usage Showing How You can Tie in With A Custom Backend To Persist Comments

import ImagePanAndZoom from 'react-image-pan-and-zoom-with-commenting';

const App = () => {
  const [isCommentSubmitLoading, setIsCommentSubmitLoading] =
    React.useState(false);
  const [isLoading, setIsLoading] = React.useState(true);
  const [comments, setComments] = React.useState<CommentDotProps[]>([]);

  const handleCommentSubmit = (comment: CommentDotProps) => {
    setIsCommentSubmitLoading(true);

    // Simulate a POST request to save a new comment
    setTimeout(() => {
      setComments([...comments, { ...comment }]);
      setIsCommentSubmitLoading(false);
    }, 3000);
  };

  React.useEffect(() => {
    // Simulate a GET request to retrieve existing comments 
    setTimeout(() => {
      setComments([
        {
          x: 0.6016064257028112,
          y: 0.6058201058201058,
          comment: "Lorem ipsum dolor sit amet. Et quod alias qui sequi labore est nostrum debitis sed officiis laborum qui ipsam consequuntur in rerum unde et recusandae quibusdam. Cum iste repudiandae sit sint placeat sed quia velit et quidem doloribus qui doloremque unde est asperiores similique.",
        },
        {
          x: 0.7653844927601894,
          y: 0.4520125762495482,
          comment:
            "Ut ipsum numquam qui expedita dolorem cum quaerat consequatur ut natus laudantium aut aspernatur laboriosam et asperiores assumenda. Ea voluptatem neque non quia laborum ut consequatur voluptatum in voluptas debitis et quisquam quidem. Ut ipsum numquam qui expedita dolorem cum quaerat consequatur ut natus laudantium aut aspernatur laboriosam et asperiores assumenda. Ea voluptatem neque non quia laborum ut consequatur voluptatum in voluptas debitis et quisquam quidem.",
        },
        {
          x: 0.45380107538609804,
          y: 0.6221498059102408,
          comment: "Rem aliquam galisum sed ducimus velit aut natus magni vel illum tempora est voluptatem vero et quam culpa eos sequi nostrum. Sed aliquam nihil ut fugit amet aut rerum dolorem et tempora voluptas et vitae repellendus et itaque dolor.",
        },
      ]);
      setIsLoading(false);
    }, 2000);
  }, []);

  return (
    <App
      src='LINK_TO_IMAGE'
      previewBoxSrc='LINK_TO_PREVIEW_IMAGE'
      comments={comments}
      isLoading={isLoading}
      isCommentSubmitLoading={isCommentSubmitLoading}
      onCommentSubmit={handleCommentSubmit}
    />
  );
};

export default App

ClassNames You Can Target

ComponentDescriptionClassNameActive CommentComponent used to display an active comment.active-commentComment DialogComponent used to allow comment entry.comment-dialogComment Display SwitchComponent used to toggle comment display.comment-display-switchComment DrawerComponent used to display list of comments.comment-drawerComment Drawer BackdropComponent used to backdrop for list of comments.comment-drawer-tintDot ContainerContainer component to house comment dots.dot-containerDot Container DotsComponent used for a comment dot.button–dotImage Pan And ZoomComponent used for image pan and zoom.image-pan-and-zoom

GitHub

View Github


Related Posts

Recent Posts

ഇടുക്കിയിലെ മലയോര മേഖലകളിൽ രാത്രിയാത്ര നിരോധിച്ചു. രാത്രി ഏഴു മുതൽ രാവിലെ ആറു വരെയാണ് നിരോധനം

ഏന്തയാർ ഈസ്റ്റിൽ പ്രളയത്തിൽ തകർന്ന പാലത്തിന് പകരം പുതിയ പാലം നിർമ്മിക്കുവാൻ താത്ക്കാലിക പാലം പൊളിച്ച് നീക്കി

Explore the Investment Opportunities: A Comprehensive Guide to Different Types of Mutual Funds

Title: Understanding Mutual Funds: A Beginner's Guide to Investing

തീവ്രമഴ മുന്നറിയിപ്പിന്റെ പശ്ചാതലത്തിൽ സംസ്ഥാനം ജാഗ്രതയിൽ

250,000 അപേക്ഷകൾ വർദ്ധിച്ചതിനാൽ ട്രാൻസ്‌പോർട്ട് കമ്മീഷണർ പരിശോധന പുനരാരംഭിക്കും

ഏലക്കയിൽ കീടനാശിനി സാന്നിധ്യം; ആറര ലക്ഷത്തിലധികം ടിൻ അരവണ നശിപ്പിക്കാൻ ടെൻഡർ ക്ഷണിച്ച് ദേവസ്വം ബോർഡ്‌

ഭീമൻ പാറക്കഷണങ്ങൾ അടർന്ന് ദേശീയ പാതയിലേക്ക് വീഴുന്നത് പതിവാകുന്നു. കുട്ടിക്കാനത്തിനും മുണ്ടക്കയത്തിനുമിടയിൽ നിലനിൽക്കുന്നത് വൻ അപകട ഭീഷണി

ചക്രവാതച്ചുഴി:അതിശക്തമായ മഴ വരുന്നു

പ്ലസ് വൺ പ്രവേശനം. അക്ഷയയിൽ തിക്കി തിരക്കേണ്ട, നെറ്റിവിറ്റി/ജാതി തെളിയിക്കാൻ പത്താംതരം സർട്ടിഫിക്കറ്റ് മതി