[js]PhotoSwipe v5 にキャプションを付ける方法

ほぼコピペ。理解するだけ。

事前知識

PhotoSwipeにはキャプションを表示するオプションがない。

全くない訳ではなくて一応あるんだけど、コードがいっぱい増えてややこしい。

ぶっちゃけ公式を読めば解決する話。

Caption | PhotoSwipe
PhotoSwipe does not support caption out of box, but you may implement a basic caption via API, as you can see below. Or ...

v4とは全然別物。

作例

まずhtmlの方をやる。

<div class="sample"><a href="https://placehold.jp/600x600.png" target="_blank"><picture><img src="https://placehold.jp/600x600.png" alt="キャプションキャプションキャプションキャプション"></picture></a></div>

<head>で読み込みと設定。

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.2.2/photoswipe.css" integrity="sha512-aYZebRqOKTENn+6dnGG8LESiKfRv+2Oi1UTr/u47p0DKdYCih17xTP+/MrTzDPTSvdpSgTwzp5aB3QfO1I+mEA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    <script type="module">
        //画像サイズ取得・付与
        $(window).one('load',function(){
            $('.sample').find('a').each(function(){
                var image = new Image();
                image.src = $(this).attr('href');
                console.log(image.width);
                $(this).attr({'data-pswp-width':image.width,'data-pswp-height':image.height});
            });
        });
        //photoswipe設定
        import PhotoSwipeLightbox from 'https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.2.2/photoswipe-lightbox.esm.js';
        const options = {
          gallery: '.sample',
          children: 'a',
          pswpModule: () => import('https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.2.2/photoswipe.esm.js')
        }
        const lightbox = new PhotoSwipeLightbox(options);
        lightbox.on('uiRegister', function() {
            lightbox.pswp.ui.registerElement({
                name: 'custom-caption',
                order: 9,
                isButton: false,
                appendTo: 'root',
                html: 'Caption text',
                onInit: (el, pswp) => {
                    lightbox.pswp.on('change', () => {
                        const currSlideElement = lightbox.pswp.currSlide.data.element;
                        let captionHTML = '';
                        if (currSlideElement) {
                            const hiddenCaption = currSlideElement.querySelector('.hidden-caption-content');
                            if (hiddenCaption) {
                                captionHTML = hiddenCaption.innerHTML;
                            } else {
                                captionHTML = currSlideElement.querySelector('img').getAttribute('alt');
                            }
                        }
                        el.innerHTML = captionHTML || '';
                    });
                }
            });
        });
        lightbox.init();
    </script>

おしまい。

仕組み

サムネ画像のaltを取得して表示してることになる。

例えば<figure>で組んでたとして、<figcaption>を表示させたいなら以下の部分を書き換える。

captionHTML = currSlideElement.querySelector('img').getAttribute('alt');

公式が案内してるのは間違いないんだけど、自作感とかやっつけ感がすごい。

装飾

PhotoSwipe側でキャプション用の装飾は付けられてないから自分でcssを書いていく。

以下の感じで出力される。

<div class="pswp__custom-caption pswp__hide-on-close">キャプションキャプションキャプションキャプション</div>

階層はこんな感じになる。

<body>
    <div class="pswp pswp--open pswp--has_mouse pswp--one-slide pswp--ui-visible">
        ...
        <div class="pswp__custom-caption pswp__hide-on-close">キャプションキャプションキャプションキャプション</div>

検証で見たらわかるんだけど。まあ、ポップアップだしね。そりゃ<body>の直下ですよね。

で、このclassはPhotoSwipe側のcssで色々組まれてるんだけど、表示に関連する内容ばかりで装飾に関連するものは何もない。だから、!importantとかを使わなくても大抵のことができる。

.pswp__hide-on-close{
    width: 100%;
    text-align: center;
    color: #fafafa;
    position: absolute;
    bottom: 20px;
}

入れ子で指定しなくていいから結構楽。

画像と被ったらどうするかとか、その辺を調整すればいいと思います。

おまけ

photoSwipe用にキャプション拡張のプラグインがある。

GitHub - dimsemenov/photoswipe-dynamic-caption-plugin: A dynamic caption plugin for PhotoSwipe v5. Automatically positions the caption aside or below the image.
A dynamic caption plugin for PhotoSwipe v5. Automatically positions the caption aside or below the image. - GitHub - dim...

凝ったことができるようになるので、そうしたい人はこちら。

自分は端っこにキャプションがでたらそれで良かったので使ってない。

コメント

タイトルとURLをコピーしました