CSS / animation

プロンプター(Prompter)を作る

─ Guide to page sections ─

プロンプター(Prompter)というものがある。壇上に上がり、演説やライブ演奏をするときのカンニングペーパーなるものだ。行動を起こすとき、プチッとクリックすると文字がロールアップするような、例えば映画のエンドロールのようなものが画面に流れればと思う。

プロンプター完成版
ロールアップして文字が流れるプロンプターを模索する

First

プロンプター(Prompter)に求める機能

作り出す前に、要件を整理してみよう。プロンプター(Prompter)を使う状況は、ギターを弾きながら歌詞を参照する、というシンプルなものだ。場所はライブステージになるかもしれない。

  • ポチッとやって動作を開始したい…こちらのタイミングで開始する
  • 文字の表示形式についてはこの段階では問わない…候補としてあるのはが下方から上方へロールアップして表示
  • そのスピードをコントロールしたい…他の曲でも対応できるようにしたい
  • 途中で動作をキャンセルしたい…流れ出した文字列をキャンセルしたり、先頭に戻す処理が必要
  • 途中で先送りしたい…動作の途中においても先送りできる
  • 変則的な曲の流れにも対応したい…長い間奏にも対応する
  • スクロールバーを非表示にする
  • レスポンシブに対応したい

Second

基本機能を付加する

まず、プロンプターを実現させるために文字がロールアップする部分に取り掛かる

本番と比べて初動を確認するためだけのモデルなので移動距離は短く、文字数も少なく詳細は省略している。

下がその html の構文であり、全てを CSS で動かす。タップ(クリック)でアニメーション(transition)を開始するには、「:checked」を利用する。

文字列をロールアップさせる仕組み
CSS transition を使ったアニメーション
<div id="wrapper-credits">
  <input type="checkbox" id="trigger">
  <label for="trigger">
    <p class="sentence roll-up" ><span class="credits-title">“ Have you ever seen the rain? ”</span><br>
    Someone told me long ago<br>there's a calm before the storm
    </p>
  </label>
</div>
#wrapper-credits {
  position: relative;
  margin: 0 auto;
  padding: 0;
  width: 100%;
  font-family: 'Noto Sans JP', sans-serif;
  font-size: 26px;
  font-weight: 100;
  line-height: 1.8;
}
label {
  display: block;
  ackground-color: #FF8C00;
  color: #fff;
  width: 100%;
  height: 2100px;
  margin: 0 auto;
  padding: 0;
  position: absolute;
  color: #fff;
  top: 20px;
  left: 0;
  text-align: center;
}
#credits{
  height: 100%;
  margin: 0 auto;
  padding: 0;
  position: absolute;
  color: #fff;
  top: 20px;
  left: 0;
  text-align: center;
  width: 100%;
}
.sentence {
  position: relative;
  padding: 1em;
  background: #FF8C00;
  transition: all 5000ms linear; /* 1秒=1000ms */
}
#trigger:checked ~ label .roll-up {
  transform: translate(0,-210px);
}

transform: translate();」で移動の距離を定義して、「transition」で文字列をゆっくりとロールアップさせる動きをコントロールする。


Third

実用的であるかを確認する

実用で使えるかどうかを確認するのに一番時間を費やした。

youtube の「Creedence Clearwater Revival - Have You Ever Seen The Rain (Official)」を流しながら挙動を確認した。この曲はシンプルで定型的な構成である。

幸運にもセクションセカンドの内容がスムーズに結果を生みそうなので、他の方法論にも着手してみた。

slick.js の場合

簡単にスライダーで実現できればと思って、slick.js を使ったプロンプターを作ってみて動作を確認した。

僅かだがスライダーの切り替わるタイミングが合わないと、プロンプターは機能しなくなる。歌詞はスムーズに順番通りに流れるが、歌詞が切り替わるタイミングで少しの差異が発生した。この差異は微調整する方法はない。

slick.js で文字列をスライドさせる仕組み
文字列をスライドさせる仕組み

飛躍した引用になるが、物理学にブロックユニバース理論というものがある。過去・現在・未来が全て一塊のブロックとして存在するという理論(時間は存在しない)であり、過去・現在・未来が全て同時に存在するというものだ。

この関係性を上手く活かせれば、特定のフレーズにおいて歌詞が少しだけ早く流れようとも、少しだけ遅く流れてしまっても、問題は発生しない。

過去・現在・未来の同時表示パネルの場合

このスライドでは解決できそにもないので、解決策としてこういう過去・現在・未来の同時表示パネルを作ってみた

これは TweenMax.js を利用したもので、高性能で人気が高い。

過去・現在・未来の同時表示パネル
過去・現在・未来の同時表示パネル

ここまで他の方法論で問題になる部分の検証を行ったが、セクションセカンドの方法論は解決策を含有している。解決策として講じた過去・現在・未来のパネルも悪くはないが、手間数を考慮して予定通りセクションセカンドの方法論で進めることとなった。


Fourth

プロンプトの最終チェック

最終チェック

  • ポチッとやって動作を開始したい…アニメーション(transition)を開始するには、「:checked」をタップ(クリック)する
  • 文字の表示形式について…下方から上方へロールアップする「過去・現在・未来」を表示
  • そのスピードをコントロールしたい…「transition: all 130000ms linear; /* 1秒=1000ms */」を設定する
  • 途中で動作をキャンセルしたい…画面をタップ(クリック)する、先頭へ戻すには再起動
  • 途中で先送りしたい…下方へスクロールが可能
  • 変則的な曲の流れにも対応したい…間奏は空白で対応する
  • スクロールバーを非表示にする…body::-webkit-scrollbar{display:none; }
  • レスポンシブに対応したい…対応済み
プロンプター完成版
CSS で作ったプロンプター完成版

Fifth

scroll-driven animations

前回、紹介したばかりのスクロールをトリガーにしたアニメーションの構築方法が大きく変わりそうである。

これまで、JavaScriptなどを駆使してスクロールアニメーションを作っていたが、今後は、CSSだけで、簡単に作れるようになるらしい。

Scroll-driven Animations は、Working Draft の API(Application Programming Interface) であり、Chrome や Edge などの Chromium ベースのブラウザーでサポートされている。

そこで、Bram.us のウェブを参考にして、「scroll-driven animations」の実際の挙動を確認することにした。尚、下のボタンは参考にしたページに関連したものや、それに伴ってリリースされた新機能の CSS の注釈である。

尚、scroll-driven animations は、このセクションで収まりきれる内容ではないため、次回のページにて詳しく展開することにしよう。

関連ページ:Scroll-driven Animations

関連ページ:CSSだけでスクロールに合わせたアニメーションがつくるscroll-driven animationsを触ってみた。(Qiita)