画像を拡大するプラグイン PhotoSwipe v5を紹介します


以前の記事で、PhotoSwipe v4を紹介しました。
一時期流行ったLightbox系の機能ですが、PhotoSwipeは高機能で、他の画像拡大プラグインよりも使い勝手がよいように感じました。

今回はバージョンアップしたPhotoSwipe v5の紹介です。
バージョンアップにともなって、設置方法が大幅に変更になりました。機能はあいかわらず使いやすいです。
タップ(画像の全画面表示)、ピンチアウト・ピンチイン(画像の拡大縮小)をかんたんに付けられますので、参考にどうぞ。

ページ後半に、カラーミーショップ向けのサンプルコードを載せています。

PhotoSwipe公式サイト

一般的なイベントやメソッドがありますので、つかいたい場合は適宜マニュアルを参照します。
かんたんな設置だけなら、コピペで動作します。

PhotoSwipe: Responsive JavaScript Image Gallery

JSとCSSの読み込み

CDNがありますので、プラグインを設置するレンタルサーバーは不要です。
必要なファイルは以下の赤枠の3つです。

photoswipe - Libraries - cdnjs


ファイル名にumdがついているものが古いブラウザにも対応している版です。
ES Modulesを使用できないIEやモダンブラウザの古いバージョン用。

動作させるための基本コード

PhotoSwipeを動作させるために必要なコードは、
HTMLで書いた画像ギャラリーと、実行に必要なJavaScriptなど(上述の3つ)になります。
公式サイトのサンプルコードを抜粋して説明します。


HTMLコード

CSSを読み込んで、画像ギャラリーをHTMLで書きます。かんたんなHTMLです。
a要素にサムネイル画像、img要素に拡大した画像を指定します。a要素は必須のようです。

CDNのファイルを利用する場合は、1行目のhrefをcdnjsのページでコピーしたURLに置き換えます。

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.4.4/photoswipe.min.css">

<div class="pswp-gallery pswp-gallery--single-column" id="my-gallery">
  <a href="https://cdn.photoswipe.com/photoswipe-demo-images/photos/2/img-2500.jpg" 
    data-pswp-width="1669" 
    data-pswp-height="2500" 
    target="_blank">
    <img src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/2/img-200.jpg" alt="" />
  </a>
  <!-- cropped thumbnail: -->
  <a href="https://cdn.photoswipe.com/photoswipe-demo-images/photos/7/img-2500.jpg" 
    data-pswp-width="1875" 
    data-pswp-height="2500" 
    data-cropped="true" 
    target="_blank">
    <img src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/7/img-200.jpg" alt="" />
    Cropped
  </a>
  <!-- data-pswp-src with custom URL in href -->
  <a href="https://unsplash.com" 
    data-pswp-src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/3/img-2500.jpg"
    data-pswp-width="2500" 
    data-pswp-height="1666" 
    target="_blank">
    <img src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/3/img-200.jpg" alt="" />
  </a>
  <!-- Without thumbnail: -->
  <a href="http://example.com" 
    data-pswp-src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/5/img-2500.jpg"
    data-pswp-width="2500" 
    data-pswp-height="1668" 
    target="_blank">
    No thumbnail
  </a>
  <!-- wrapped with any element: -->
  <div>
    <a href="https://cdn.photoswipe.com/photoswipe-demo-images/photos/6/img-2500.jpg"
      data-pswp-width="2500" 
      data-pswp-height="1667" 
      target="_blank">
      <img src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/6/img-200.jpg" alt="" />
    </a>
  </div>
</div>


公式サイトにある例によると、サムネイルを一部切り抜いて表示したり、サムネイル画像と拡大画像を別のものに変更したり、サムネイルなし(拡大画像をそのままサムネイルにつかう場合)にしたりできます。

data-pswp-width、data-pswp-heightで、あらかじめ画像サイズを指定しておく必要があります。
画像枚数が少ない場合はループしません。

JavaScriptコード

ES modulesをつかう場合は、umdなしのJavaScriptファイルを2つ読み込みます。
ほとんどの場合、IEなどの古いブラウザの対応は不要かと思います。

CDNのファイルを利用する場合は、importらへんの2ヶ所、cdnjsのページでコピーしたURLに置き換えます。

JavaScript

<script type="module">
import PhotoSwipeLightbox from 'https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.4.4/photoswipe-lightbox.esm.min.js';
const lightbox = new PhotoSwipeLightbox({
  gallery: '#my-gallery',
  children: 'a',
  pswpModule: () => import('https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.4.4/photoswipe.esm.min.js')
});
lightbox.init();
</script>


gallerychildrenを指定して、拡大する画像ギャラリーと画像を指定します。
galleryは画像ギャラリーの大外の要素を指定します。
childrenはギャラリー内の画像を指定します。セレクターがつかえます。

スライドショー slickで動かす

スライドショー機能に組み合わせて、PhotoSwipeを動かしたいことがあります。

当サイトは、カラーミーショップユーザー向けの情報発信をしていますので、ここでは、カラーミーショップの商品詳細ページに設置する場合について、コードを交えて紹介します(カラーミーショップに限らず、他の場合でもやることはいっしょです)。

slick(jQueryプラグイン)をつかっている、Discover無料版のテンプレート上でサンプルコードを書きました。
商品詳細ページの大画像をクリック(またはタップ)したときに、起動するようになります。

サンプルコード

大画像に対してPhotoSwipeを実装して、画像拡大するように作り変えます。
ここでは、img要素の外側に、a要素を書いて包みこみます。

本来は、data-pswp-widthなどで画像サイズの指定が必須ですが、画像サイズが揃っていない場合も多いので、テンプレート内では指定せずに、計算してあとからJavaScript側で書きこむようにします。

商品詳細ページの一部 HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.4.4/photoswipe.min.css">

<div class="p-product-img__main js-images-slider">
  <div class="p-product-img__main-item">
    <{if $product.img_url != ""}>
    <a href="<{$product.img_url}>">
      <img src="<{$product.img_url}>" alt="<{$productlist[num].name|escape:'html'}>" />
    </a>
    <{else}>
    <img src="https://img.shop-pro.jp/tmpl_img/86/no-image.jpg" alt="<{$productlist[num].name|escape:'html'}>" />
    <{/if}>
  </div>
  <{if $otherimg_num != 0}>
  <{section name=num loop=$otherimg}>
    <{if $otherimg[num].url != ""}>
    <div class="p-product-img__main-item">
      <a href="<{$otherimg[num].url}>">
        <img src="<{$otherimg[num].url}>" alt="<{$productlist[num].name|escape:'html'}>" />
      </a>
    </div>
    <{/if}>
  <{/section}>
  <{/if}>
</div>


さて、data-pswp-widthなどの画像サイズの指定が必要ですが、ここで計算して入れます。
JavaScriptで実行する関係で、処理順をきちんと指示しないと正常動作しません。ややこしいコードになりますので、すでにほかの方が作ってくださっているコードを参照しました(ありがとうございます!)。
参照)【JS】PhotoSwipe v5を使って画像をポップアップ表示する|notes by SHARESL

参照先にコードの解説も載っていますので、気になる方はそちらもあわせてご覧ください。

JavaScript

<script type="module">
import PhotoSwipeLightbox from 'https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.4.4/photoswipe-lightbox.esm.min.js';
import PhotoSwipe from 'https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.4.4/photoswipe.esm.min.js';
const slider = '.js-images-slider';

class Gallery {
  constructor() {
    this.imagePopUp();
  }

  //特定の画像の読み込み
  loadImage(src) {
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.onload = () => resolve(img);
      img.onerror = (e) => reject(e);
      img.src = src;
    });
  }

  // スライド画像のポップアップ(PhotoSwipe)
  imagePopUp(){
    const gallery = document.querySelector('.p-product-img__main');
    if(!gallery){
      return;
    }
    
    // aタグにdata-pswp-widthとdata-pswp-height属性を付ける
    const galleries = gallery.querySelectorAll('a');
    galleries.forEach((el, index, array) => {
      this.loadImage(el.href).then( img => {
        el.setAttribute('data-pswp-width', img.naturalWidth);
        el.setAttribute('data-pswp-height', img.naturalHeight);
        el.classList.remove('is-loading');
      });
    });
    
    // PhotoSwipeを適用
    const lightbox = new PhotoSwipeLightbox({
      gallery              : gallery, //リストを囲む要素を指定
      children             : '.p-product-img__main-item:not(.slick-cloned) > a', //ポップアップさせる要素を指定
      pswpModule           : PhotoSwipe  // PhotoSwipeのCoreモジュールをここに指定
    });

    //PhotoSwipeとslickの画像をそろえるためにGoToする
    lightbox.on('closingAnimationStart', () => {
      const index = $('.pswp__counter').text().split(' ');
      $(slider).slick('slickGoTo', index[0] - 1, true);
    });

    lightbox.init();
  }
}

new Gallery();
</script>


1-2行目…importでJavaScriptのURLを指定
3行目…const slider = '.js-images-slider';で画像ギャラリーを指定
41行目…スライドショーの場合、画像のcloneをつくるので、セレクターを使って上手に指定
45-49行目…PhotoSwipeを閉じたタイミングで、PhotoSwipeとslickの画像をそろえる

PhotoSwipeとslickのタッチ操作がバッティングするので、
PC時は、slick側はdraggable: false;にしておくのがよさそうです。

デモサイト

デモサイト)https://naeco.jp/demo/slick-n-photoswipe.html

挙動はこちらで確認いただけます。

画像をタップして全画面表示、元画像が大きい場合はピンチアウトで細部を拡大できます。
PCサイト・スマホサイトの両方で動作します。

おわりに

今回は、使い勝手のよい画像拡大プラグイン PhotoSwipe v5の紹介をしました。
ピンチイン、ピンチアウトで細部の拡大ができるので、大きめの画像を登録しておく必要があります。
反対に、大きめの画像が登録されていない場合は、あまり効果がでないです。

カラーミーショップで大きい画像をアップロードするには、管理画面内の画像サイズ設定で数字を大きくしてから、アップロードし直します。

執筆者

えいじ@naeco.jp この記事を書いた人

メーカー系情報システム部門出身の個人事業主。
自作するのが好きですぐに試したくなる、凝り性なWebエンジニア。
カラーミーショップ、モールなどのECについて記事にしています。

ご相談・お問い合わせはこちら