こんにちは、コーダーのばやしです。
突然ですが、バックグラウンドで音楽を再生しつつ、ページ遷移を行っても再生が途切れないようにしたい時ってありますよね。(←そんな無いと思うよ。イロコト代表穂刈より。)
CookieやSessionStorageに再生位置を保存させて、遷移後に同じ所から再生ということも可能ですが、ページ遷移の際に処理が止まるためどうしても音声は途切れてしまいシームレスとは言えません。
また、近年自動再生系への締付けがきつく(特にiOS)、ユーザーによる操作を挟まないと再生すらさせてもらえないので通常であれば表題のような実装は困難です。
そのような場合に役に立つのが、非同期ページ遷移です。
目次
一般的に非同期ページ遷移というと、AjaxとpushState(History API)を活用してシームレスにページ遷移を行う、所謂Pjaxによる一連の実装の事を指す事が多いかと思いますが、本項もPjaxをベースにした話になります。
jquery-pjaxなど様々ありますが、今回はBarba.jsを利用します。
古いバージョンと最新バージョン(v2)とで記述方法が変わるのでネットで情報を探す際は気をつけてください。(個人的に、コード上でBarbaと書かれている方が旧版、barbaとなっている方がv2という認識でいます。断言はしません。)本項ではv2を利用します。
音声処理系において定番のライブラリであるHowler.jsを利用します。
各ブラウザごとの面倒な調整などもまとめて行ってくれるので、ただ音を流すだけであればかなり簡単に実装できます。
下記の公式サイトの下部のUsed byに錚々たる面子が列挙されている通り、ワールドワイドで多く使われているので情報も多いです。より詳細な情報を探ろうとすると殆ど英語になりますが、Google先生やDeepL先生に活躍していただけば特に問題はないです。
※音声が流れますのでご注意ください。
※再生されない場合はページ内でタップまたはクリックをしてみてください。
使用楽曲:"Ethiopia Rag" (1909), by Joseph F. Lamb (Wikimedia)
Barba.jsとHowler.jsの各ライブラリの詳細な使い方は巷に溢れていますので、表題のような実装をする際の考え方と簡単なデモコードを紹介していきます。
非同期遷移実装がなされていない通常のページで音声を再生した場合、ページ遷移によってJSの処理が閉じるため当然音声再生も止まってしまいます。
Barba.jsで非同期遷移する場合、現在表示されているページの指定した領域内を遷移先のページのものに差し替えます。
JSによって遷移先のページの情報を取得して差し替えを行うため通常のページ遷移は発生せず、最初に表示したページで実行した音声再生の処理がそのまま継続され、音声を再生し続けてくれます。
Wikimediaにある適当な音源を再生してみます。
const music = new Howl({
src: 'https://upload.wikimedia.org/wikipedia/commons/b/b8/%22Ethiopia_Rag%22_%281909%29%2C_by_Joseph_F._Lamb.mp3',
autoplay: true,
volume: 0.5,
loop: true,
});
music.play();
autoplay: true 自動再生を試みることができます。 volume: 0.5 ボリュームを0〜1で設定できます。 loop: true 指定することでループ再生が出来ます。 近年のブラウザにおいては自動再生が出来ない事が多く、ユーザーの何らかのアクションが求められるため、基本的には「再生ボタンを押したら再生される」という形を推奨します。
今回は3ページ間を非同期遷移するように設定します。
<body data-barba="wrapper">
<div class="menu">
<ul>
<li><a href="./index.html">PAGE01</a></li>
<li><a href="./index_02.html">PAGE02</a></li>
<li><a href="./index_03.html">PAGE03</a></li>
</ul>
</div>
<!-- ここから切り替える内容 -->
<main data-barba="container" data-barba-namespace="home">
<div class="body body-01">
<p>これはPAGE01です。</p>
</div>
</main>
<!-- ここまで切り替える内容 -->
<!-- JS読み込み -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.2.3/howler.min.js"
integrity="sha512-6+YN/9o9BWrk6wSfGxQGpt3EUK6XeHi6yeHV+TYD2GR0Sj/cggRpXr1BrAQf0as6XslxomMUxXp2vIl+fv0QRA=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@barba/core"></script>
<script src="./assets/base.js"></script>
</body>
data-barba="wrapper"
bodyなどラッパー要素に指定します。
data-barba="container"
切り替わる要素に指定します。
data-barba-namespace="home"
各ページで処理を分けたい場合などに、こちらで定義します。無くても動きます。
HTML側で上記の属性を各ページに設定の上、下記のようにbarba.init();を実行すると、それだけで非同期で遷移するようになります。data-barba="container"が指定されている要素を非同期で差し替えるという動きになります。
barba.init({
transitions: [{
leave(data) {
return gsap.to(data.current.container, {
x:"100%"
});
},
enter(data) {
gsap.from(data.next.container, {
x: "-100%"
});
}
}]
});
※アニメーションはGSAPを使っています。
注意点として、titleタグは遷移後のページのものに自動で差し替わりますが、descriptionなど他のメタタグは差し替わらないので、差し替えるコードを書く必要があります。
GoogleAnalyticsでアクセス解析をしている場合も調整が必要です。
GoogleAnalyticsにおいては基本的にはページビューを判定してアクセス計測をしていますが、Barba.jsを用いて非同期遷移にするとページビューが発生するのは初期読み込み時とリロード時のみで、正しく計測されません。GA/GTM側で、履歴の更新で判定する方式を追加する必要があります。
また、タイトルが1つズレて計測されるというパターンもありました。GTM側に情報を送るタイミングがBarba.jsによりtitleタグが書き換えられる前になってしまっている影響で1つ前のタイトルが計測されるというもので、情報送信タイミングをずらすことで対応可能です。
そうして出来上がったものが下記になります。
リンクを押してページを移動しても音楽が途切れないことが分かるかと思います。
※音声が流れますのでご注意ください。
※再生されない場合はページ内でタップまたはクリックをしてみてください。
今回は主に音楽をシームレスで再生することに焦点を合わせましたが、音声ではなく背景で動画を再生させそれを途切れさせないようにするなど様々な活用方法がありそうです。弊社のフィールドですと、特にアニメやゲームサイトの世界観を表現するための表現に有用と思います。
主にJS周りの調整で工数が通常より多くかかってしまいますが、初見時の効果は大きいと思いますので、表現方法の一手としてレパートリーに加えたいですね。
お読みいただきありがとうございました。
それではまた。
ばやし
WEBコーダー。お絵かきと音ゲーと写真撮影(旅行)が趣味。 最近はAIに脳を破壊されています。