PhotoSwipeの使い方!Light Boxの決定版を導入しよう!

PhotoSwipeの使い方!Light Boxの決定版を導入しよう!

2015年1月のリニューアルにあたり、ブログ全体に取り入れたのが、この「PhotoSwipe」。個人的にはライトボックス系の決定版だと言えるくらい完璧なライブラリだと思っています。自分の環境用にカスタマイズする方法と合わせて紹介します。ちなみにjQueryは不要です。

サンプルデモ

下記は、サンプルの画像です。クリック(タッチ)すると、Twitterアプリのようなアニメーションで画像が拡大されます。マウス、または指でスライドすると前後の写真に移動し、スマホの場合はダブルタッチすると画像をビューポートを変えずにズームイン、ズームアウトすることができます。拡大前と拡大後で画像を分けること(例えば、.jpg.gifなども)ができるので、転送量節約にももってこいですね〜。

  • 縦長写真

    縦長の写真。

  • 正方形写真

    正方形の写真。

  • 横長写真

    横長の写真。

  • 通常写真

    数合わせで神津牧場(良いところです)。

主な機能

主な機能は下記の通りです。デスクトップPCではもちろん、特にスマホで快適に操作することができます。

項目説明
アニメーションサムネイル画像をクリックすると、その小さい画像が拡大するかのようなアニメーションを経て、オリジナル画像に切り替わります。
ズーム画像ビュー時、ダブルタップすると拡大、縮小することができます。ビューポートが変わらないので、ピンチイン、ピンチアウトの操作が必要ありません。
スライドスライドすると、前後の画像に簡単に移動することができます。
キャプション画像ビュー時に、下にコメントを表示することができます。
固有リンク1つ1つの画像に固有リンクが自動で作成されます。固有リンクにアクセスした場合、そこからPhotoSwipeを終了してすぐに記事に戻れます。SNSなどで画像をシェアすることが容易になります。(固有リンク)

ライブラリの入手

PhotoSwipeはGithub上でダウンロードすることができます。まずはライブラリを入手して下さい。

ダウンロードしたPhotoSwipe-master.zipを解凍すると、いくつかのファイルが含まれていますが、その中で利用するのは下記7つのファイルです。default-skin.cssと、3つの画像ファイルは一緒のフォルダに設置します。以降は、7つのファイルを全て同一フォルダに設置したという仮定で説明していきます。

PhotoSwipe-master.zip

  • PhotoSwipe-master
    • dist
      • photoswipe.min.js
      • photoswipe-ui-default.min.js
      • photoswipe.css
      • default-skin
        • default-skin.css
        • default-skin.png
        • default-skin.svg
        • preloader.gif

プログラミング

それでは早速、簡単にPhotoswipeを実装してみましょう。この章では、PhotoSwipeを起動させるまでを説明します。

ファイルの読み込み

まずはヘッダー内で、2のJavaScript、2つのCSSを読み込みます。読み込む順番は変更しないで下さい。

HTML

<!-- CSSの読み込み -->
<link rel="stylesheet" href="./photoswipe.css">
<link rel="stylesheet" href="./default-skin.css">

<!-- JavaScriptの読み込み -->
<script src="./photoswipe.min.js"></script>
<script src="./photoswipe-ui-default.min.js"></script>

セット用のJavaScript

HTML上にある画像に対し、PhotoSwipeの機能をセットするためのJavaScriptを用意します。こちらは公式ドキュメントで案内されているのと同内容です。そのままコピーして下さい。HTMLヘッダー内のscript要素、または、外部ファイル化して読み込んで下さい。前項で読んだJavaScriptよりも、後に読み込むようにして下さい。

JavaScript

/**************************************************

	PhotoSwipeをセットするためのJavaScript

	公式ドキュメントより
	http://photoswipe.com/documentation/getting-started.html

**************************************************/
var initPhotoSwipeFromDOM = function( gallerySelector ) {

    // parse slide data (url, title, size ...) from DOM elements 
    // (children of gallerySelector)
    var parseThumbnailElements = function(el) {
        var thumbElements = el.childNodes,
            numNodes = thumbElements.length,
            items = [],
            figureEl,
            linkEl,
            size,
            item;

        for(var i = 0; i < numNodes; i++) {

            figureEl = thumbElements[i]; // <figure> element

            // include only element nodes 
            if(figureEl.nodeType !== 1) {
                continue;
            }

            linkEl = figureEl.children[0]; // <a> element

            size = linkEl.getAttribute('data-size').split('x');

            // create slide object
            item = {
                src: linkEl.getAttribute('href'),
                w: parseInt(size[0], 10),
                h: parseInt(size[1], 10)
            };



            if(figureEl.children.length > 1) {
                // <figcaption> content
                item.title = figureEl.children[1].innerHTML; 
            }

            if(linkEl.children.length > 0) {
                // <img> thumbnail element, retrieving thumbnail url
                item.msrc = linkEl.children[0].getAttribute('src');
            } 

            item.el = figureEl; // save link to element for getThumbBoundsFn
            items.push(item);
        }

        return items;
    };

    // find nearest parent element
    var closest = function closest(el, fn) {
        return el && ( fn(el) ? el : closest(el.parentNode, fn) );
    };

    // triggers when user clicks on thumbnail
    var onThumbnailsClick = function(e) {
        e = e || window.event;
        e.preventDefault ? e.preventDefault() : e.returnValue = false;

        var eTarget = e.target || e.srcElement;

        // find root element of slide
        var clickedListItem = closest(eTarget, function(el) {
            return (el.tagName && el.tagName.toUpperCase() === 'FIGURE');
        });

        if(!clickedListItem) {
            return;
        }

        // find index of clicked item by looping through all child nodes
        // alternatively, you may define index via data- attribute
        var clickedGallery = clickedListItem.parentNode,
            childNodes = clickedListItem.parentNode.childNodes,
            numChildNodes = childNodes.length,
            nodeIndex = 0,
            index;

        for (var i = 0; i < numChildNodes; i++) {
            if(childNodes[i].nodeType !== 1) { 
                continue; 
            }

            if(childNodes[i] === clickedListItem) {
                index = nodeIndex;
                break;
            }
            nodeIndex++;
        }



        if(index >= 0) {
            // open PhotoSwipe if valid index found
            openPhotoSwipe( index, clickedGallery );
        }
        return false;
    };

    // parse picture index and gallery index from URL (#&pid=1&gid=2)
    var photoswipeParseHash = function() {
        var hash = window.location.hash.substring(1),
        params = {};

        if(hash.length < 5) {
            return params;
        }

        var vars = hash.split('&');
        for (var i = 0; i < vars.length; i++) {
            if(!vars[i]) {
                continue;
            }
            var pair = vars[i].split('=');  
            if(pair.length < 2) {
                continue;
            }           
            params[pair[0]] = pair[1];
        }

        if(params.gid) {
            params.gid = parseInt(params.gid, 10);
        }

        if(!params.hasOwnProperty('pid')) {
            return params;
        }
        params.pid = parseInt(params.pid, 10);
        return params;
    };

    var openPhotoSwipe = function(index, galleryElement, disableAnimation) {
        var pswpElement = document.querySelectorAll('.pswp')[0],
            gallery,
            options,
            items;

        items = parseThumbnailElements(galleryElement);

        // define options (if needed)
        options = {
            index: index,

            // define gallery index (for URL)
            galleryUID: galleryElement.getAttribute('data-pswp-uid'),

            getThumbBoundsFn: function(index) {
                // See Options -> getThumbBoundsFn section of documentation for more info
                var thumbnail = items[index].el.getElementsByTagName('img')[0], // find thumbnail
                    pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
                    rect = thumbnail.getBoundingClientRect(); 

                return {x:rect.left, y:rect.top + pageYScroll, w:rect.width};
            }

        };

        if(disableAnimation) {
            options.showAnimationDuration = 0;
        }

        // Pass data to PhotoSwipe and initialize it
        gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options);
        gallery.init();
    };

    // loop through all gallery elements and bind events
    var galleryElements = document.querySelectorAll( gallerySelector );

    for(var i = 0, l = galleryElements.length; i < l; i++) {
        galleryElements[i].setAttribute('data-pswp-uid', i+1);
        galleryElements[i].onclick = onThumbnailsClick;
    }

    // Parse URL and open gallery if it contains #&pid=3&gid=1
    var hashData = photoswipeParseHash();
    if(hashData.pid > 0 && hashData.gid > 0) {
        openPhotoSwipe( hashData.pid - 1 ,  galleryElements[ hashData.gid - 1 ], true );
    }
};

// PhotoSwipeを起動する
initPhotoSwipeFromDOM( '.my-gallery' ) ;

起動用のJavaScript

PhotoSwipeを起動するためのJavaScriptも必要ですね。それが下記の部分です。前項で紹介したコードの一番最後に、加えてあるのを確認して下さいね。

JavaScript

// PhotoSwipeを起動する
initPhotoSwipeFromDOM( '.my-gallery' ) ;

コンテナの作成

続いて、PhotoSwipe用のコンテナを、あらかじめHTML内に記述しておきます。場所はどこでも大丈夫ですが、分かりやすいよう、body要素の最後でいいでしょう。これは、サムネイル画像をクリックしてビューモードになった時のデザインです。公式ドキュメントで案内されているのと同内容で、個々のコードを理解する必要はありません。そのままコピーして下さい。

HTML

<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

	<!-- Background of PhotoSwipe. 
		 It's a separate element as animating opacity is faster than rgba(). -->
	<div class="pswp__bg"></div>

	<!-- Slides wrapper with overflow:hidden. -->
	<div class="pswp__scroll-wrap">

		<!-- Container that holds slides. 
			PhotoSwipe keeps only 3 of them in the DOM to save memory.
			Don't modify these 3 pswp__item elements, data is added later on. -->
		<div class="pswp__container">
			<div class="pswp__item"></div>
			<div class="pswp__item"></div>
			<div class="pswp__item"></div>
		</div>

		<!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
		<div class="pswp__ui pswp__ui--hidden">

			<div class="pswp__top-bar">

				<!--  Controls are self-explanatory. Order can be changed. -->

				<div class="pswp__counter"></div>

				<button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

				<button class="pswp__button pswp__button--share" title="Share"></button>

				<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

				<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

				<!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
				<!-- element will get class pswp__preloader--active when preloader is running -->
				<div class="pswp__preloader">
					<div class="pswp__preloader__icn">
					  <div class="pswp__preloader__cut">
						<div class="pswp__preloader__donut"></div>
					  </div>
					</div>
				</div>
			</div>

			<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
				<div class="pswp__share-tooltip"></div> 
			</div>

			<button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
			</button>

			<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
			</button>

			<div class="pswp__caption">
				<div class="pswp__caption__center"></div>
			</div>

		</div>

	</div>

</div>

画像部分のHTML

仕上げに、HTML内に画像を配置しましょう。まず、全体を囲む要素として、my-galleryというクラス名の付いたdiv要素を配置します。この中に、画像を配置していきます。

HTML

<div class="my-gallery">
	<!-- この中に記述していく -->
</div>

個々の画像を配置していきましょう。公式の案内に従えば、figure要素を用いて、次のようにマークアップしていきます。必要な要素は「オリジナル画像のURL」「オリジナル画像のサイズ」「サムネイル画像のURL」「キャプション」の4点です。「オリジナル画像のサイズ」は、例えば、横幅800px、縦幅600pxの場合は800x600というように指定します。注意点として、個々の画像のマークアップは、全て同じ階層構造でなければPhotoSwipeが機能しません。

HTML

<div class="my-gallery">

	<figure>
		<a href="{画像のURL}" data-size="{画像のサイズ}">
			<img src="{サムネイル画像のURL}" alt="{画像下に表示されるキャプション}" />
		</a>
		<figcaption>サムネイル下に表示されるメッセージ</figcaption>
	</figure>

	<figure>
		<a href="./photo.jpg" data-size="800x600">
			<img src="./photo-thumbnail.jpg" alt="写真の説明でーす。" />
		</a>
		<figcaption>サムネイル下に表示されるメッセージ</figcaption>
	</figure>

</div>

なお、my-galleryのコンテナを増やすことで、複数グループの画像ギャラリーを配置することができます。

HTML

<!-- 1つ目の画像ギャラリー -->
<div class="my-gallery">
	<!-- この中に記述していく -->
</div>

<!-- 2つ目の画像ギャラリー -->
<div class="my-gallery">
	<!-- この中に記述していく -->
</div>

サンプルデモ

PhotoSwipeのデモ
PhotoSwipeのデモ

この章の内容を反映させたデモンストレーションが下記です。どのように動作するのか、確認してみて下さいね!

サンプルデモを見る

オプション

PhotoSwipeを起動する際に、ライトボックスの機能を自由に調整することができます。この章では、主なオプションを紹介します。全てを知りたい場合は、公式ドキュメント(英語)をご参考下さい。

オプションの一覧

ということで、主なオプションを見ていきましょう。

showAnimationDuration
PhotoSwipeを起動する時のアニメーションの速度をミリ秒数で設定可。0にすればアニメーションはなし。デフォルトは333。0以外を設定する場合は、CSSファイル内の333msの数値も、同値に変更する必要がある。
変更するセレクタ一覧:
.pswp--animate_opacity,.pswp__bg,.pswp__caption,.pswp__top-bar,.pswp--has_mouse .pswp__button--arrow--left,.pswp--has_mouse .pswp__button--arrow--right
hideAnimationDuration
PhotoSwipeを終了時のアニメーションの速度をミリ秒数で設定可。0にすればアニメーションはなし。デフォルトは3330以外を設定する場合は、CSSファイル内(showAnimationDurationと同じ)も変更する必要がある。
showHideOpacity
PhotoSwipeを起動、終了する際、サムネイル画像からオリジナル画像に移り変わる時に、フェードイン効果を付けるか否かをBoolean値で指定する。デフォルトはfalse。サムネイル画像とオリジナル画像のアスペクト比が異なる場合などにtrueにすれば、不自然さを軽減できる。
bgOpacity
画像ビュー時の背景の不透明度を01の間で指定する。0が完全透明で、1が完全不透明。デフォルトは1
spacing
画像ビュー時の、前後の画像との距離をビューポートに対するパーセンテージで指定する。デフォルトは0.12。数値を増やすだけ画像スライド時の移動アニメーションが速くなる。
maxSpreadZoom
スマホで画像をダブルタッチで拡大する時、元の大きさより最大で何倍まで拡大するかを指定する。デフォルトは2。オリジナル画像がとても大きい場合、その通りに拡大した時、端末の機能によってはフリーズする可能性があるため、制御しておいた方がいい。
loop
画像ビュー時のスライドで、インフィニティスライドを有効にするか。デフォルトはtruetrueの場合は、最後から最初へ、最初から最後へスライド可能で、falseの場合は不可。ただし、画像が2枚以下の場合、強制的にfalseになる。
pinchToClose
タッチデバイスで、ピンチインでPhotoSwipeを終了できるか否かをBoolean値で指定する。デフォルトはtruetrueだと、ピンチインの割合に応じて、終了アニメーションが進んだり戻ったりする。falseだと、ピンチインしても何も起こらなくなる。
closeOnScroll
上下にスクロールした時にPhotoSwipeを閉じるか否かをBoolean値で指定する。デフォルトはtruetrueだと、画像ビュー時に上下にスクロールすると、PhotoSwipeが終了する。falseだと、スクロールしても何も起こらない。これはマウスを使えるデスクトップPC版のオプション。タッチデバイスの場合はcloseOnVerticalDragを利用する。
closeOnVerticalDrag
上下にドラッグした時にPhotoSwipeを閉じるか否かをBoolean値で指定する。デフォルトはtruetrueだと、画像ビュー時に上下にドラッグすると、PhotoSwipeが終了する。falseだと、ドラッグができない。これはタッチデバイス用のオプション。デスクトップPCの場合はcloseOnScrollを利用する。
verticalDragRange
上下のドラッグでPhotoSwipeを終了させる設定の時、どのくらいの距離をドラッグした時に終了させるかを設定する。値は01の数値で指定でき、数値が大きいほど、ドラッグ量が少なく終了させることができる。
escKey
ESCでPhotoSwipeを終了できるか否かをBoolean値で指定する。デフォルトはtrue
arrowKeys
キーボードでの操作を有効にするか否かをBoolean値で指定する。デフォルトはtrue。PhotoSwipeは、例えば、左右の矢印キーでスライドできたりする。
history
個別URL機能を利用するか否かをBoolean値で指定する。デフォルトはtruetrueの場合、画像ビュー時に、自動的に個々の画像のURLに切り替わる。falseの場合は元のURLのまま。URL欄を見ながら、画像をスライドしてみましょう。URLが切り替わるのが鬱陶しい場合はfalseにする。
preload
画像ビュー時に、前後の画像を何枚プリロードするかを2要素の配列形式で指定する。例えば、[2,5]の場合は、前2枚分、後5枚分の画像をプリロードする。
tapToClose
タップでPhotoSwipeを終了させるか否かをBoolean値で指定する。デフォルトはfalsetrueの場合は、画像ビュー時にタップすると終了できる。
shareEl
シェアボタンを表示させるか否かをBoolean値で指定する。デフォルトはtrue
closeEl
閉じるボタンを表示させるか否かをBoolean値で指定する。デフォルトはtrue
captionEl
キャプション(コメント)を表示させるか否かをBoolean値で指定する。デフォルトはtrue
fullscreenEl
デスクトップPCでの起動時に、フルスクリーンボタンを表示させるか否かをBoolean値で指定する。デフォルトはtrue
zoomEl
デスクトップPCでの起動時に、ズームボタンを表示させるか否かをBoolean値で指定する。デフォルトはtrue
counterEl
何枚中何枚目かを示すナビゲーションを表示させるか否かをBoolean値で指定する。デフォルトはtrue
arrowEl
前後ボタンを表示させるか否かをBoolean値で指定する。デフォルトはtrue
preloaderEl
プリロード中のローディングアニメーションを表示させるか否かをBoolean値で指定する。デフォルトはtrue
tapToToggleControls
タッチデバイスで、キャプション上などをタップした時に、画像だけを表示させるか否かをBoolean値で指定する。デフォルトはtruefalseにすると、常に、キャプションやナビゲーションが画像と一緒に表示される。

オプションの指定方法

オプションを指定するには、PhotoSwipeをセットする時のJavaScript内の下記部分を調整して下さい。

JavaScript

// define options (if needed)
options = {
	index: index,

	// define gallery index (for URL)
	galleryUID: galleryElement.getAttribute('data-pswp-uid'),

	getThumbBoundsFn: function(index) {
		// See Options -> getThumbBoundsFn section of documentation for more info
		var thumbnail = items[index].el.getElementsByTagName('img')[0], // find thumbnail
			pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
			rect = thumbnail.getBoundingClientRect(); 

		return {x:rect.left, y:rect.top + pageYScroll, w:rect.width};
	}

};

例えば、preloadpinchToCloseのオプションを追加するには、下記のようにします。

JavaScript

// define options (if needed)
options = {
	index: index,

//ここから追加
	preload: [1,3],
	pinchToClose: true,
//ここまで追加

	// define gallery index (for URL)
	galleryUID: galleryElement.getAttribute('data-pswp-uid'),

	getThumbBoundsFn: function(index) {
		// See Options -> getThumbBoundsFn section of documentation for more info
		var thumbnail = items[index].el.getElementsByTagName('img')[0], // find thumbnail
			pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
			rect = thumbnail.getBoundingClientRect(); 

		return {x:rect.left, y:rect.top + pageYScroll, w:rect.width};
	}

};

closeOnVerticalDragのオプションも加えるかーっていう場合は下記のようになります。自分好みのPhotoSwipeを作りましょう!!

JavaScript

// define options (if needed)
options = {
	index: index,

//ここから追加
	preload: [1,3],
	pinchToClose: true,
	closeOnVerticalDrag: true,
//ここまで追加

	// define gallery index (for URL)
	galleryUID: galleryElement.getAttribute('data-pswp-uid'),

	getThumbBoundsFn: function(index) {
		// See Options -> getThumbBoundsFn section of documentation for more info
		var thumbnail = items[index].el.getElementsByTagName('img')[0], // find thumbnail
			pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
			rect = thumbnail.getBoundingClientRect(); 

		return {x:rect.left, y:rect.top + pageYScroll, w:rect.width};
	}

};

オプションのテスト

オプション・パラメータを調整して、PhotoSwipeの動作を確認することができます。どういう風に変わるのか、色々と試してみて下さいね。

showHideOpacity

loop
pinchToClose
closeOnScroll
closeOnVerticalDrag

escKey
arrowKeys
history
tapToClose
shareEl
closeEl
captionEl
fullscreenEl
zoomEl
counterEl
arrowEl
preloaderEl
tapToToggleControls

カスタマイズ

公式ドキュメントのサンプルコードでは、自分の好みを100%満たせなかったので、ちょこちょことカスタマイズしました。よろしければ、参考にして下さい。

コンテナを動的に生成する

個人的なこだわりなので、同じ気持ちを持つ人以外は不要だと思います。通常だと、PhotoSwipe用のコンテナをHTMLにあらかじめ配置しなければいけないのですが、そのコード量も多く、ソースコードを見た時に気になる…。また、JavaScriptが有効じゃない人にとっては意味がない。ということで、JavaScriptで動的に生成することにしました。面倒なのでjQuery使ってます。

JavaScript

//コンテナを動的に生成する
//(コンテナ用のHTMLを地道に改行削ってぶっ込む)
$("body").append('<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true"><div class="pswp__bg"></div><div class="pswp__scroll-wrap"><div class="pswp__container"><div class="pswp__item"></div><div class="pswp__item"></div><div class="pswp__item"></div></div><div class="pswp__ui pswp__ui--hidden"><div class="pswp__top-bar"><div class="pswp__counter"></div><button class="pswp__button pswp__button--close" title="Close (Esc)"></button><button class="pswp__button pswp__button--share" title="Share"></button><button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button><button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button><div class="pswp__preloader"><div class="pswp__preloader__icn"><div class="pswp__preloader__cut"><div class="pswp__preloader__donut"></div></div></div></div></div><div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap"><div class="pswp__share-tooltip"></div></div><button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)"></button><button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)"></button><div class="pswp__caption"><div class="pswp__caption__center"></div></div></div></div></div>');

クラス名だけで画像をギャラリーに加える

公式のサンプルの場合、指定したクラス名の中に、figure要素で、しかも同じ階層構造のHTMLを配置しないと、ギャラリー画像として認識してくれません。例えば、次のように構造が少しでも違うとギャラリーに含んでくれません。

HTML

<div class="my-gallery">

	<!-- 含まれる -->
	<figure>
		<a href="{画像のURL}" data-size="{画像のサイズ}">
			<img src="{サムネイル画像のURL}" alt="{画像下に表示されるキャプション}" />
		</a>
		<figcaption>サムネイル下に表示されるメッセージ</figcaption>
	</figure>

	<!-- 含まれる -->
	<figure>
		<a href="./photo.jpg" data-size="800x600">
			<img src="./photo-thumbnail.jpg" alt="写真の説明でーす。" />
		</a>
		<figcaption>サムネイルの説明</figcaption>
	</figure>

	<!-- figure要素じゃないので同じ階層構造でも含まれない -->
	<div>
		<a href="./photo.jpg" data-size="800x600">
			<img src="./photo-thumbnail.jpg" alt="写真の説明でーす。" />
		</a>
		<figcaption>サムネイルの説明</figcaption>
	</div>

	<!-- 構造が違うので含まれない -->
	<div>
		<figure>
			<a href="./photo.jpg" data-size="800x600">
				<img src="./photo-thumbnail.jpg" alt="写真の説明でーす。" />
			</a>
			<figcaption>サムネイルの説明</figcaption>
		</figure>
	</div>

</div>

このブログは1カ所に画像を集めてギャラリーを作る用途でPhotoSwipeを使っているわけではありません。単純なライトボックスとして使っています。なので、クラス名(例ではimages)だけでギャラリーに加えられるようにカスタマイズしました。次のように、ページ内ならどんな場所にあっても、figure要素じゃなくても、指定したクラス名が付いていることを条件に画像ギャラリーに加える仕様になっています。全体を囲むコンテナは不要です。こちらも、要素の番号を取得するのにjQueryを利用しています。

HTML

<!-- [.images]が付いてるのでギャラリーに含まれる -->
<figure class="images">
	<a href="./photo.jpg" data-size="800x600">
		<img src="./photo-thumbnail.jpg" alt="写真の説明でーす。" />
	</a>
	<figcaption>サムネイルの説明</figcaption>
</figure>

<!-- [.images]が付いてるのでギャラリーに含まれる -->
<p class="images">
	<a href="./photo.jpg" data-size="800x600">
		<img src="./photo-thumbnail.jpg" alt="写真の説明でーす。" />
	</a>
</p>

<!-- [.images]が付いてるのでギャラリーに含まれる -->
<div>
	<p class="images">
		<a href="./photo.jpg" data-size="800x600">
			<img src="./photo-thumbnail.jpg" alt="写真の説明でーす。" />
		</a>
	</p>
</div>

<!-- [.images]が付いてるのでギャラリーに含まれる -->
<div>
	<div>
		<p class="images">
			<a href="./photo.jpg" data-size="800x600">
				<img src="./photo-thumbnail.jpg" alt="写真の説明でーす。" />
			</a>
		</p>
	</div>
</div>

下記のように、「ラッパーにクラス名を付ける」「その下のリンクタグに[オリジナル画像のURL]とdata-sizeを付ける」「その下のimg要素に[サムネイル画像のURL]と[キャプション(alt)]を付ける」という点は守って下さい。

HTML

<hoge class="images">
	<a href="{オリジナル画像のURL}" data-size="{オリジナル画像のサイズ}">
		<img src="{サムネイル画像のURL}" alt="{キャプションのテキスト}">
	</a>
</hoge>

セット処理を1回目のロードだけにする

公式のサンプルコードの場合、サムネイル画像をクリックするごとに、画像リストなどのセット処理を1から行なっているようです。画像数が動的に変わらない限り、セット処理は1回きりで大丈夫なはずなので、そのように変更しました。

カスタマイズ版のデメリット

1ページ全体を1つの画像ギャラリーにするということで、このカスタマイズ版を利用した場合、1ページに複数のグループを設定することができません。ただし、さらなるカスタマイズで対応することは可能です。気力が湧いて来たら、今後、実装しようかと思います。

サンプルデモ

HTML構造に関係なく画像をグループにまとめる
HTML構造に関係なく画像をグループにまとめる

以上のカスタマイズを施したプログラムのサンプルデモです。それぞれ、コンテナ要素や、階層構造が違くても、まとめて1つの画像ギャラリーに集約できているのを確認してみて下さい。

サンプルデモを見る

ダウンロード

この記事で紹介してきた内容をダウンロードすることができます。動作確認などにお使い下さい。ライブラリ関連のファイルについてはGitHubから別途ダウンロードして下さい。全てのファイルを同フォルダ内に設置して、HTMLファイルにアクセスして下さい。

ファイル一覧

SYNCER00244
photoswipe-normal.html Download
photoswipe.min.js
photoswipe-ui-default.min.js
photoswipe.css
default-skin.css
default-skin.png
default-skin.svg
preloader.gif
fire-photoswipe-normal.js Download
photo-thumbnail.jpg Download
photo.jpg Download
ramen-thumbnail.jpg Download
ramen.jpg Download
viewbow-thumbnail.jpg Download
viewbow.jpg Download
logo-thumbnail.png Download
logo.png Download
photoswipe-customize.html Download
fire-photoswipe-customize.js Download

ファイル名をクリックすると内容を確認できます。「Download Zip」をクリックするとファイル一式をダウンロードできます。

photoswipe.min.jsphotoswipe-ui-default.min.jsphotoswipe.cssdefault-skin.cssdefault-skin.pngdefault-skin.svgpreloader.gifはzipファイルの中に含まれていません。

Download Zip