PhotoSwipe 5 lightbox with Ionic 6 (Angular)

I noticed this old forum post while working to integrate PhotoSwipe (version 5.2.4) into my app (Ionic/Angular version 6.1.2) and figured I’d share some updated tips for anyone interested. This is just to fill in some gaps in the documentation.

Install via NPM

npm i photoswipe --save

Note that you probably don’t want to install the type definitions as they appear to be outdated.

Use in a template

import PhotoSwipe from 'photoswipe'; // dont use {curly braces} here
lightbox: PhotoSwipe;
lightbox_data: any = [{
	src: 'https://dummyimage.com/800x800/000/fff',
	height: '800',
	width: '800',
	alt: 'a placeholder image reading 800x800'
	caption: 'Image One'
	},{
	src: 'https://dummyimage.com/800x800/000/fff',
	height: '800',
	width: '800',
	alt: 'a placeholder image reading 800x800'
	caption: 'Image Two'
	}];

// call from anywhere in your template; index = initial slide number to open
openLightbox(index: number = 0) {
	const options = {
  	index: index,
  	closeSVG:
		'<svg aria-hidden="true" class="pswp__icn" viewBox="0 0 512 512" width="100" height="125"><path d="M400 145.49L366.51 112 256 222.51 145.49 112 112 145.49 222.51 256 112 366.51 145.49 400 256 289.49 366.51 400 400 366.51 289.49 256 400 145.49z"/></svg>',
  	zoom: false,
  	arrowPrev: false,
  	arrowNext: false,
  	bgOpacity: 1,
  	dataSource: this.lightbox_data
	};
	
	this.lightbox = new PhotoSwipe(options);
	// on() events go here (see below)
	this.lightbox.init();
}

Optional Captions

I wasn’t able to successfully use the documented method for adding captions, so I came up with the following, which you can call right before this.lightbox.init() in openLightbox() above.

this.lightbox.on('contentActivate', ({ content }) => {
	// remove existing captions to prevent dupes
	let existing = document.querySelectorAll('.custom-caption');
	if (existing.length) {
		existing.forEach((cap) => {
  		cap.remove();
	});
	}
	// add captions when slide is active
	let caption = content.data.caption; // your caption
	var div = document.createElement('div');
	div.setAttribute('class', 'custom-caption');
	div.style.cssText =
	'color: #fff;position: absolute;padding: 1em;bottom: 0;background: rgba(0, 0, 0, 0.75);max-height: 40vh;overflow-y: scroll;transition:.15s opacity linear';
	div.innerHTML = caption;
	let parent = content.element.parentElement;
	if (parent) {
		parent.insertAdjacentElement('afterend', div);
	} else {
		content.slide.container.parentElement.append(div);
	}
	});
	this.lightbox.init();
}

Getting image dimensions, etc.

If your data doesn’t include dimensions, you’ll need to get them on demand at some point. I used this simple function to loop through my image data and get the height, width, and so on.

prepareLightboxImage(image_url: any) {
	var img = new Image();
	img.onload = () => {
  	  var height = img.height;
  	  var width = img.width;
  	  if (height && width) {
  	     // build your array of images, e.g. by adding to this.lightbox_data
  	     // you can also build your caption, alt text, etc. while you're here 
  	  }
	};
	img.src = image_url;
	img.remove();
}

Destroy on leave

I haven’t tested this on an actual Android device, but something like this might be useful for when a user uses the hardware back button while the lightbox is open.

ionViewWillLeave() {
    if (typeof this.lightbox !== 'undefined') {
      if (!this.lightbox.isDestroying) {
        this.lightbox.destroy();
      }
    }
  }

Add styles to global.scss

It’s critical you add the styles to a root/global stylesheet rather than to a component/page stylesheet.

@import "~photoswipe/dist/photoswipe.css"; // path to node module styles

// Avoid the notch
.pswp .pswp__top-bar {
  margin-top: constant(safe-area-inset-top); // for ios 11.1
  margin-top: env(safe-area-inset-top); // for ios 11.2 and onwards
}
// Show caption only when UI toolbar is visible
.pswp:not(.pswp--ui-visible) .custom-caption {
  opacity: 0 !important;
}

That’s pretty much it. Hope this is helpful to someone.

Be sure to note the versions at the top of this post if you have issues. I get the impression that PhotoSwipe 5 is still a work in progress when it comes to framework compatibility, so I can’t guarantee this will work forever (or at all for that matter).

6 Likes

Thank you so much for this! Just to confirm does this still work for photoswipe 5.3.4?