rlamana / react-pig

Arrange images in a responsive, progressive-loading grid managed in JavaScript using CSS transforms.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

react-pig

Arrange images in a responsive, progressive-loading grid managed in JavaScript using CSS transforms.

View Demo

NPM npm bundle size JavaScript Style Guide

A re-implementation of @schlosser's pig.js in React.

Instead of hosting images locally I've used Cloudinary - an image hosting provider, which adds the benefit of on-the-fly image resizing. So we don't need to worry about managing/generating multiple versions of an image at different resolutions. Like the original version of Pig.js we still need to provide an array of objects containing metadata about each image. I've created a node script upload.js to do this for us, see below section on upload.js.

In addition each image is now clickable and will expand to the center of the screen. It uses React Spring to handle the transition.

upload.js

Using this file assumes you are using Cloudinary as your image hosting provider. You could take the concepts within it and write it for your own image hosting provider of choice.

Running the file will;

  • Loop through a local folder of images and uploads them all to Cloudinary
  • Generates metadata for each image, including url, aspectRatio, dominant colour (useful for preload styling), file birthtime (useful for sorting photos by date) and exif data.
  • On completion of the upload, it generates a JSON file containing metadata about the collection of images. This JSON file can then be plugged into Pig.

To use upload.js

  1. Create a Cloudinary account.
  2. Create a file named .env and save it in the same folder as upload.js. Paste in the following with your Cloudinary credentials filled out;
cloud_name="abc123"
api_key="1234567890"
api_secret="yourapisecret"
  1. Run the file thusly node upload --in=./imgs/ --out=./imageData.json --cloudinaryFolder=whatever
  • --in - your local folder where your images are at
  • --out - the output JSON file
  • --cloudinaryFolder - the folder in Cloudinary (optional)

For Apple Photos users

The Apple Photos app conveniently has a feature where it can export your photos into folders named with location and date. upload.js will use these folder names to automatically add location and date meta data to the images. This is useful for grouping images later. To export your images from Apple Photos;

  1. Select all images to export
  2. File -> Export -> Export Photos -> Filename: Use Title & Subfolder Format: Moment Name
  3. When running upload.js just point it at the generated folder.

generateJSON.js

This file can be used if you've already uploaded your images to Cloudinary and just want to generate the JSON file for them. Assuming you have a Cloudinary account and have set up your .env file accordingly, you can run this file with;

node generateJSON --cloudinaryFolder=whateverFolderYouWantJsonFor --out=./outputFilename.json

Example usage of react-pig

yarn add react-pig
# or
npm i react-pig
import Pig from 'react-pig'
import imageData from './imageData.json' // the file generated by upload.js

class App extends Component {
  render() {
    return (
      <Pig
        imageData={imageData} // Array. Required.
        groupByDate // Boolean. Optional. Groups images by 'date' value. And uses the first 'location' in the group for the heading text.
        gridGap={10} // Integer. Optional. Defaults to 8
        expandedSize={1600} // Integer. Optional. Expanded image will be loaded in that size. Defaults to 1000
        thumbnailSize={25} // Integer. Optional. Thumbnail image will be loaded in that size. Defaults to 10
        sortFunc={(a, b) => a.imageOrder > b.imageOrder} // Function. Optional. Used for sorting images f.ex. if you add custom fields to the json file
        bgColor="#fff" // String. Optional. Used for outlines when image is expanded, and for group headings
        getUrl={(url, pxHeight) => {
          // Pig calls this function every time it needs to fetch an image.
          // The url arg will be provided as is from imageData
          // Assuming the imageData was generated using upload.js, the url string will contain {{HEIGHT}}
          // The purpose of this function is to replace {{HEIGHT}} value with a dynamic value (which is passed in with pxHeight)
          // Eg this:
          // http://res.cloudinary.com/cloudinaryusername/image/upload/h_{{HEIGHT}}/v12345678/cloudinaryfolder/image.jpg
          // Becomes this:
          // http://res.cloudinary.com/cloudinaryusername/image/upload/h_800/v12345678/cloudinaryfolder/image.jpg
          // This gives you flexibility to define what the url looks like in case you're using something other than Cloudinary.
          // getUrl is optional.
          // If you omit this prop completely, Pig will do exactly this;
        }}
      />
    )
  }
}

export default App

Todo:

  • Tests
  • Clear up readme
  • Fix group heading text alignment
  • Possibly provide a value to group by?
  • Conditional rendering based on users scroll speed
  • Dont expand if expanded size is less than container width
  • expanded tile outline based on gridgap
  • Group by months
  • bug: resizing isn't setting width correctly in tile
  • Use resize observer instead of scroll/resize listeners
  • Convert this package into a module
  • Proptype checks

This React library was packaged with https://github.com/transitive-bullshit/create-react-library

License

MIT © nickmcmillan

About

Arrange images in a responsive, progressive-loading grid managed in JavaScript using CSS transforms.


Languages

Language:JavaScript 92.0%Language:CSS 7.0%Language:HTML 1.0%