A photo gallery JavaScript single page app built with React, Redux, and Typescript. Bootstrapped with Create React App.
Hosted at https://timotaglieber.de/photos.
Optional: If you'd like to use the create-album-from-tifs
npm script later, first download and install GraphicsMagick or ImageMagick. In Mac OS X, you can simply use Homebrew and do:
brew install imagemagick
brew install graphicsmagick
Regular installation:
npm install
-
Create an
albums
directory in./public
-
For each album you'd like to host, create a directory inside
./public/albums
, for example./public/albums/album1
. -
Create a .json file listing the album content:
./public/albums/album1/album.json
. -
List your photos in
album.json
by using the following structure:[ { "file": "file-name-of-first-photo.jpg", "title": "Title of first photo", "location": "Location where first photo was taken", "date": "Month Year", "caption": "Optional caption, one line rendered below location and date" }, { "file": "file-name-of-second-photo.jpg", "title": "Title of second photo", "location": "Location where second photo was taken", "date": "Month Year", "caption": "Optional caption, one line rendered below location and date" } ]
- The first element of the array is the first photo that is shown in the app (the counter in the upper right corner will show
1/X
).
- The first element of the array is the first photo that is shown in the app (the counter in the upper right corner will show
-
Create directories for the two supported maximum image widths in
./public/albums/album1
:./public/albums/album1/1920
and./public/albums/album1/3840
-
1920
and3840
are expected to contain the same number of files and the same file names, but each has the images scaled down:- Every image in
./public/albums/album1/1920
has a maximum width of 1920 pixels. - Every image in
./public/albums/album1/3840
has a maximum width of 3840 pixels. - The file names must match the
file
property fromalbum.json
. - Image height is not considered, since I'm assuming that most photos of an album will have "landscape" aspect ratio. This is of course a simplification and might not apply to your case.
- There is no restriction on image file types/extension, anything your target browser supports works.
- Every image in
-
Following the given examples, the final directory content should be:
public albums album1 album.json 1920 file-name-of-first-photo.jpg file-name-of-second-photo.jpg 3840 file-name-of-first-photo.jpg file-name-of-second-photo.jpg
-
Create a production bundle with
npm run build
and deploy the entire content of./build
to your web host. Note that your photos from./public/albums
are copied into the./build
directory. -
The default path for the app is
yourdomaingoeshere.com/photos
, this can be configured inpackage.json
(homepage
property). -
Loading
http[s]://yourdomaingoeshere.com/photos
will jump into the default album configured in./src/config.ts
. -
Once any album is loaded, you can use a number of ways to cycle through the photos:
- Arrow keys
- Mouse wheel
- Clicking or tapping in the left or right half of the page
- Swiping left or right with touch gestures
-
The album will update the hash URL if you cycle to another photo. Examples:
http[s]://yourdomaingoeshere.com/photos/#album1/file-name-of-first-photo.jpg
http[s]://yourdomaingoeshere.com/photos/#album1/file-name-of-second-photo.jpg
- This allows sharing the URL to a specific photo
-
The app will load the
1920
or3840
version of a photo depending onwindow.screen.width
andwindow.devicePixelRatio
. It's not the most sophisticated mechanism, but will at least ensure that small mobile screens will only load the HD version and not 4k.
npm run create-album-from-tifs -- --source=<pathToDirWithTifFilesInside> --target=<albumOutputPath> --date="<date>" --location="<location>"
This will read all .tif files inside the source directory and convert them to .jpg with GraphicsMagick. An album.json
will be created automatically. The same date
and location
is used for each photo. The title of each photo is the file name without extensions.
Make sure that the directory albumOutputPath
exists and that it contains the empty sub-directories 1920
and 3840
.
I'm using this project as a learning playground for frontend stuff. It works better for me to have an actual use case when doing that (hosting my own photos). There used to be a 200 line vanilla JS version, but it didn't support multiple albums.
I didn't like the UI of any photo gallery I've come across and wanted to create something that is simple, clean, and focused. Plus the combination of a learning project and an actual personal use case.