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)",
});
});
});