上のような写真を散らしたようなレイアウトをJavascript/CSS/HTMLを用いて作ります。
JavaScriptのLightbox系プラグインである「PhotoSwipe」はこのような特殊な配置と相性が良く、これを用いることで、画像の鑑賞性と操作性についても損なうこと無く、画像をデザイン性を持たせて配置することが可能です。
PhotoSwipeによる効果と動作
PhotoSwipeを用いることで、画像をクリックしたときにポップアップで画像を拡大表示することができるようになります。上の画像のいずれかをクリックしてみてください。以下のように画像が拡大されて表示されるはずです。
画面の両端の矢印(<,>)を押すと次の画像に遷移します。スマートフォンなどの端末では、左右にスワイプすることでも移動が可能です。

今回のような、デザイン性重視で写真の鑑賞性を度外視しているようなデザインの場合でも、これを用いることで写真の細部を見せたいという要求に応えることができます。
PhotoSwipeのJavaScript/CSS読み込み
PhotoSwipeを用いるため、JSとCSSのファイルをページの表示の際に取得する必要があります。
方法としては以下の2種類があります。いずれの方法でも実装可能ですが、個人的にはGitHubからファイルを取得して参照できる位置にファイルを配置する1つ目の方法がお勧めです。
方法1:GitHubから読み込み
GitHubのページからファイルをダウンロードして、いくつのファイルを取り出します。多少の手間を惜しまないのであればこちらを使います。
上記のPhotoSwioeのGitHubページにアクセスして、「Code」→「Download ZIP」からファイルをダウンロードします。もしくは「git clone」します。

ダウンロードしたファイルを解凍して、できたディレクトリから以下3つのファイルを取り出します。ファイルを取り出したら、サイトから参照できる位置にアップロードします。
- PhotoSwipe/dist/photoswipe.css
- PhotoSwipe/dist/umd/photoswipe.umd.min.js
- PhotoSwipe/dist/umd/photoswipe-lightbox.umd.min.js
<script src="{PATH:photoswipe.umd.min.js}"></script>
<script src="{PATH:photoswipe-lightbox.umd.min.js}"></script>
<link rel="stylesheet" href="{PATH:photoswipe.css}">
方法2:CDNからの読み込み
CDN(コンテンツ・デリバリ・ネットワーク)を用いて、必要なファイルの読み込みを行います。HTLMに数行追加するだけなの非常に手軽に実装することができます。
上記のページから、以下赤枠3つを取得します。</>をクリックすることで、HTMLへで直接貼り付けられる形式でコピーすることができます。2023/12現在最新はバージョンは5.4.2でした。
GitHubのReleasesについても同じ版数だったので、いずれでも同じ動作を確認できています。

- photoswipe.css
- photoswipe.umd.min.js
- photoswipe-lightbox.umd.min.js
以前CDNを用いていたページで、提供元のサポートが切れてCDNを用いていたページのデザインが気づかない内に一斉に表示が崩れていた経験があるので、このようなことも念頭に置きつつ使用する際には注意が必要です。
ここまでの内容で上記を使ったコードの例を示します。
{PATH:xxx}の箇所はそれぞれ任意のURLやPATHに置き換えするところです。
サイズについては以下の章で自動で画像サイズを取得する実装を紹介しています。imageタグ内のstyleの「pointer-event:none」はこの処理の際の動作調整のために着けているものです。
PhotoSwipeのサンプルコード
ここまでの内容で上記を使ったコードの例を示します。
<!DOCTYPE html>
<html>
<head>
<title>GaPhotoSwipe</title>
</head>
<body>
<script src="{PATH:photoswipe.umd.min.js}"></script>
<script src="{PATH:photoswipe-lightbox.umd.min.js}"></script>
<link rel="stylesheet" href="{PATH:photoswipe.css}">
<div id="gallery">
<a data-pswp-height="{サイズ}" data-pswp-width="{サイズ}" href="{PATH:画像}">
<img style="pointer-events: none" src="{PATH:画像}">
</a>
</div>
<script type="text/javascript">
var lightbox = new PhotoSwipeLightbox({
gallery: '#gallery',
children: 'a',
pswpModule: PhotoSwipe
});
lightbox.init();
</script>
</body>
</html>
サイズについては以下の章で自動で画像サイズを取得する実装を紹介しています。imageタグ内のstyleの「pointer-event:none」はこの処理の際の動作調整のために着けているものです。
CSSによる散らばり配置・レイアウト
PhotoSwipeを用いても、散らばり風のデザインにはならないので、Style Sheetを用いてレイアウトを調整します。以下コードの先頭と末尾の<style></style>はHTML上へ直接記入するときにだけ使用してください。
CSSの例
<style type="text/css">
#gallery {
width: 95%;
margin: 1em auto; /* 上下,左右 */
display: flex;/* 親要素 flex container */
flex-flow: wrap;/* 折り返し */
}
#gallery img {
width: 100%;
height: auto;
border: none;
max-width: 310px;/* サイズ調整 */
margin: 1em 0;
padding: 8px; /* 写真外枠 */
background: #fff;
box-shadow: 0px 5px 5px rgba(0, 0, 0, 0.7);
}
#gallery p {
flex: 270px;/* 子要素 flex Item */
}
.pic-r1 {
z-index: 2;
transform: rotate(-10deg);
}
.pic-r2 {
z-index: 5;
transform: rotate(15deg);
}
.pic-r3 {
z-index: 3;
transform: rotate(5deg);
}
.pic-r4 {
z-index: 5;
transform: rotate(-3deg);
}
.pic-r5 {
z-index: 5;
animation: animation-1 6s infinite ease 1s both;
}
@keyframes animation-1 {
0% {
transform: rotate(8deg);
}
50% {
transform: rotate(-15deg);
}
100% {
transform: rotate(8deg);
}
}
</style>
・画像表示に角度を(18~40行)
・画像のサイズを調節/枠付け(8~17行)
・表示範囲を調節(2~7行)
・画像にアニメーションを付与(41~51行)
整然と画像を整列させて並べるのに比べて、雰囲気を持たせることができます。背景をコルクボード調にしておしゃれな写真レイアウト風にしているようなデザインのものもよく見ます。・画像のサイズを調節/枠付け(8~17行)
・表示範囲を調節(2~7行)
・画像にアニメーションを付与(41~51行)
上の例では、敢えて白の縁取りを行い、画像に影を付けることでチェキで撮影した写真を並べているようなデザインにしています。
画像をHTML上に配置
以下のように画像を挿入します。
<div id="gallery">
<p class="pic-r1">
<a href="{PATH:画像}" data-pswp-width="" data-pswp-height="">
<img src="{PATH:画像}" style="pointer-events: none">
</a>
</p>
<p class="pic-r2">
<a href="{PATH:画像}" data-pswp-width="" data-pswp-height="">
<img src="{PATH:画像}" style="pointer-events: none">
</a>
</p>
</div>
画像配置の角度など細かな要素を定義したclassで画像を囲うことで、画像のレイアウトなどを細かく調節することが可能です。
JavaScriptによる画像サイズの取得
PhotoSwipeによって画像を拡大する際、画像のサイズ情報が必要ですが、サイズを逐一手入力で指定していると面倒なので、画像サイズを自動で取得して属性に挿入できるような工夫をします。
参考にさせていただいたのは以下のページです。
今回はbodyタグの最後に配置しています。
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {
const galleries = gallery.querySelectorAll('a');
galleries.forEach((el) => {
loadImage(el.href).then(img => {
el.setAttribute('data-pswp-width', img.naturalWidth);
el.setAttribute('data-pswp-height', img.naturalHeight);
el.firstElementChild.removeAttribute('style');
});
});
});
function loadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = (e) => reject(e);
img.src = src;
});
}
<script>
実装まとめ
上記までのポイントをまとめた動作するコードを置いておきます。
"1×"や"0.5×"などに切り替えると、画面表示領域のサイズに応じて横並びに表示される画像の枚数についても動的に変化することが分かると思います。
これを基にして自分なりの実装を試してみてください。
See the Pen Untitled by sukima-log (@sukima-log) on CodePen.
参考:
以上、ありがとうございました。