検索で出てくる情報では実現できない部分もあり、てこずったのでメモとして。
実現したいこと
- Turn.jsを使用
- 最初のページを表紙1ページではなく、左右にページを表示させた見開きにしたい
- ページをクリックすることでページめくりを動作させたい
Turn.js
Turn.jsに関しては検索すれば色々でてくるので当記事では触れませんので、上記公式などを参照ください。
Turn.js自体も古いのですが、昔に使ったjQuery Bookletの代替案として探しており、最新のWP内蔵jQueryでも動いたのと、見た目をjQuery Bookletにかなり近づけられたのとで採用しました。
ただし公式のリンクが壊れていてドキュメントが見れません。幸いPDFではWEB上に残っていたので一応リンクを残しますが、ダウンロードしたファイルの中に同じものがあるのでそちらを見れば事足りると思います。
対応策
表紙を見開き状態にする
- javascript – Set the first page is double page instead of single page in turn.js? – Stack Overflow
- No “one page” front page · Issue #138 · blasten/turn.js
- How to load the book already opened? · Issue #195 · blasten/turn.js
- Start with book opened · Issue #45 · blasten/turn.js
1目のスレッドで2つ目以降のリンクが紹介されており、そこを見れば実現できます。
動作としては、初回に1ページ目を表示させず、ページめくりの動作時にも1ページ目を表示させないという処理を施します。
多少参考コードと違いますが、whenを使って以下のように記載しました。
jQuery(function($) {
$("#flipbook").turn({
page: 2,
when: {
turning: function (event, page) {
if (page == 1){
event.preventDefault();
}
},
start: function (event, pageObject) {
if (pageObject.page == 1){
event.preventDefault();
}
}
}
});
});
その上で、以下のように先頭に表示させない1ページ目用のdivを追加しています。
このdivの中身は空でよく、スペーサーのような役割を意図しています。
<!-- Turn.jsの動作対象 -->
<div id="flipbook">
<div></div><!-- ←これが表示させないスペーサー用div -->
<div>1</div><!-- ←スペーサー用divがないとこのページが表紙として配置される -->
<div>2</div><!-- ←スペーサー用divがないとこのページが最初の見開き左側に配置される -->
<div>3</div>
<div>4</div>
</div>
クリックでページをめくる
個人的な結論としては以下になります。
- Turn.jsの動作対象に指定している要素を覆うように、左右1枚づつ計2枚のdivをabsoluteで被せる
- 被せたdivにクリックイベントを設定して、左右どちらかをクリックすることで動作させる
<div class="wrap">
<div class="layer--left"></div>
<div class="layer--right"></div>
<div id="flipbook">
Turn.jsの動作対象
</div>
</div>
上記のようなHTMLを設定しCSSで.layer–leftと.layer–rightをTurn.jsの動作対象の上に被せ、以下のようなJSでページ送りを動作させます。
// 前のページへ
$(".layer--left").click(function(e){
$("flipbook").turn("previous");
});
// 次のページへ
$(".layer--right").click(function(e){
$("flipbook").turn("next");
});
デメリットはテキストなどが選択できなくなる点で、選択できることが必須であればこの手は使えません。
画像などの選択する必要がない要素が大半を占めるなら、そのサイズに合わせて上に載せるdivのサイズを変更すればデメリットのない状態で対応できます。
没案1
検索で以下のような情報が見つかりますが、見開き3ページ程度しか動作せずそれ以上のページでは無反応になります。
Turn.jsの動作対象に指定している要素を取得すればわかりますが、実際に見開き3ページ(左右1ページづつなので計6ページ程度)の要素しか取得できず、上記ページやaddEventListnerを使ってイベントを設定する方法では対応できません。
没案2
Turn.jsの動作対象の各ページ用divにonclickをつけることで動作できるのではと試したところ以下のようになり、快適とは言い難い操作感でした。
- 動作は実行される
- ただし動作後に1秒程度待たないと次のページをクリックしても動かない
結び
条件次第の上かなり無理やりな手法ではありますが、どうにか対応できたかなと思います。
追記
スマホでの閲覧がほとんど、あるいは無視できない状況ではTurn.jsのようなライブラリはかなり下火かもしれません。
今回代替案を探した際にあまり見つかりませんでした。
今後のことも考えて、調査中に見つけたライブラリをメモ的に残します。いずれも多機能といいますか、UIを見るとコンセプトから違う感じです。
以下は試しに実装してみたものの、Chromeで閲覧時に、ページをめくると一瞬画像が消えるため除外。img要素でも背景画像でも発生するため回避策を見出せませんでした。
8人がこの記事を評価
役に立ったよという方は上の「記事を評価する」ボタンをクリックしてもらえると嬉しいです。
連投防止のためにCookie使用。SNSへの投稿など他サービスとの連動は一切ありません。