Adding Animated Image Zoom to Your React App with PhotoSwipe

PulkitPulkit
3 min read

In one of my recent projects(image-tweaker), I provided users with the ability to upload images, which were then displayed in a collection on the dashboard. I was searching for a way to give these images a cool animated view, and that's when I discovered PhotoSwipe!

PhotoSwipe is a powerful, easy-to-use JavaScript library that allows you to create beautiful, animated image galleries. It provides a smooth and responsive experience, making your image collections look stunning on any device.

Let's make an image gallery in React with the react-photoswipe-gallery.

Let's Start by Bootstrapping a Fresh React-TS App

npm create vite@latest react-app-gallery -- --template react
cd react-app-gallery
npm install
npm run dev

And just like that, we have our plain Vite React app ready to go!

This will set up a new React project with TypeScript support. You should see a default Vite React app running at http://localhost:3000.

Clean Up the Default Setup

You can also remove the default CSS in App.css and index.css.

export default function App() {
  return <div>App</div>;
}

Adding PhotoSwipe

Now let's start adding the dependencies

npm i react-photoswipe-gallery photoswipe

Include the CSS file from photoswipe. (As a best practice, I typically add these types of default CSS files in main.tsx.)

import "photoswipe/dist/photoswipe.css";

Now, let's create a simple image gallery using react-photoswipe-gallery. Update App.tsx with the following code:

Add some images and include their links in App.tsx, like this:

import Image1 from "./assets/image1.png";
import Image2 from "./assets/image2.png";
import Image3 from "./assets/image3.png";

make an array of images(you can use external links as well)

const images = [Image1, Image2, Image3];

Now, to add the photoswipe gallery, let's wrap the images in Gallery.

import { Gallery, Item } from "react-photoswipe-gallery";

import Image1 from "./assets/image1.png";
import Image2 from "./assets/image2.png";
import Image3 from "./assets/image3.png";

export default function App() {
  const images = [Image1, Image2, Image3];
  return (
    <Gallery>
      // images here
    </Gallery>
  );
}

A single image inside the gallery looks like this:

<Item original={image} width="1024" height="768">
  {({ ref, open }) => (
    <img
      ref={ref}
      onClick={open}
      src={image}
      style={{
        width: "200px",
        height: "200px",
      }}
    />
  )}
</Item>

This code creates an image item within a gallery using the react-photoswipe-gallery library. Here's a breakdown of this spooky code:

  • <Item>: This is a component from the react-photoswipe-gallery library that represents a single image item in the gallery.

    • original={image}: This prop sets the original, full-size image source.
  • {({ ref, open }) => (...)}: This is a render prop function that provides two arguments:

    • ref: A reference to the image element, used to track and manipulate the DOM element.

    • open: A function that opens the image in the gallery when called.

But we have an array of images, so we simply map the array

{images.map((image, index) => (
  <Item key={index} original={image} width="1024" height="768">
    {({ ref, open }) => (
      <img
        ref={ref}
        onClick={open}
        src={image}
        style={{
          width: "200px",
          height: "200px",
        }}
      />
    )}
  </Item>
))}

Currently, the image appears quite congested.

Just so as to add some breathing space let's add some styles

style={{
  width: "200px",
  height: "200px",
  margin: 10,
  cursor: "pointer",
  borderRadius: 10,
}}

And yes, it works fine now, here's the complete code

import { Gallery, Item } from "react-photoswipe-gallery";

import Image1 from "./assets/image1.png";
import Image2 from "./assets/image2.png";
import Image3 from "./assets/image3.png";

export default function App() {
  const images = [Image1, Image2, Image3];
  return (
    <Gallery>
      {images.map((image, index) => (
        <Item key={index} original={image} width="1024" height="768">
          {({ ref, open }) => (
            <img
              ref={ref}
              onClick={open}
              src={image}
              style={{
                width: "200px",
                height: "200px",
                margin: 10,
                cursor: "pointer",
                borderRadius: 10,
              }}
            />
          )}
        </Item>
      ))}
    </Gallery>
  );
}

Here's the final version!

With these changes, your image gallery should now look much cleaner and more user-friendly. The added margin and rounded corners give each image some breathing room and a polished appearance. Enjoy your improved gallery!

1
Subscribe to my newsletter

Read articles from Pulkit directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Pulkit
Pulkit

Hi there! ๐Ÿ‘‹ I'm Pulkit, a passionate web and app developer specializing in MERN and React Native technologies. With a keen interest in open-source contributions and competitive programming, I love building innovative solutions and sharing my knowledge with the community. Follow along for insights, tutorials, and updates on my coding journey!