ライトボックス Luminous Lightbox の使い方

Luminous はとても軽量でシンプルな jQuery に依存しない画像用ライトボックスプラグイン(JavaScript)です。

以下は Luminous Lightbox(v2.3.5/2021-08-03)の基本的な使い方や、ギャラリー表示やキャプションの表示方法、画像枚数と現在の画像位置(インデックス)の表示、webpack でのバンドル、WordPress で表示する方法などの解説(覚書)です。

Luminous Github

Luminous Github:https://github.com/imgix/luminous

作成日:2021年9月29日

インストール

Luminous はダウンロードして読み込むか、npm などを使ってインストールすることができます。

ダウンロード

https://github.com/imgix/luminous の右上の「Code」をクリックして「Download ZIP」をクリックするか、本文中(Installation > Manual) の Download リンクをクリックすると luminous-main.zip という ZIP ファイルをダウンロードできるので、保存して解凍します。

解凍したフォルダ(luminous-main)の中の dist 内の以下の JavaScript と CSS ファイルを使います。

  • luminous.min.js
  • luminous-basic.min.css

Luminous Github

CSS(luminous-basic.min.css)は head 内で読み込みます。「path/to/」の部分は適宜変更します。

<head>
   ・・・   
<link rel="stylesheet" href="path/to/luminous-basic.min.css">
   ・・・
</head>

JavaScript は body の閉じタグの直前などで読み込みます。

<script src="path/to/luminous.min.js"></script> 
  ・・・
</body>

luminous.min.js にはソースマップの記述(//# sourceMappingURL=luminous.min.js.map)が最後にあるので、オプションで(必要に応じて)ソースマップファイル(luminous.min.js.map)を luminous.min.js と同じ階層に配置します(読み込む必要はありません)。

WordPress での読み込み

以下は WordPress で使う場合の読み込みの例です。「path/to/」の部分は適宜変更します。

10 行目と18行目は更新時にキャッシュをクリアするための記述ですが、この場合は省略しても良いかと思います。11行目はスクリプトを </body> 終了タグの前に配置するために true を指定しています。

functions.php
function add_my_styles_and_scripts() {	
          
  ・・・その他の読み込み・・

  //JavaScript の読み込み
  wp_enqueue_script( 
    'luminous-js', 
    get_theme_file_uri( '/path/to/luminous.min.js' ), 
    array(), //依存するスクリプトはなし
    filemtime( get_theme_file_path( '/path/to/luminous.min.js' ) ), 
    true //</body> 終了タグの前に配置
  );
  //CSS の読み込み
  wp_enqueue_style(
    'luminous-style',
    get_theme_file_uri( '/path/to/luminous-basic.min.css' ),
    array(),  //依存するスタイルシートはなし
    filemtime( get_theme_file_path( '/path/to/luminous-basic.min.css' ) )
  );
}
add_action('wp_enqueue_scripts', 'add_my_styles_and_scripts');

関連ページ:WordPress CSSやJavaScriptファイルの読み込み

npm

npmコマンドを使ってインストールする場合はプロジェクトのフォルダで以下を実行します。

npm install luminous-lightbox
webpack

以下は webpack を使ってバンドルする場合のエントリポイントでの記述例です。CSS をバンドルする場合は CSS ローダーや style ローダー(必要に応じて MiniCssExtractPlugin)が必要です。CSS をバンドルしない場合は、別途 head 内で読み込みます。

エントリポイント(index.js など)
//Luminous と LuminousGallery(ギャラリー表示用)のインポート(ES6)
import { Luminous, LuminousGallery } from 'luminous-lightbox';

/* 以下は require を使って読み込む場合
const Luminous = require('luminous-lightbox').Luminous;
const LuminousGallery = require('luminous-lightbox').LuminousGallery;
*/

//CSS のインポート(CSS ローダーが必要)
import 'luminous-lightbox/dist/luminous-basic.min.css';

関連ページ:webpack の基本的な使い方

Luminous の使い方

基本的な使い方は JavaScript で Luminous を初期化し、HTML でライトボックス表示する画像を任意のクラス名を設定した a 要素で囲み、href 属性に拡大表示(ポップアップ)する画像のパスを指定します。

Luminous にはそのページで1つの画像のみに適用する方法(単体表示)と複数の画像に適用する方法(ギャラリー表示)があります。

単体表示

対象の img 要素を任意のクラス名(以下の場合は luminous)を設定した a 要素で囲みます。a 要素の href 属性には拡大表示する画像のパスを指定します。

以下の場合、01-w600.jpg は表示画像(サムネイル)で、01-w1800.jpg は拡大表示する画像です(表示画像と拡大画像に同じ画像を指定することもできます)。パスは適宜環境に合わせて変更します。

HTML
<a class="luminous" href="../img/01-w1800.jpg">
  <img src="../img/01-w600.jpg" width="300" height="185" alt="Lotus">
</a>

JavaScript では querySelector() などを使って任意のクラス名(この例の場合は luminous)を設定した a 要素(trigger element)を取得して、new Luminous() の引数に渡して初期化します。

そのページに対象の要素がない場合は、初期化を行わないようにするため、querySelector() の戻り値が null でない場合にのみ初期化するようにしています。

JavaScript
//luminous クラスを指定した a 要素を取得
const luminousElem = document.querySelector('.luminous');

//上記で要素が取得できていれば Luminous を初期化
if( luminousElem !== null ) {
  new Luminous(luminousElem);
}

new Luminous() の第1引数には DOM 要素を指定する必要があります。querySelector() は一致する要素がない場合は null を返すので、一致する要素がない場合は new Luminous() に null が渡されて「Uncaught TypeError: `new Luminous` requires a DOM element as its first argument.」のようなエラーが発生します。

複数画像の単体表示

Luminous には複数の画像をライトボックス表示するためのギャラリー表示機能(LuminousGallery)がありますが、ギャラリー表示ではなく、複数の画像をそれぞれ単体表示するには、querySelectorAll() などを使って複数の a 要素(trigger element)をまとめて取得し、それぞれの要素に対して new Luminous() で初期化します。

以下の例では a 要素に luminous2 というクラスを指定しています。

HTML
<div class="col-md-4">
  <a class="luminous2" href="../img/01-w1800.jpg"> 
    <img src="../img/01-w600.jpg" alt="" width="300" height="185"> 
  </a> 
</div>
<div class="col-md-4">
  <a class="luminous2" href="../img/02-w1800.jpg"> 
    <img src="../img/02-w600.jpg" alt="" width="300" height="185"> 
  </a> 
</div>
<div class="col-md-4">
  <a class="luminous2" href="../img/03-w1800.jpg"> 
    <img src="../img/03-w600.jpg" alt="" width="300" height="185"> 
  </a> 
</div>

以下では querySelectorAll() で luminous2 クラスを指定した全ての a 要素を取得し、取得した要素の数が 0 より大きければ、NodeList のメソッド forEach() を使ってそれぞれの要素に対して new Luminous() で初期化しています。

JavaScript
//querySelectorAll() で全ての luminous2 クラスを指定した a 要素を取得
const luminousElems = document.querySelectorAll('.luminous2');
  
//取得した要素の数が 0 より大きければ
if( luminousElems.length > 0 ) {
  luminousElems.forEach( (elem) => {
    new Luminous(elem);
  });
}

ギャラリー表示(LuminousGallery)

LuminousGallery を使うと、拡大表示した際に前後の画像へのナビゲーションを表示して、複数の画像にライトボックスを適用することができます。

以下の例では a 要素(trigger element)に luminous3 というクラスを指定しています。

HTML
<div class="col-md-4">
  <a class="luminous3" href="../img/01-w1800.jpg"> 
    <img src="../img/01-w600.jpg" alt="" width="300" height="185"> 
  </a> 
</div>
<div class="col-md-4">
  <a class="luminous3" href="../img/02-w1800.jpg"> 
    <img src="../img/02-w600.jpg" alt="" width="300" height="185"> 
  </a> 
</div>
<div class="col-md-4">
  <a class="luminous3" href="../img/03-w1800.jpg"> 
    <img src="../img/03-w600.jpg" alt="" width="300" height="185"> 
  </a> 
</div>

JavaScript では取得した要素の集まり(NodeList や HTMLCollection)を new LuminousGallery() に渡して初期化します。

JavaScript
//querySelectorAll() で全ての luminous3 クラスを指定した a 要素を取得
const luminousGalleryElems = document.querySelectorAll('.luminous3');
// または getElementsByClassName() を使っても同じ
//const luminousGalleryElems = document.getElementsByClassName('luminous3');

//取得した要素の数が 0 より大きければ
if( luminousGalleryElems.length > 0 ) {
  // LuminousGallery で初期化
  new LuminousGallery(luminousGalleryElems);
}

キャプションの表示

キャプションを表示するには、初期化の際にオプションの caption を指定します。

※ 単体表示の new Luminous() では第2引数に、ギャラリー表示の new LuminousGallery() では第3引数にオプションの caption を指定します。

デフォルトではオプションの caption は null になっていますが、文字列または文字列を返す関数を指定することができます。

caption に関数を指定する場合、その関数は a 要素(trigger element)を引数として受け取ります。関数が返す文字列(キャプションとして出力される値)は HTML も記述できるため、ユーザーからの入力を利用する場合はエスケープするなど注意が必要です。

単体表示のキャプション

以下は画像の alt 属性の値をキャプションとする例です。

HTML
<a class="luminous4" href="../img/01-w1800.jpg">
  <img src="../img/01-w600.jpg" width="300" height="185" alt="白い蓮の花">
</a>

caption: に指定する関数に渡される引数 trigger は a 要素(trigger element)です。

JavaScript
//オプションの設定
const luminousOpts = {
  //alt 属性の値をキャプションに表示
  caption: (trigger) => {
    //img 要素に alt 属性が設定されていれば
    if(trigger.querySelector('img').hasAttribute('alt')) {
      //img 要素の alt 属性の値を取得して返す
      return trigger.querySelector('img').getAttribute('alt');
    }else{
      return '';
    }
  },
}

const luminousElemCaption = document.querySelector('.luminous4');
if( luminousElemCaption !== null ) {
  //第2引数にオプションを指定
  new Luminous(luminousElemCaption, luminousOpts);
}

上記では、img 要素に alt 属性が設定されていることを確認してから alt 属性の値を取得して返していますが、img 要素には alt 属性は必須なのと、getAttribute() も指定した属性が存在しない場合はほとんどのブラウザは null ではなく、空文字列を返すようなので以下のように記述しても問題ないかと思います。

const luminousOpts = {
  caption: (trigger) => {
    return trigger.querySelector('img').getAttribute('alt');
  },
}

白い蓮の花

a 要素の data-* 属性の値をキャプションに表示

以下は a 要素に data-caption 属性が設定されていて、その値が空でない場合はその値をキャプションとして表示する例です。

a 要素に data-caption 属性が設定されていない場合は img 要素の alt 属性の値をキャプションとして表示します。

HTML
<a class="luminous5" href="../img/01-w1800.jpg" data-caption="白い蓮の花(data-caption)"> 
  <img src="../img/01-w600.jpg" width="300" height="185" alt="白い蓮の花の画像">
</a>
JavaScript
//オプションの設定
const luminousOpts2 = {
  caption: (trigger) => {
    //a 要素に data-caption 属性が設定されていて、その値が空でない場合
    if(trigger.hasAttribute('data-caption') && trigger.getAttribute('data-caption') !== '') {
      //a 要素の data-caption 属性の値をキャプションとして表示
      return trigger.getAttribute('data-caption');
    }else{
      //a 要素の data-caption 属性が設定されていなければ img 要素の alt 属性の値を表示
      return trigger.querySelector('img').getAttribute('alt');
    }
  },
}

const luminousElemCaption2 = document.querySelector('.luminous5');
if( luminousElemCaption2 !== null ) {
  new Luminous(luminousElemCaption2, luminousOpts2);
}

白い蓮の花の画像

figcaption の値をキャプションに表示

以下は figcaption の値をキャプションに表示する例です。figcaption が設定されていない場合や figcaption の値が空の場合は alt 属性の値をキャプションとして表示します。

figcaption 要素は、Node インターフェイスの parentElement プロパティを使って a 要素(trigger)の親要素を起点に querySelector() で取得しています。

HTML
<figure>
  <a class="luminous6" href="../img/02-w1800.jpg"> 
    <img src="../img/02-w600.jpg" alt="庭の石の上の猫の画像" width="300" height="185"> 
  </a> 
  <figcaption>庭に来る半野良の猫(トラ)</figcaption>
</figure>
JavaScript
const luminousOpts3 = {
  caption: (trigger) => {
    //figcaption 要素を取得
    const figCaption = trigger.parentElement.querySelector('figcaption');
    if(figCaption !== null && figCaption.textContent !== '') {
      return figCaption.textContent;
    }else{
      if(trigger.querySelector('img').hasAttribute('alt')) {
        return trigger.querySelector('img').getAttribute('alt');
      }else{
        return '';
      }
    }
  },
}
const luminousElemCaption3 = document.querySelector('.luminous6');
if( luminousElemCaption3 !== null ) {
  new Luminous(luminousElemCaption3, luminousOpts3);
}
庭の石の上の猫の画像
庭に来る半野良の猫(トラ)
ギャラリー表示のキャプション

ギャラリー表示(LuminousGallery)の場合、new LuminousGallery() の第2引数にはギャラリーオプションを指定し、第3引数に caption のオプションを指定します。

この例では第2引数に指定するギャラリーオプションは特に指定しないので(あまり指定するオプションもないようなので)、第2引数には空のオブジェクト { } を指定しています。

その他は前述の caption のオプションと同じです。

JavaScript
// caption のオプション(img 要素の alt 属性の値をキャプションに表示)
const luminousOpts4 = {
  caption: (trigger) => {
    return trigger.querySelector('img').getAttribute('alt');
  },
} 
  
const luminousGalleryElems2 = document.querySelectorAll('.luminous7');
if( luminousGalleryElems2.length > 0 ) {
  //第3引数に caption のオプションを指定
  new LuminousGallery(luminousGalleryElems2, {}, luminousOpts4);
} 
HTML
<div class="col-md-4">
  <a class="luminous7" href="../img/01-w1800.jpg"> 
    <img src="../img/01-w600.jpg" alt="白い蓮の花" width="300" height="185"> 
  </a> 
</div>
<div class="col-md-4">
  <a class="luminous7" href="../img/02-w1800.jpg"> 
    <img src="../img/02-w600.jpg" alt="庭に来る半野良の猫" width="300" height="185"> 
  </a> 
</div>
<div class="col-md-4">
  <a class="luminous7" href="../img/03-w1800.jpg"> 
    <img src="../img/03-w600.jpg" alt="枝垂れ桜と経堂" width="300" height="185"> 
  </a> 
</div>
画像枚数と現在の画像のインデックスの表示

以下はギャラリー表示でキャプションに画像の枚数と現在表示されている画像のインデックス(位置)を表示する例です。

ギャラリー表示の対象の画像の枚数は、a 要素(trigger element)に指定されているクラスを持つ全ての要素を取得してその長さを取得します。

以下の例では配列のメソッド indexOf() を使って現在の位置を取得するため、querySelectorAll() で取得した要素の集まり(NodeList)を配列に変換しています。

caption のコールバック関数の引数 trigger は現在表示されている画像のリンク要素(a 要素)なので、indexOf() に trigger を指定してインデックスを取得しています(配列のインデックスは0から始まるので1を加算)。

caption には HTML が使えるので、クラスを指定した span 要素で画像枚数とインデックスを囲んでスタイルを設定できます。

//caption のオプション
const luminousOptsFr = {
  caption: (trigger) => {
    //a 要素(trigger element)に指定されているクラスを持つ全ての要素を取得して配列に変換
    const elemsArray =  Array.prototype.slice.call( document.querySelectorAll('.' + trigger.className) ) ;
    //画像の枚数
    const total = elemsArray.length;
    //現在の画像のインデックス(添字 + 1)
    const index = elemsArray.indexOf( trigger ) + 1 ;
    //画像の alt 属性の値及び画像枚数とインデックスをキャプションとする
    return trigger.querySelector('img').getAttribute('alt') + 
           '<span class="fraction">' + index + '/' + total + '</span>';
  },
} 

const luminousGalleryElemsFr = document.querySelectorAll('.luminousFr');
if( luminousGalleryElemsFr.length > 0 ) {
  new LuminousGallery(luminousGalleryElemsFr, {}, luminousOptsFr);
}  

上記の場合、画像の alt 属性の値をキャプションとしていますが、画像枚数とインデックスだけを表示する場合は以下のようになります。また、以下の例では配列のようなオブジェクトを配列に変換するのに Array.from() を使っています。

const luminousOptsFr = {
  caption: (trigger) => {
    // この例では Array.from() を使って配列に変換
    const elemsArray = Array.from(document.querySelectorAll('.' + trigger.className));
    const total = elemsArray.length;
    const index = elemsArray.indexOf( trigger ) + 1 ;
    return index + '/' + total;
  },
} 
HTML
<div class="col-md-4">
  <a class="luminousFr" href="../img/01-w1800.jpg"> 
    <img src="../img/01-w600.jpg" alt="白い蓮の花" width="300" height="185"> 
  </a> 
</div>
<div class="col-md-4">
  <a class="luminousFr" href="../img/02-w1800.jpg"> 
    <img src="../img/02-w600.jpg" alt="庭に来る半野良の猫" width="300" height="185"> 
  </a> 
</div>
<div class="col-md-4">
  <a class="luminousFr" href="../img/03-w1800.jpg"> 
    <img src="../img/03-w600.jpg" alt="枝垂れ桜と経堂" width="300" height="185"> 
  </a> 
</div>

この例では画面幅が 460px より大きい場合は、画像枚数とインデックスは position: absolute と right: 0 で右端に表示し、画面幅が 460px 以下の場合はキャプションの右側に表示するようにしています。画面幅を 460px で切り替えているのは、luminous-basic.css のメディアクエリに合わせているためです。

CSS
span.fraction {
  display: inline-block;
  position: absolute;
  right: 0; 
  font-size: 12px;
  color: #bbb;
}
  
@media (max-width: 460px) {
  span.fraction {
    position: relative;
    margin-left: 2rem;
  }
  /* 独自の設定 */
  .lum-lightbox-inner img {
    max-width: 240vw;
    max-height: 90vh;
  }
  /* 独自の設定 */
  .lum-lightbox-caption {
    position: relative;
  }
}

以下は left: 0; と top: 0; を指定して左上に表示する例です(画面幅や画像サイズによっては画像の上に表示されます)。

CSS
span.fraction {
  display: inline-block;
  position: absolute;
  left: 0;
  top: 0;
  font-size: 12px;
  color: #fff;
}

表示する span 要素(span.fraction)を絶対配置にした場合、その基準となる要素(position が static 以外の要素)は div.lum-lightbox-inner になります。

<div class="lum-lightbox lum-open">
  <div class="lum-lightbox-inner"><!-- 基準となる要素 -->
    <div class="lum-lightbox-loader"></div>
    <div class="lum-lightbox-image-wrapper">
      <span class="lum-lightbox-position-helper">
        <img class="lum-img" src="../img/01-w1800.jpg">
        <p class="lum-lightbox-caption">白い蓮の花<span class="fraction">1/3</span></p>
      </span>
    </div>
    <button class="lum-previous-button lum-gallery-button">previous</button>
    <button class="lum-next-button lum-gallery-button">next</button>
  </div>
  <div class="lum-close-button"></div>
</div>
luminous-basic.css 抜粋
.lum-lightbox-inner {
  top: 2.5%;
  right: 2.5%;
  bottom: 2.5%;
  left: 2.5%;
}

そのため、画面幅や画像サイズによって表示される位置が異なってくるので、キャプションの中に配置した方が無難かもしれません。

関連項目:何番目の要素か(インデックス)を取得

サンプル

以下はキャプションと画像枚数と現在の画像のインデックスを表示する例です。

1つのページ内で異なるクラス(lumi1, lumi2, lumi3, lumi4, lumi5)を指定することにより、複数のギャラリー表示ができます。以下のサンプルでは .lumi1 を指定しています。

また、キャプションは .caption を指定した要素があればそのテキスト、figcaption 要素があればそのテキスト、いずれもない場合は alt 属性の値を表示します。

HTML
<div class="row">
  <div class="col-md-4"> 
    <a class="lumi1" href="../img/01-w1800.jpg"> 
      <img src="../img/01-w600.jpg" alt="白い蓮の花の写真" width="300" height="185">
    </a> 
    <p class="caption">白い蓮の花(.caption)</p>
  </div>
  <div class="col-md-4">
    <figure> 
      <a class="lumi1" href="../img/02-w1800.jpg"> 
        <img src="../img/02-w600.jpg" alt="庭に来た半野良の猫の写真" width="300" height="185"> 
      </a>
      <figcaption>庭に来る半野良の猫(figcaption)</figcaption>
    </figure>
  </div>
  <div class="col-md-4"> 
    <a class="lumi1" href="../img/03-w1800.jpg"> 
      <img src="../img/03-w600.jpg" alt="枝垂れ桜と経堂の写真(alt 属性)" width="300" height="185"> 
    </a> 
  </div>
</div>
JavaScript
for(let i=1; i<6; i++) {
  //キャプション(オプション)
  let lumiOptsX =  'lumiOptsX' + i;
  lumiOptsX = {
    caption: (trigger) => {
      //a 要素(trigger element)に指定されているクラスを持つ全ての要素を取得して配列に変換
      const elemsArray =  Array.prototype.slice.call( document.querySelectorAll('.' + trigger.className) ) ;
      //画像の枚数
      const total = elemsArray.length;
      //現在の画像のインデックス(添字 + 1)
      const index = elemsArray.indexOf( trigger ) + 1 ;
      //.caption を指定した要素
      const captionElem = trigger.parentElement.querySelector('.caption');
      //figcaption 要素
      const figCaption = trigger.parentElement.querySelector('figcaption');
      
      //.caption を指定した要素、または figcaption 要素のテキストをキャプションに(いずれもない場合は alt 属性の値) 
      if(captionElem !== null && captionElem.textContent !== '') {
        //画像枚数が1枚より大きければインデックスをキャプションに追加
        if(total > 1) {
          return captionElem.textContent + '<span class="fraction">' + index + ' / ' + total + '</span>';
        }else{
          return captionElem.textContent;
        }
      }else if(figCaption !== null && figCaption.textContent !== '') {
        if(total > 1) {
          return figCaption.textContent + '<span class="fraction">' + index + ' / ' + total + '</span>';
        }else{
          return figCaption.textContent;
        }
      }else{
        if(trigger.querySelector('img').hasAttribute('alt')) {
          if(total > 1) {
            return trigger.querySelector('img').getAttribute('alt') + '<span class="fraction">' + index + ' / ' + total + '</span>';
          }else{
            return trigger.querySelector('img').getAttribute('alt');
          } 
        }else{
          if(total > 1) {
            return index + ' / ' + total ;
          }else{
            return '';
          } 
        }
      }
    },
  } 
  //lumi1, lumi2, lumi3, lumi4, lumi5 クラス
  const lumiClass =  '.lumi' + i;
  let lumiGalleries = document.querySelectorAll(lumiClass);
  if( lumiGalleries.length > 0 ) {
    new LuminousGallery(lumiGalleries, {}, lumiOptsX);
  }
} 
CSS
.lumi1 + .caption, .lumi1 + figcaption {
  text-align: center;
  color: #999;
  opacity: 0;
  transition:  opacity 0.4s ease 0s;
}
.lumi1:hover + .caption, .lumi1:hover + figcaption {
  opacity: 1;
}
.lumi1 img {
  opacity: 1;
  transition:  opacity 0.4s ease 0s;
}
.lumi1:hover img {
  opacity: .75;
}
span.fraction {
  display: inline-block;
  position: absolute;
  right: 0;
  font-size: 12px;
  color: #bbb;
}
@media (max-width: 460px) {
  span.fraction {
    position: relative;
    margin-left: 2rem;
  }
}
白い蓮の花の写真

白い蓮の花(.caption)

庭に来た半野良の猫の写真
庭に来る半野良の猫(figcaption)

options

以下は、Luminous に用意されているオプションと単体表示とギャラリー表示でのオプションの設定例です。ギャラリー表示(LuminousGallery)の場合は、第2引数はギャラリーオプションを指定し、第3引数にオプションを指定します。

ギャラリー表示(LuminousGallery)の場合、第2引数のギャラリーオプションを指定する必要がない場合は、空のオブジェクトを指定します。

また、オプションは生成する Luminous または LuminousGallery のインスタンスにそれぞれ作成して設定します(内容が同じだからと言って、共用すると期待通りの動作にならないようです)。

//デフォルトのオプション
var options = {
  namespace: null,
  sourceAttribute: "href",
  caption: null, //キャプション
  openTrigger: "click",
  closeTrigger: "click",
  closeWithEscape: true,
  closeOnScroll: false,
  showCloseButton: true, //ドキュメントでは false となっている
  appendToNode: document.body,
  appendToSelector: null,
  onOpen: null,
  onClose: null,
  includeImgixJSClass: false,
  injectBaseStyles: true
};

//単体表示の場合(第2引数にオプションを指定)
new Luminous(document.querySelector(".luminous"), options);

//ギャラリー表示の場合(第3引数にオプションを指定)
new LuminousGallery(document.querySelector(".luminous"), {}, options);
オプション 意味 デフォルト値
namespace ライトボックス表示する際に生成される要素に付与されるクラス名のプレフィックス。例えば、'wdl' を指定すると外側の div 要素には wdl-lightbox や wdl-open クラスが追加されます。デフォルトのクラス(lum-lightbox や lum-open など)は常に付与されます。独自クラスの追加 null
sourceAttribute ライトボックス画像(拡大画像)のパスを指定する属性 "href"
caption キャプションに表示する文字列や文字列を返す関数。キャプションへの出力はエスケープされないのでユーザーの入力値を使用する場合は注意が必要です。 null
openTrigger ライトボックス画像を表示する際のイベント "click"
closeTrigger ライトボックス画像を閉じる際のイベント "click"
closeWithEscape esc キーを押すことでクローズさせるかどうか true
closeOnScroll スクロールでクローズさせるかどうか false
showCloseButton クローズ(閉じる)ボタンを表示するかどうか true
appendToNode ライトボックス画像を追加(append)するノード document.body
appendToSelector ライトボックス画像を追加(append)する要素(セレクタ)。appendToNode よりも優先されます。 null
onOpen ライトボックス画像を表示する際に呼び出される関数 null
onClose ライトボックス画像を閉じる際に呼び出される関数 null
includeImgixJSClass true を指定すると、ライトボックス内の img 要素に imgix-fluid と言うクラスを追加します。 false
injectBaseStyles 基本スタイルを追加するかどうか。追加されるスタイルは injectBaseStylesheet.js により挿入されます。 true

ソースコード

CSS スタイル

必要に応じて独自のスタイルシートで Luminous のスタイルを上書きします。

Luminous のスタイルは luminous-basic.css に記述されているので、それを元にスタイルを設定します。

以下はライトボックス画像が表示される際に </body> の直前に挿入される HTML の例です。

<div class="lum-lightbox lum-open">
  <div class="lum-lightbox-inner">
    <div class="lum-lightbox-loader"></div>
    <div class="lum-lightbox-image-wrapper" style="width: 1603px; max-width: 1603px; height: 411px; max-height: 411px;">
      <span class="lum-lightbox-position-helper">
        <img class="lum-img" src="..img/01-w1800.jpg">
        <p class="lum-lightbox-caption">白い蓮の花</p>
      </span>
    </div>
    <button class="lum-previous-button lum-gallery-button">previous</button>
    <button class="lum-next-button lum-gallery-button">next</button>
  </div>
  <div class="lum-close-button"></div>
</div>

luminous-basic.css には例えば以下のような記述があります。

luminous-basic.css 抜粋
.lum-lightbox {
  /* ライトボックスの背景色 */
  background: rgba(0, 0, 0, 0.6);  
}

/* ライトボックス画像の表示領域 */
.lum-lightbox-inner {
  top: 2.5%;
  right: 2.5%;
  bottom: 2.5%;
  left: 2.5%;
}

.lum-lightbox-inner img {
  position: relative;
}

/* キャプション(画面幅が460px以上の場合) */
.lum-lightbox-inner .lum-lightbox-caption {
  margin: 0 auto;
  color: #fff;
  max-width: 700px;
  text-align: center;
}

以下は独自のスタイルシートで、背景色を上書きし、z-index を追加する例です。

独自のスタイルシート
  
.lum-lightbox {
  background: rgba(0, 0, 0, 0.7);  /* 背景色を上書き */
  z-index: 9999;    /* z-index を追加  */
}

以下はクローズボタンのスタイルです。X 印は :before と :after で幅2px、高さ32px、背景色が白の疑似要素をそれぞれ45度回転させて作成されています。

luminous-basic.css 抜粋(クローズボタン部分)
.lum-close-button {
  position: absolute;
  right: 5px; /* ボタンの位置 */
  top: 5px; /* ボタンの位置 */
  width: 32px; /* ボタンの幅 */
  height: 32px; /* ボタンの高さ */
  opacity: 0.3;
}
.lum-close-button:hover {
  opacity: 1;
}
.lum-close-button:before,
.lum-close-button:after {
  position: absolute;
  left: 15px;
  content: " ";
  height: 33px; /* X 印の高さ(長さ)*/
  width: 2px;  /* X 印の幅(太さ)*/
  background-color: #fff;
}
.lum-close-button:before {
  transform: rotate(45deg);
}
.lum-close-button:after {
  transform: rotate(-45deg);
}

以下はギャラリー表示の際に表示される前後の画像への矢印ボタンのスタイルです。

luminous-basic.css 抜粋(ギャラリーボタン)
.lum-previous-button {
  left: 12px;
}

.lum-next-button {
  right: 12px;
}

/* 左右の矢印ボタンの共通のスタイル */
.lum-gallery-button:after {
  content: "";
  display: block;
  position: absolute;
  top: 50%;
  width: 36px;
  height: 36px;
  border-top: 4px solid rgba(255, 255, 255, 0.8);
}

.lum-previous-button:after {
  transform: translateY(-50%) rotate(-45deg);
  border-left: 4px solid rgba(255, 255, 255, 0.8);
  box-shadow: -2px 0 rgba(0, 0, 0, 0.2);
  left: 12%;
  border-radius: 3px 0 0 0;
}

.lum-next-button:after {
  transform: translateY(-50%) rotate(45deg);
  border-right: 4px solid rgba(255, 255, 255, 0.8);
  box-shadow: 2px 0 rgba(0, 0, 0, 0.2);
  right: 12%;
  border-radius: 0 3px 0 0;
}
メディアクエリ

メディアクエリは 460px 以下のものが1つだけ設定されているので必要に応じて追加します。以下は luminous-basic.css に記述されている画面幅が460px以下でのスタイルです。

img の max-width と max-height が none に設定され、画像のサイズそのままが表示されるようになっていて、大きな画像の場合はユーザーはスクロールして見ることができるようになっています。

luminous-basic.css 抜粋(メディアクエリ部分)
@media (max-width: 460px) {
  .lum-lightbox-image-wrapper {
    display: flex;
    overflow: auto;
    -webkit-overflow-scrolling: touch;
  }

  .lum-lightbox-caption {
    width: 100%;
    position: absolute;
    bottom: 0;
  }

  .lum-lightbox-position-helper {
    margin: auto;
  }
  
  /* 画像のサイズそのままが表示される */
  .lum-lightbox-inner img {
    max-width: none;
    max-height: none;
  }
}

以下は画面幅が460px以下でも画像が画面サイズ内に収まるように表示する例です(値は適当です)。

独自のスタイルシート
@media (max-width: 460px) {
  .lum-lightbox-inner img {
    max-width: 100vw;
    max-height: 95vh;
  }
}

以下はこのページの設定例です。

画面幅が460px以下の場合、画像の横幅は最大で画面幅の2.4倍、高さは最大 90vh、キャプションは position: relative にして、クローズボタンの存在がわかりやすいように背景色や opacity を変更しています。

独自のスタイルシート
@media (max-width: 460px) {
  .lum-lightbox-inner img {
    max-width: 240vw;
    max-height: 90vh;
  }
  .lum-lightbox-caption {
    position: relative;
  }
  .lum-close-button {
    opacity: 0.7;
    background: rgba(0,0,0,.8);
    border-radius: 50%;
  }
}
独自クラスの追加

全てのライトボックス表示のスタイルの変更は前述のように既存のスタイルを上書きすればよいのですが、複数のライトボックスのクラスを設定している場合で、特定のライトボックスに異なるスタイルを適用するにはオプションの namespace を設定して、独自のクラスを追加し、そのクラスに対してスタイルを設定することができます。

以下はオプションの namespace に 'blue' を設定する例です。

JavaScript
const luminousOpts5 = {
  //オプションの namespace に 'blue' を設定
  namespace: 'blue',
  //キャプション
  caption: (trigger) => {
    return trigger.querySelector('img').getAttribute('alt');
  },
}
//luminous8 クラスを指定した要素を取得
const luminousGalleryElems3 = document.querySelectorAll('.luminous8');

//取得した要素が1つ以上あればギャラリー表示のライトボックスを生成
if( luminousGalleryElems3.length > 0 ) {
  //上記オプションを指定して初期化
  new LuminousGallery(luminousGalleryElems3, {}, luminousOpts5);
} 

ライトボックス表示する画像を囲んだ a 要素に luminous8 クラスを指定

HTML
<div class="col-md-4">
  <a class="luminous8" href="../img/01-w1800.jpg"> 
    <img src="../img/01-w600.jpg" alt="白い蓮の花" width="300" height="185"> 
  </a> 
</div>
<div class="col-md-4">
  <a class="luminous8" href="../img/02-w1800.jpg"> 
    <img src="../img/02-w600.jpg" alt="庭に来る半野良の猫" width="300" height="185"> 
  </a> 
</div>
<div class="col-md-4">
  <a class="luminous8" href="../img/03-w1800.jpg"> 
    <img src="../img/03-w600.jpg" alt="枝垂れ桜と経堂" width="300" height="185"> 
  </a> 
</div>

ライトボックス表示された画像には、namespace に設定した 'blue' を含むクラス(blue-lightbox や blue-lightbox-inner など)が追加されます。

全ての既存のクラス名の「lum」の部分を namespace に設定した文字列に置き換えたクラスが追加されます(既存のクラスはそのまま残ります)。

ライトボックスの HTML
<div class="lum-lightbox blue-lightbox lum-open blue-open">
  <div class="lum-lightbox-inner blue-lightbox-inner">
    <div class="lum-lightbox-loader blue-lightbox-loader"></div>
    <div class="lum-lightbox-image-wrapper blue-lightbox-image-wrapper" style="width: 357px; max-width: 357px; height: 752px; max-height: 752px;">
      <span class="lum-lightbox-position-helper blue-lightbox-position-helper">
        <img class="lum-img blue-img" src="../samples/plugins/luminous/img/01-w1800.jpg">
        <p class="lum-lightbox-caption blue-lightbox-caption">白い蓮の花</p>
      </span>
    </div>
    <button class="lum-previous-button blue-previous-button lum-gallery-button blue-gallery-button">previous</button>
    <button class="lum-next-button blue-next-button lum-gallery-button blue-gallery-button">next</button>
  </div>
  <div class="lum-close-button blue-close-button"></div>
</div>  

例えば、以下のように追加されたクラスを使って、そのライトボックスのみにスタイルを適用することができます。

.blue-lightbox {
  background: rgba(51,68,166,0.6); /* 背景色を変更 */
}

WordPress で表示

以下は WordPress で Luminous を使ってライトボックス表示する例です。

この例ではテーマのディレクトリ内に「luminous」というディレクトリを作成し、その中にLuminous 関連のファイルを配置しています。

wp-content
  └── themes         
      ├── index.php
      └── my-theme //使用するテーマのディレクトリ
          ├── content.php
          ├── footer.php
          ├── functions.php
          ├── header.php
          ├── index.php
          ├── luminous //Luminous 関連のファイルを格納するフォルダ
          │   ├── luminous-basic.min.css //ダウンロードしたファイル
          │   ├── luminous.min.js //ダウンロードしたファイル
          │   └── myLuminous.js //初期化などを記述したファイル
          ├── sidebar.php
          ├── single.php
          └── style.css

以下は Luminous の初期化を記述したファイル myLuminous.js です。

ライトボックス表示用のクラスを2つ用意しています。

  • .luminous:ページに対象の要素が複数ある場合は LuminousGallery でギャラリー表示し、1つだけの場合 Luminous で単体表示
  • .lumi-solo:ページに対象の要素が複数ある場合でも常に単体表示

また、キャプションはどちらの場合も figcaption 要素に値が記述されていれば、その値を表示し、figcaption 要素がなければ img 要素の alt 属性の値を表示します。

※オプションの設定内容は全く同じですが、それぞれ個別に設定します。

myLuminous.js
//オプション(キャプション)の設定
const luminousOpts = {
  caption: (trigger) => {
    const figCaption = trigger.parentElement.querySelector('figcaption');
    if(figCaption !== null && figCaption.textContent !== '') {
      return figCaption.textContent;
    }else{
      if(trigger.querySelector('img').hasAttribute('alt')) {
        return trigger.querySelector('img').getAttribute('alt');
      }else{
        return '';
      }
    }
  },
}

//luminous クラス(単体&ギャラリー表示用)を指定した a 要素を取得
const luminousElems = document.querySelectorAll('.luminous');
 
if( luminousElems !== null ) {
  if( luminousElems.length > 1 ) {
    //対象の要素が複数ある場合は LuminousGallery でギャラリー表示
    new LuminousGallery(luminousElems, {}, luminousOpts);
  }else if(luminousElems[0]){
    //対象の要素が1つだけの場合 Luminous で単体表示
    new Luminous(luminousElems[0], luminousOpts);
  }
}

//アイキャッチ画像用オプション(キャプション)の設定
const lumiSoloOpts = {
  caption: (trigger) => {
    const figCaption = trigger.parentElement.querySelector('figcaption');
    if(figCaption !== null && figCaption.textContent !== '') {
      return figCaption.textContent;
    }else{
      if(trigger.querySelector('img').hasAttribute('alt')) {
        return trigger.querySelector('img').getAttribute('alt');
      }else{
        return '';
      }
    }
  },
}

//lumi-solo クラス(アイキャッチ画像用:ページに1つのみ)を指定した a 要素を取得
const lumiSoloElem = document.querySelector('.lumi-solo');
 
//上記で要素が取得できていれば Luminous を初期化
if( lumiSoloElem !== null ) {
  new Luminous(lumiSoloElem, lumiSoloOpts);
}

functions.php

functions.php ではダウンロードした Luminous の CSS と JavaScript、及び上記のファイルを読み込みます。

functions.php
function add_my_styles_and_scripts() {
          
   ・・・その他の読み込み・・
  
  //Luminous の JavaScript の読み込み
  wp_enqueue_script( 
    'luminous-js', 
    get_theme_file_uri( '/luminous/luminous.min.js' ), 
    array(), //依存するスクリプトはなし
    filemtime( get_theme_file_path( '/luminous/luminous.min.js' ) ), 
    true //</body> 終了タグの前に配置
  );
  //Luminous の設定(初期化を記述したファイル)の読み込み
  wp_enqueue_script( 
    'my-luminous', 
    get_theme_file_uri( '/luminous/myLuminous.js' ), 
    array('luminous-js'), //依存するスクリプト(Luminous の JavaScript)
    filemtime( get_theme_file_path( '/luminous/myLuminous.js' ) ), 
    true //</body> 終了タグの前に配置
  );
  //CSS の読み込み
  wp_enqueue_style(
    'luminous-style',
    get_theme_file_uri( '/luminous/luminous-basic.min.css' ),
    array(),  //依存するスタイルシートはなし
    filemtime( get_theme_file_path( '/luminous/luminous-basic.min.css' ) )
  );
  
}
add_action( 'wp_enqueue_scripts', 'add_my_styles_and_scripts' );
投稿に挿入した画像の表示

投稿に挿入した画像をライトボックス表示するには、投稿の編集画面でライトボックス表示する画像の設定でリンク先を「メディアファイル」にして「リンクCSSクラス」に myLuminous.js で設定したクラス「luminous」または「lumi-solo」を指定します。

キャプションを表示するには「Altテキスト」またはその画像のキャプションを設定します。

WordPress 投稿画面

アイキャッチ画像の表示

アイキャッチ画像をライトボックス表示するには、テンプレートファイル(single.php など)でアイキャッチ画像を出力する際に拡大表示する画像へのリンクにクラス(以下の例では .lumi-solo)を指定します。

以下は投稿の個別ページで、挿入されたアイキャッチ画像があればライトボックスを適用する例です。

single.php の例(アイキャッチ画像の出力部分の抜粋)
<?php if(have_posts()) : ?>
<?php while(have_posts()) : the_post(); ?>

  ・・・中略・・・

  <?php if(has_post_thumbnail()) : ?>
  <?php
  $post_thumbnail_id = get_post_thumbnail_id();
  $my_thumbnail = get_post( $post_thumbnail_id );
  $my_thumbnail_caption = esc_html( $my_thumbnail->post_excerpt );  //キャプション
  $src_info = wp_get_attachment_image_src( $post_thumbnail_id, 'large' );
  $width = $src_info[ 1 ]; 
  $height = $src_info[ 2 ];
  ?>
  <figure> 
    <!-- a 要素にライトボックス用のクラスを指定し、href に拡大画像の URL(パス)を指定 -->
    <a class="lumi-solo" href="<?php echo esc_url(get_the_post_thumbnail_url(get_the_ID(),'full')); ?>"> 
      <img src="<?php echo esc_url(get_the_post_thumbnail_url(get_the_ID(),'large')); ?>" alt="<?php echo trim( strip_tags( get_post_meta( get_post_thumbnail_id($post->ID), '_wp_attachment_image_alt', true ) ) ) ?>" width="<?php echo $width; ?>" height="<?php echo $height; ?>"> 
    </a>
    <figcaption><?php echo $my_thumbnail_caption ? $my_thumbnail_caption : '' ?></figcaption>
  </figure>
  <?php endif; ?>

  ・・・中略・・・

<?php endwhile; ?>
<?php endif; ?>

関連ページ:アイキャッチ画像の出力

投稿に挿入した全ての画像に適用

以下は投稿に挿入された画像でリンク先を「メディアファイル」に設定している全ての画像を、記事の本文中の画像へのリンクを書き換えてライトボックス表示できるようにする例です。

リンクの書き換えは preg_replace_callback() を使っています。

この方法の場合、毎回画像にクラスを指定しなくてすむのと、すでに挿入されている画像もライトボックス表示の対象にできます。また、画像のリンク先を「メディアファイル」に設定していない画像はライトボックスは適用されません。

投稿のコンテンツを出力する the_content() の代わりに以下を記述します。

<?php 
  $content = get_the_content();
  // /wp-content/uploads(アップロードした画像)へのリンクを表すパターン
  $pattern = '/(<a )((class=")([^">]*)("))?([^>]*"http(s)?:[^">]*\/wp-content\/uploads\/[^">]*"[^>]*>)/u';
  //preg_replace_callback() のコールバック関数
  function add_luminous_class($matches) {
    if ($matches[2] !== '' && $matches[3] !== '') {
      //a 要素にクラスが指定されている場合は、そのクラスに続けてライトボックス用のクラスを追加
      return $matches[1]. $matches[3] .$matches[4]. ' luminous' .$matches[5] .$matches[6];
    } else {
      //a 要素にクラスが指定されていなければ、ライトボックス用のクラス属性を追加
      return $matches[1]. ' class="luminous"' .$matches[5] .$matches[6];
    } 
  }
  $content = preg_replace_callback($pattern, 'add_luminous_class', $content);
  //the_content フィルターを適用
  $content = apply_filters('the_content',$content);
  $content = str_replace( ']]>', ']]&gt;', $content );
  echo $content;
?>

関連ページ:ループで使うテンプレートタグや関数(get_the_content)