imgをbackgroundに置き換えてフル画面スライドショー

フル画面のスライドショーを自分のブログに実装してみました。これまでのブログ投稿からお気に入りの写真をピックアップしたスライドショーです。

imgのsrcをbackgroundのurlに置き換える

画像をフル画面表示するには、画像を背景にすることでccsのbackground-size:coverが使えるので便利、アスペクト比を維持して親要素の縦横の長い方に合わせてくれて、レスポンシブにも対応できます。

DrupalのViewsのフィルタで選択した画像フィールドの画像を抽出するとだいたいこんな感じのHTMLができあがります。Drupalでなくても応用の効く方法かと思われ、その辺は構造を置き換えてみてください。

<div class="view-slideshow">
  <div class="views-row"><div class="views-field-field-image"><img src="url-1"></div></div>
  <div class="views-row"><div class="views-field-field-image"><img src="url-2"></div></div>
  <div class="views-row"><div class="views-field-field-image"><img src="url-3"></div></div>
</div>

DrupalのViewsのフィールド値のリライトではstyle属性の設定はできないように設計されているので、画像のsrcを親要素.views-rowの背景にする簡単なjQueryのスクリプトを書いてみました。

$(".view-slideshow .views-row").each(function(){
   var bgUrl = $(".views-field-field-image img", this).attr("src");
   $(this).css("background-image", "url(" + bgUrl +")"); 
   $(".views-field-field-image img", this).hide();
});

cycle2に組み込む

今まで実に様々なスライドショーのスクリプトを試してきたのですが、自分はここ2、3年くらいはCycle2一本です。自分の書いたスクリプトや他の配布スクリプトとコンフリクトを起こしたりすることが少なく動作も軽快、サムネイルでの画像の切替、カルーセル式の横回転、スマホでのフリック操作等、必要な機能が揃っていて、実装も簡単です。スライドとなる要素は画像に限らずDOMで指定できます。

$(".view-slideshow").addClass("cycle-slideshow");
$(".view-slideshow.cycle-slideshow").attr("data-cycle-slides",".views-row");

これだけでCycle2の基本が実装できます。スライドを囲む親要素にcycle-slideshowのクラス属性を設定して、Cycle2のスクリプトを呼び出してきます。data-cycle-slidesでスライド要素を指定します。これにattrのチェーンで属性をどんどん追加して、様々なアクションを追加したり、ページャーを追加したり、思うがままです。

.view-slideshow{position:fixed;top:0;width:100%;z-index:-1; }
.view-slideshow .views-row{width:100%;height:100vh;background-size:cover;background-position:center;}

cssです。スライドを囲む親要素はposition:fixedで固定、フル画面なのでスライドショーに重ねてユーザーインターフェースを置くことになるので、z-indexは必須です。

スライド要素のheight:100vhのvhはcssの新しい単位でview-portに対して100vhが画面の高さになります。background-size:coverで背景画像のアスペクト比を維持したままで領域いっぱいに描画、background-position:centerで背景画像を中央寄せにします。

画像の抽出

自分のブログでは個々のコンテンツに30~50くらいの画像を組み込んでいます。コンテンツ単位で抽出するのはタグ付けとかで簡単にできますが、コンテンツに組み込まれたフィールド値である画像だけを抽出するとなると、ここはDrupalの出番です。

Field collectionモジュールでフィールドを構造化して、チェックボックスを付ける方法とかも考えてみたのですが、既存コンテンツの既存フィールドをそのまま利用したいので、シンプルに画像のタイトル属性を使うことにしました。

お気に入り画像のタイトル属性に★を入力して抽出しています。機種依存文字じゃない記号なら何でも構わないのですが、文字にするとタイトル要素の意味のある内容にならないように記号にしています。DrupalのViewsのContextual filterで画像のタイトル属性を呼び出し、画像のタイトル要素に★が含まれるフィールドを抽出するようにフィルタを設定します。この辺りの設計のしやすさはDrupalならではじゃないかと思います。

レスポンシブ対応なので、このままスマホでも画像はフル画面で表示されますが、例えば写真の左右の端にメインとなる部分が写っている写真とかはスマホではかなりブサイクになってしまいます。ネイティブアプリじゃなく横向きを強制することはできないので、パソコン用とスマホ用でスライドショー自体を切り替えることにしました。パソコンとスマホで共用できる画像はタイトル属性に★、パソコンだけに出力する画像は★★、スマホだけに出力する画像(例えば縦長の画像)は★★★に分け、パソコン用とスマホ用の2種類のスライドショーを出力し、user agentで切り替えています。

このため厳密にはレスポンシブデザインとは言えなくなりましたが、自宅では23.5インチの大画面、電車の中やカフェとかでiPhone6 plusの小さな画面、どっちでもバッチリ楽しめるようになり、一人悦に入っています。ちなみにスマホでは自動的スライドさせないで、フリック操作で切り替えるようにしています。