Hugo: 複数画像の比較を行うスライダーのショートコード
本ブログでは複数枚の画像比較を行うスライダーを設置している。2枚の画像比較は before and after image slider とかで検索すれば色々見つかるだろう。ところが、複数枚だとなかなか発見すること自体が難しい。これはようやく見つけたDicsというJavaScript実装をHugoで利用可能にしたときの記録である。
本ブログでは複数枚の画像比較を行うスライダーを設置している。2枚の画像比較は before and after image slider とかで検索すれば色々見つかるだろう。ところが、複数枚だとなかなか発見すること自体が難しい。これはようやく見つけたDicsというJavaScript実装をHugoで利用可能にしたときの記録である。
この『Dics』の何が良いって、バニラ実装(ネイティブJavaScript)だということだ。jQueryなどを使っていないためバージョン競合が起こりにくい。HugoのTheme側でjQueryを使っているケースなどで、競合しないことがとてもありがたい。さらに、スライダーの向きを縦にできるのも良い。スマホでの横スライドは、誤ってページ履歴を戻す/進める誤操作の原因になるのでイライラしがちである。
Hugoでの利用
先に最終的なものを見せてしまおう。
利用例
記事内での利用例は以下だ。
{{< dics >}}
  {{< dicsimg src="images/A.jpg" caption="yo" >}}
  {{< dicsimg src="images/B.jpg" caption="hey" >}}
  {{< dicsimg src="images/C.jpg" caption="hey!" >}}
{{< /dics >}}
2つのshortcode: dics と dicsimg から成り立つshortcodeということになる。これらに対応するこのようなshortcode 2種を用意することで画像比較を実現する。
実際に利用している例はこちらの記事を見ていただきたい。
shortcode実装
dics 側のL2-3で実装しているのは、Dicsが配っているJavascriptとCSSの読み込みだ。このshortcodeが呼ばれた回数を数えるカウンターである dicscount が存在しないケース(=最初の登場箇所)でのみこれらのリソースを読み込むようにしている。つまり、Dicsを利用しないページではこのリソースを読み込まない実装ということだ。
真似る場合は、リソースパスは実際のパス(通常は /static 以下)に合わせよう。
{{- if not ($.Page.Scratch.Get "dicscount") -}}
<link rel="stylesheet" href="/css/dics.min.css" />
<script src="/js/dics.min.js"></script>
{{ end }}
{{- $.Page.Scratch.Add "dicscount" 1 -}}
{{ $baseURL := .Site.BaseURL }}
<div class="dics-wrapper">
	<div class="b-dics">
		{{ .Inner }}
	</div>
</div>
dicsimg shortcodeの実装はシンプルだ。imgタグを生成するだけである。記事フォルダ内のコンテンツを読み込ませたかったので .Page.Resources を使っているのがちょっとした工夫、くらいだろうか。もし解像度の変換などを行いたければ $image を処理すれば良い。
{{- $image := (.Page.Resources.ByType "image").GetMatch (printf "**%s**" (.Get "src")) -}}
    <img src="{{ $image.RelPermalink }}"{{ with .Get "alt" | default (.Get "caption") }}alt="{{.}}"{{ end }} loading="lazy"/>
JavaScriptの組み込み
ここまで作った上で、Javascriptの発火用のコードをどこかに仕込む必要がある。 Dics を発火しないと、ただ単に画像が並んでいるだけになってしまう。
筆者の使っているThemeではjQueryを利用しているため、以下のような実装となった。 new Dics({ 以下に書かれているのはDicsのオプションなので、真似して利用する場合は設定値は自由に変えよう。
$(document).ready(function () {
  jQuery(".b-dics").each(function (i) {
    new Dics({
      container: this,
      linesOrientation: "vertical",
      textPosition: "left",
      arrayBackgroundColorText: ["#000000", "#FFFFFF"],
      arrayColorText: ["#FFFFFF", "#000000"],
      linesColor: "rgb(0,0,0)",
    });
  });
});








