photoswipe-dynamic-caption-plugin
Version:
A caption plugin for PhotoSwipe v5+ that smartly positions it aside or below the image.
187 lines (127 loc) • 7.39 kB
Markdown
## Dynamic caption plugin for [PhotoSwipe](https://photoswipe.com/) v5
**[> Plugin demo <](https://dimsemenov.github.io/photoswipe-dynamic-caption-plugin/)**
The plugin can automatically position the text below or aside depending on the available space. For small to medium sized captions. And only for images with the default `fit` scale mode.
For accessibility, make sure that important captions are always available without PhotoSwipe - either use an `alt` attribute on thumbnails or `aria-labelledby`.
### Intiailization
The plugin has a single JS file `photoswipe-dynamic-caption-plugin.esm.js` (UMD version is in the `dist/` folder) and a single CSS file `photoswipe-dynamic-caption-plugin.css`. Include them directly or via with npm:
```
npm i photoswipe-dynamic-caption-plugin --save
```
It can be initialized like this:
```html
<script type="module">
import PhotoSwipeLightbox from 'photoswipe/dist/photoswipe-lightbox.esm.js';
// or 'photoswipe-dynamic-caption-plugin' if using package manager
import PhotoSwipeDynamicCaption from 'https://unpkg.com/photoswipe-dynamic-caption-plugin/photoswipe-dynamic-caption-plugin.esm.js';
const lightbox = new PhotoSwipeLightbox({
gallerySelector: '#gallery',
childSelector: '.pswp-gallery__item',
pswpModule: () => import('photoswipe/dist/photoswipe.esm.js'),
// Optional padding for images,
// note that this is an option of PhotoSwipe, not a plugin
paddingFn: (viewportSize) => {
return {
top: 30, bottom: 30, left: 70, right: 70
}
},
});
const captionPlugin = new PhotoSwipeDynamicCaption(lightbox, {
// Plugins options, for example:
type: 'auto',
});
// make sure you init photoswipe core after plugins are added
lightbox.init();
</script>
```
```html
<link rel="stylesheet" href="https://unpkg.com/photoswipe-dynamic-caption-plugin/photoswipe-dynamic-caption-plugin.css">
```
Also refer the source of the demo page - [index.html](https://github.com/dimsemenov/photoswipe-dynamic-caption-plugin/blob/main/index.html).
### Plugin options
#### `captionContent: '.pswp-caption-content'`
Used to retrieve caption content.
Can be a selector of the element from which caption content will be retrieved, if the element is not found - the plugin will try to use the thumbnail image `alt` attribute.
```html
<a href="path/to/large-image.jpg" data-pswp-width="1024" data-pswp-height="768">
<img src="path/to/thumbnail.jpg" alt="" />
<span class="pswp-caption-content">Caption content</span>
</a>
```
Or a function that should return caption content. For example:
```js
captionContent: (slide) => {
return slide.data.element.querySelector('img').getAttribute('alt');
}
```
#### `type: 'auto'`
Position type of the caption, can be 'auto', 'below', or 'aside'.
- 'below' - caption will always be place below the image
- 'aside' - caption will always be placed to the right side of the image
- 'auto' - the plugin will try to automatically determine the best position (depending on available space)
#### `mobileLayoutBreakpoint: 600`
Maximum window width at which mobile layout should be used, or a function that should return true if mobile layout should be used. For example:
```js
mobileLayoutBreakpoint: (pswp, captionPlugin) => {
return (window.innerWidth < 750);
}
```
#### `horizontalEdgeThreshold: 20`
When caption `x` position is less than this value, it'll get class `pswp__dynamic-caption--on-hor-edge`. You may use it to apply different styling, such as horizontal padding.
#### `mobileCaptionOverlapRatio: 0.3`
A ratio defines the amount of horizontal empty space before the mobile caption switches to "overlap" layout. For example, if it's set to 0.3 - the caption will start overlapping the image when more than 30% of horizontal space is not occupied by an image. If you set it to 0 - the caption will always overlap. If you set it to 1 - the caption will always shift the image (unless it's taller than viewport).
#### verticallyCenterImage: false
If enabled, the image will always be vertically centered in the remaining space between caption and the rest of viewport. If set to false (default value) - the image will lift up only if caption does not fit below.
### Styling
The caption has class `pswp__dynamic-caption`.
It can be in one of these states:
- Below the main image - `pswp__dynamic-caption--below`.
- Right side of the main image - `pswp__dynamic-caption--aside`.
- "Mobile" (by default just pinned to bottom) - `pswp__dynamic-caption--mobile`
If the caption is near left horizontal edge - it gets class `pswp__dynamic-caption--on-hor-edge`.
Feel free to adjust styles in the plugin CSS file (and use media queries if you need):
```css
.pswp__dynamic-caption--aside {
max-width: 300px;
padding: 20px 15px 20px 20px;
margin-top: 70px;
}
.pswp__dynamic-caption--below {
max-width: 700px;
padding: 15px 0 0;
}
.pswp__dynamic-caption--mobile {
background: rgba(0, 0, 0, 0.5);
padding: 10px 15px;
}
```
### How 'auto' positioning works
- Check if there is more horizontal or vertical free space around the image.
- If there is more free vertical space:
- Set caption width to the width of the image
- Add `pswp__dynamic-caption--below` class, so size can also be adjusted via CSS.
- Measure caption height.
- Check if caption will fit without any adjustments of image position.
- If it does - just show the caption below the image.
- If it doesn't - reduce pan area height by the height of caption.
- If there is more horizontal space:
- Add `pswp__dynamic-caption--aside` class, so size can be adjusted via CSS.
- Measure caption width.
- Check if caption will fit on the right side without any adjustments of image position.
- If it does - just show the caption aside of the image.
- If it doesn't - reduce pan area width by the width of caption.
If `mobileLayoutBreakpoint` requirements are met:
- Measure caption height when it occupies 100% width.
- Reduce pan area height to fit the caption below the image.
- Check amount of free horizontal space after the adjustment.
- If there is too much horizontal space (`mobileCaptionOverlapRatio`) - just overlap the caption and keep the image at the default position.
## Changelog
### 1.2.0
- Requires PhotoSwipe 5.3.0.
- Caption now moves with the slide when dragged (instead of fading in and out).
- Each slide now has a separate DOM element (before there was only a single caption element that changed content).
- No longer uses temporary caption to measure size.
- You may now access caption and its data via `dynamicCaption` property of a slide. For example `pswp.currSlide.dynamicCaption`.
### 1.1.0
- No longer adjusts main image padding. If you need to dynamically change padding based on the screen size - use PhotoSwipe option `paddingFn` (introduced in 5.1.61)
- Caption receives class `pswp__dynamic-caption--on-hor-edge` when it's on horizontal edge (`x` position is less than threshold). Added option `horizontalEdgeThreshold` to control this.
- Reworked mobile layout. Now the caption tries to not overlap the main image if there is an empty space below. Added option `mobileCaptionOverlapRatio` to control this.