Skip to content
This repository has been archived by the owner before Nov 9, 2022. It is now read-only.

axeleroy/photo-gallery

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
src
 
 
 
 
 
 
 
 
 
 
 
 
 
 

PhotoGallery

A minimal photo gallery mimicking Google Photos' style and intended for use with static websites.

Preview of the app

Demo (in production!)

axel.leroy.sh/photography

Blog article

axel.leroy.sh/blog/the-making-of-photo-gallery

Goals and functionalities

When working on this project, my goals were to make this photo gallery

  • Embeddable in a static website hosted on AWS (S3 & Cloudfront).
  • Functionaly minimal: it should just display albums and pictures with relevant EXIF data.
  • (relatively) Lightweight with minimal dependancies, with notably no CSS framework involved.
  • Efficient, with small thumbnails and HTTP requests caching.
  • Look like Google Photo's album grid.

What are not goals of this project

  • Being user friendly: there's no GUI to manage albums and pictures.
  • Handle everyone's use-cases. My main goal was to make a custom solution for my own portfolio, not to anwser a broad userbase's needs.

Using PhotoGallery

How it works

PhotoGallery fetches all of its data from static JSON files meant to be stored allongside the app or pictures.

There are two types of JSON files:

  • Album List: describes the albums shown by the app
[
    {
        id: "string",
        name: "string",
        thumbnail: {
            default : {
                url: "string",
                height: 300, // in pixels
                width: 400 // in pixels
            },
            webp: [
                {
                    url: "string",
                    height: 300, // in pixels
                    width: 400 // in pixels
                },
                {
                    url: "string",
                    height: 600, // in pixels
                    width: 800 // in pixels
                }
            ],
            jpeg: [
                {
                    url: "string",
                    height: 300, // in pixels
                    width: 400 // in pixels
                },
                {
                    url: "string",
                    height: 600, // in pixels
                    width: 800 // in pixels
                }
            ]
        }
    },
    {
        id: "string",
        name: "string",
        thumbnail: {
            ...
        }
    }
]
  • Album Content: describes an album and the pictures it contains
{
   id: "string",
   name: "string",
   pictures: [
     {
       id: "string",
       thumbnail: {
          default : {
              url: "string",
              height: 300, // in pixels
              width: 400 // in pixels
          },
          webp: [
              {
                  url: "string",
                  height: 300, // in pixels
                  width: 400 // in pixels
              },
              {
                  url: "string",
                  height: 600, // in pixels
                  width: 800 // in pixels
              }
          ],
          jpeg: [
              {
                  url: "string",
                  height: 300, // in pixels
                  width: 400 // in pixels
              },
              {
                  url: "string",
                  height: 600, // in pixels
                  width: 800 // in pixels
              }
          ]
       },
       fullsize: {
          default : {
               url: "string",
               height: 300, // in pixels
               width: 400 // in pixels
          },
          webp: [
           {
                url: "string",
                height: 300, // in pixels
                width: 400 // in pixels
            },
            {
                url: "string",
                height: 600, // in pixels
                width: 800 // in pixels
            }
           ],
           jpeg: [
            {
                url: "string",
                height: 300, // in pixels
                width: 400 // in pixels
            },
            {
                url: "string",
                height: 600, // in pixels
                width: 800 // in pixels
            }
           ]
       },
       exif: {
         'Tag': "value" 
       }   
     },
     {
       id: "string",
       thumbnail: {
         ...
       },
       fullsize: {
         ...
       }
     }
   ]
}

These JSONs are mapped to TypeScript classes you can find in src/app/types and are generated by the Python script in scripts/.

Speaking of Python script…

Uploading pictures and generating JSON files

In order to easily upload pictures and create the JSONs, I created a Python script taking care of everything.

Given a folder containing pictures you want to add to an album, it

  • parses the relevant EXIF data from each picture
  • generates thumbnails and different sizes of the pictures
  • generates a JSON file describing the album's content (see How it Works)
  • uploads the JSON, pictures and the thumbnails to the given S3 bucket (all under s3://bucket-name/albumname/)
  • updates the albums list JSON with the new album on top

It is located in scripts/ and requires

  • Python 3.6+
  • libjpeg and libwebp installed
  • a few dependencies you have to install using pip install -r requirements.txt
  • and to set up your AWS credentials

Finally, to list its parameters, just type python add-album.py -h.

Once it had run, take the created/updated albums.json and upload it wherever you want (in a bucket, on your website allongside the gallery, etc.)

Note to users of previous version: Since the album structure has changed to handle different sizes and WebP, I made a migration script named migrate-albums.py to migrate existing albums.

Building the Angular app

First, install everything using npm install. Then modify src/environments/environment.ts or copy it to src/environments/environment.prod.ts and make the modifications you need (refer to AppConfig.ts).

The most important attributes to set are

  • albumListUrl: the URL to the albums list JSON
  • albumBaseUrl: the URL to the folder containing the albums to display
  • albumFileNameUrl: Name of the album JSON file, with file extension.

Set the last two variables so that the app fetches the JSON at albumBaseUrl + albumId + albumFileNameUrl.

For example, given this configuration

{
  albumListUrl: 'https://my-wonderful-website.com/assets/albums.json',
  albumBaseUrl: 'https://my-bucket.s3.eu-central-1.amazonaws.com/',
  albumFileNameUrl: '/album.json'
}

The app will fetch the albums list at https://my-wonderful-website.com/assets/albums.json and for an album with the ID fantastic-album will fetch its content at https://my-bucket.s3.eu-central-1.amazonaws.com/fantastic-album/album.json.

Once everything is all set, build the app

npm build [--prod] --baseHref=/base-folder [--deployUrl=/assets/]

Then take everything in /dist/photo-gallery and deploy anywhere you want !

Note: make sure the assets folder containing the icons is at the root of you website. Edit the code if you want the icons to be stored somewhere else.

Making it yours: customize its CSS

Here are some CSS styles to apply to the page containing the app in order to customize its look to your liking:

Changing the typography

Style h1 and .thumbnail-legend to change the look of the page title and thumbnails' legend. You can also style the links using the a and a:hover selectors.

Grid spacing

To widen or tighten the gap between thumbnails, change .thumbnail-list-item's margin properties.

Placeholder color

To change the color of loading pictures, change the .thumbnail-bg's background-color.

Loader style and color

Use border properties to customize the style and color of the .loader component. You can find multiple examples here.

Make the last line of thumbnails fill the entire width of the page

Just set the following:

.thumbnail-list-end {
  flex-grow: 0 !important;
}

About

A minimal photo gallery mimicking Google Photos' style and intended for use with static websites

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published