• Stars
    star
    357
  • Rank 119,149 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 8 years ago
  • Updated almost 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

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

Progressive Image Grid (pig.js)

npm Bower

→ → Play with a demo

Arrange images in a responsive, progressive-loading grid managed in JavaScript using CSS transforms, with one lightweight library. Here's what you get:

  1. Performance: The pig.js grid specializes in displaying a large number of photos. While a more traditional approaches would paginate images, or use AJAX to load and insert buckets of additional images onto the page, pig.js intelligently loads and unloads images as you scroll down the page, to ensure ensure speedy rendering of images, smooth scrolling, and minimal network activitiy.
  2. Responsiveness: Images are loaded in JavaScript, at different resolutions depending on screen size. Also, because images are positioned using CSS transforms, images smartly re-tile when you shrink or expand the browser window.
  3. User Experience: Images are previewed with a small placeholder image that is scaled and blured. When the image loads, it gives the effect that the image was brought into focus (it's super cool!).

A lot of this is stolen straight from Google Photos (by way of observation and some creative use of the Chrome Inspector) and Medium (by way of some dope blog posts).

If you want to see pig.js in action, check out the site that motivated it in the first place: a catalog of everything I ate in 2015: feeding.schlosser.io. That site is also on GitHub.

Getting Started

Step 0: Install

Download the latest release.

Step 1: Create your markup

<!-- Include the pig.js library -->
<script src="/path/to/pig.min.js"></script>

<!-- Create a container element for the grid. -->
<div id="pig"></div>

Step 2: Create a structure to serve your images

Pig includes by default an easy method for handling responsive images at different screen sizes. By default, Pig will attempt to request images with size (height in pixels) 100, 250, and 500. It will also request a thumbnail 20px tall, which is used to create an effect of the blurred image coming into focus.

Example: Serving Static Files

Create a directory structure like:

.
├── index.html
├── path
│   └── to
│       └── pig.min.js
├── img
│   ├── 20
│   |   ├── blue.jpg
│   |   ├── red.jpg
│   |   ...
│   |
│   ├── 100
│   |   ├── blue.jpg
│   |   ├── red.jpg
│   |   ...
│   |
│   ├── 250
│   |   ├── blue.jpg
│   |   ├── red.jpg
│   |   ...
│   |
│   └── 500
│       ├── blue.jpg
│       ├── red.jpg
│       ...
...

And then set the urlForSize configuration option to account for this structure:

var options = {
  urlForSize: function(filename, size) {
    return '/img/' + size + '/' + filename;
  },
  // ...
};

Step 3: Create a new Pig instance, passing image data and options

var imageData = [
  {filename: 'blue.jpg', aspectRatio: 1.777},
  {filename: 'red.jpg', aspectRatio: 1.5},
  {filename: 'green.jpg', aspectRatio: 1.777},
  {filename: 'orange.jpg', aspectRatio: 1.777},
  {filename: 'yellow.jpg', aspectRatio: 1},
  {filename: 'purple.jpg', aspectRatio: 2.4},
];

var options = {
  urlForSize: function(filename, size) {
    return '/img/' + size + '/' + filename;
  },
  // ...
};

var pig = new Pig(imageData, options).enable();

API

Pig(imageData[, options])

The Pig constructor will setup a new progressive image grid instance. It returns a new instance of the Pangea class.

imageData (array)

Note: This argument is required.

A list of objects, one per image in the grid. In each object, the filename key gives the name of the image file and the aspectRatio key gives the aspect ratio of the image. The below example shows how you would pass six images into the PIG:

var imageData = [
  {filename: 'blue.jpg', aspectRatio: 1.777},
  {filename: 'red.jpg', aspectRatio: 1.5},
  {filename: 'green.jpg', aspectRatio: 1.777},
  {filename: 'orange.jpg', aspectRatio: 1.777},
  {filename: 'yellow.jpg', aspectRatio: 1},
  {filename: 'purple.jpg', aspectRatio: 2.4},
];
var options = { /* ... */ };
var pig = new Pig(imageData, options);

options (object)

You can customize the instance by passing the options parameter. The example below uses all options and their defaults:

var imageData = [ /* ... */ ];
var options = {
  containerId: 'pig',
  classPrefix: 'pig',
  figureTagName: 'figure',
  spaceBetweenImages: 8,
  transitionSpeed: 500,
  primaryImageBufferHeight: 1000,
  secondaryImageBufferHeight: 300,
  thumbnailSize: 20,
  urlForSize: function(filename, size) {
    return '/img/' + size + '/' + filename;
  },
  onClickHandler: function(filename) { },
  getMinAspectRatio: function(lastWindowWidth) {
    if (lastWindowWidth <= 640)  // Phones
      return 2;
    else if (lastWindowWidth <= 1280)  // Tablets
      return 4;
    else if (lastWindowWidth <= 1920)  // Laptops
      return 5;
    return 6;  // Large desktops
  },
  getImageSize: function(lastWindowWidth) {
    if (lastWindowWidth <= 640)  // Phones
      return 100;
    else if (lastWindowWidth <= 1920) // Tablets and latops
      return 250;
    return 500;  // Large desktops
  }
};
var pig = new Pig(imageData, options);

options.containerId (string)

The class name of the element inside of which images should be loaded.

Default: 'pig'

options.classPrefix (string)

The prefix associated with this library that should be prepended to class names within the grid.

Default: 'pig'

options.figureTagName (string)

The tag name to use for each figure. The default setting is to use a <figure></figure> tag.

Default: 'figure'

options.spaceBetweenImages (number)

Size in pixels of the gap between images in the grid.

Default: 8

options.transitionSpeed (number)

Transition speed in milliseconds.

Default: 500

options.primaryImageBufferHeight (number)

Height in pixels of images to preload in the direction that the user is scrolling. For example, in the default case, if the user is scrolling down, 1000px worth of images will be loaded below the viewport.

Default: 1000

options.secondaryImageBufferHeight (number)

Height in pixels of images to preload in the direction that the user is NOT scrolling. For example, in the default case, if the user is scrolling down, 300px worth of images will be loaded above the viewport. Images further up will be removed.

Default: 300

options.thumbnailSize (number)

The height in pixels of the thumbnail that should be loaded and blurred to give the effect that images are loading out of focus and then coming into focus.

Default: 20

options.urlForSize (function)

Get the URL for an image with the given filename & size.

Parameters:

  • filename (string) - The filename of the image.
  • size (number) - The size (height in pixels) of the image.

Returns:

  • (string) - The URL of the image at the given size.

Default:

function(filename, size) {
  return '/img/' + size + '/' + filename;
}

options.getMinAspectRatio (function)

Get the minimum required aspect ratio for a valid row of images. The perfect rows are maintained by building up a row of images by adding together their aspect ratios (the aspect ratio when they are placed next to each other) until that aspect ratio exceeds the value returned by this function. Responsive reordering is achieved through changes to what this function returns at different values of the passed parameter lastWindowWidth.

Parameters:

  • lastWindowWidth (number) - The last computed width of the browser window.

Returns:

  • (number) - The minimum aspect ratio at this window width.

Default:

function(lastWindowWidth) {
  if (lastWindowWidth <= 640)  // Phones
    return 2;
  else if (lastWindowWidth <= 1280)  // Tablets
    return 4;
  else if (lastWindowWidth <= 1920)  // Laptops
    return 5;
  return 6;  // Large desktops
}

options.getImageSize (function)

Get the image size (height in pixels) to use for this window width. Responsive resizing of images is achieved through changes to what this function returns at different values of the passed parameter lastWindowWidth.

Parameters:

  • lastWindowWidth (number) - The last computed width of the browser window.

Returns:

  • (number) - The size (height in pixels) of the images to load.

Default:

function(lastWindowWidth) {
  if (lastWindowWidth <= 640)  // Phones
    return 100;
  else if (lastWindowWidth <= 1920) // Tablets and latops
    return 250;
  return 500;  // Large desktops
}

options.onClickHandler (function)

Add callback function which is called when a image is clicked with the image name. By default this is an empty function.

Parameters

  • filename (string) - The name of the clicked image

Default function(filename) {}

Pig.enable()

Enable the Pig library by beginning to listen to scroll and resize events, loading images and displaying them in the grid.

Pig.disable()

Disable the Pig library by removing event listeners set in Pig.enable().

More Repositories

1

substituteteacher.js

Rotate through a series of sentences
JavaScript
326
star
2

intermediate-flask

A look at some intermediate Flask features
HTML
30
star
3

eventum

An event-driven CMS that syncs with Google Apps
Python
21
star
4

schlosser.io

My personal website
HTML
9
star
5

flask-seed

A Flask boilerplate app
Python
9
star
6

feeding-dan

In 2015, I took a picture of everything I ate. These are those photos.
JavaScript
9
star
7

yosemite-scraper

A Scraper to find last minute cancellations for campgrounds near yosemite
Python
9
star
8

shortener-web

A URL Shortener for the serverless era
JavaScript
4
star
9

wiki-battle

In what language are editors the most excited on Wikipedia right now?
JavaScript
3
star
10

servers

How I run DigitalOcean servers
3
star
11

when-will-the-1-come

When will the 1 train arrive at Columbia?
Python
2
star
12

nav.js

A lightweight, style-it-yourself navbar
JavaScript
1
star
13

notebook

A Firebase-backed markdown notebook built in polymer
HTML
1
star
14

dotfiles

My dotfiles
Vim Script
1
star
15

people-nav

A cool little experiment in JS + CSS
HTML
1
star
16

Chrome.AI-server

The server for SpeakEasy
Python
1
star
17

dfa-roadmap

DFA Design Roadmap
JavaScript
1
star
18

remindr

Let people remind you!
Python
1
star
19

setup.schlosser.io

One script to setup a new Mac, just the way I like it :)
Shell
1
star
20

absent

Connecting the Dots: Chronic Absenteeism in New York City Public Schools
Jupyter Notebook
1
star
21

EtMe

A personal collection of Etsy stores based on Foursquare checkins.
Python
1
star
22

NearBuy

The DevFest Battle of the Hacks Project
Swift
1
star
23

learn-websites

Learn how to build beautiful websites with paralax and scrolling effects!
Python
1
star
24

DropboxScripts

Scripts that seek to simplify the Dropbox user experience
Python
1
star
25

FoodJournal

A Python script that allows users to create an automated WordPress blog with photos and descriptions of the food they eat.
Python
1
star