ScrollScaleについて
ScrollScaleの概要
ScrollScaleはvideoが画面中央部に来たら画面中央を中心に拡大される処理を実現するJavaScriptのプログラムです(サンプルページ)。ソースコードはこちら。
動画に重ね合わせて、キャッチコピーなどのメッセージを印象的に伝えることができます。
使い方
- JSファイルとCSSファイルを読み込みます。
<script src="js/ScrollScale.js"></script> <link rel="stylesheet" href="css/ScrollScale.css">
- 動画を表示したい位置に次のhtmlを記述します。
<div class="ScrollScale" id="id name"> <video src=""/> </div>
- JavaScriptで記述したhtmlのid名を引数にScrollScaleのインスタンスを生成します。
document.addEventListener('DOMContentLoaded',function(){ new ScrollScale("id name"); });
- メッセージを表示するには、以下のようにします。
<div class="ScrollScale" id="ScrollScale1"> <video src=""></video> <div class="contants"> <div> <h3>You can create some contants layer on the video.</h3> </div> <div> <h3>contants class</h3> <span>This is sample. This is sample. This is sample. This is sample.</span> <a href="#">Button</a> </div> </div> </div>
仕組み
JavaScript
ScrollScaleには次のクラスがあります。
- ScrollScaleクラス :class="ScrollScale"のdivタグで囲まれた部分の全体的な処理を行います。
- SSVideoクラス:videoタグの処理を行います。
- SSContantsクラス:class="contants"のdivタグで囲まれた部分の処理を行います。
- SSContantクラス:class="contants"のdivタグ内のdivタブの処理を行います。
ScrollScale使用時には、ユーザによってScrollScaleのインスタンスが生成されます。この時、このインスタンスは指定されたid名のdivタグのDOMを取り出し、インスタンス変数に格納します。同時に、このdivタグに囲まれているvideoやcontantsの子要素について、それらを扱うSSVideoやSSContantsクラスのインスタンスを生成します。
このプログラムでは、このように、DOMの木構造の要素それぞれについて対応するクラスを作成し、各要素についての処理は対応する各クラスが行うように設計しました。
ScrollScaleクラス
ScrollScaleクラスには次のメソッドがあります
- constructor:コンストラクタメソッド
- scale_size:video拡大の処理を行う
- return_size:video縮小の処理を行う
- scroll_event:画面がスクロールされた時の処理を行う
画面がスクロールされた時、このインスタンスのscroll_eventメソッドが呼び出されます。scroll_eventメソッドでは、このインスタンスに対応するScrollScaleのvideoが画面上のどこの位置に存在しているのかを確認し、画面中央よりも上の位置にあればscale_sizeメソッドを呼び出します。また、画面中央よりも下の位置にあれば、return_sizeメソッドを呼び出します。 scale_sizeメソッドは、このメソッド自身が要素の大きさを変える事はせず、子要素のvideo、contantsを扱うインスタンスのactivateメソッドを呼び出します。この子要素のactivateメソッドによって、要素の大きさが拡大されます。 return_sizeメソッドは、子要素のvideo、contantsを扱うインスタンスのdeactivateメソッドを呼び出します。この子要素のdeactivateメソッドによって、要素の大きさが縮小されます。
SSVideoクラス
SSVideoクラスには次のメソッドがあります。
- constructor:コンストラクタメソッド
- activate:videoを拡大させる処理を行う
- deactivate:videoを縮小させる処理を行う
- calculate_size:videoを画面に対してどれだけ拡大すればいいのかを計算する
activateメソッドでは、videoのcssに対して、position:sticky、z-index=-1を適用します。また、videoの再生を開始し、calculate_sizeメソッドを呼び出します。
calculate_sizeメソッドでは、videoを画面いっぱいに拡大させる処理を行います。具体的には、画面の大きさと自身の大きさの比を求め、transform:scaleを行います。
deactivateメソッドでは拡大したvideoの大きさをもとに戻します。
SSContantsクラス
SSContantsクラスには次のメソッドがあります。
- constructor:コンストラクタメソッド
- activate:contantsを表示する処理を行う
- deactivate:contantsを非表示にする処理を行う
- calculate_size:class="ScrollScale"のdivタグに対して、heightを指定する
constructorメソッドでは、class="contants"のdivタグ内に存在する子要素の処理を扱うSSContantのインスタンスを生成します。
activateメソッドが呼び出されるまでは、contantsはdisplay:noneで非表示にされています。activateメソッドでは、これを表示状態にし、さらにclass="contants"のdivタグ内に存在する要素に対してacitvateメソッドを呼び出します。また、calculate_sizeメソッドを呼び出します。
calculate_sizeメソッドでは、インスタンスが扱うclass="contants"のdivタグのheightに合わせて、class="ScrollScale"のdivタグの要素のheightを指定します(この要素のheightを変えるわけではなく、親要素のheightを変えます!子要素を扱うクラスから、親要素の要素のプロパティにアクセスするのは適切ではない気がしますが、現在はこうなっています)。なぜここで親要素のheightを指定するのかと言うと、contantsがposition:absoluteなためです。absoluteでは、親要素からこの要素のheightを取得することができず、親要素のheightを明示的に定義しなければ、親要素のheightが0になってしまいます。
deactivateメソッドでは、要素を再び非表示にします。
SSContantクラス
SSContantクラスは次のメソッドを持ちます。
- constructor:コンストラクタメソッド
- activate:要素を表示する
- deactivate:要素を非表示にする
SSContantが対応するのは、class="contants"のdivタグ内に存在する子要素1つ1つです。
activateメソッドでは、この要素がちょうど画面の中央に表示されるよう適切なpadding-topとpadding-bottomを計算し適用します。
deactivateメソッドでは、この適用したpaddinngを0にします。
CSS
CSSは次のようになります。
拡大前は、videoが画面中央の位置になるようにclass="ScrollScale"のdivタグにpaddingが指定されています。
拡大後は、videoのheightとweightがwindowの高さ・幅と同じになります。contantも同様に画面中央になるように位置が調整されます。
現状解決していない問題と課題
risizeの処理
画面の大きさが変更された場合、表示されるコンテンツの位置関係を変更後の大きさに合わせた位置に合わせ直す必要があります。このプログラムでは、画面の大きさに合わせて位置関係が変更される部分に、contantのpadding、contantのアニメーション基準点、class="ScrollScale"のdivタグのheightがあります(他にもあったかもしれません)。risize時にこれら全ての位置を定義し直す必要があります(class="ScrollScale"のdivタグのrisizeについては実装しました)。
モバイル端末の処理
モバイル端末(特にiPhoneやiPad)の場合、上にスクロールした場合、検索バーなどが表示され、画面の大きさが変化します。この際、表示されていたvideoの表示が崩れ、暴れるように移動します。原因はわかっていませんが、おそらくどこかの要素のpaddingやheightの大きさが崩れることによって、こうなってしまうのだと思います。
拡大位置の指定や、文字のアニメーションをつけるためにJavaScriptのaddEventListenerのscrollを使ったのですが、iphoneなどのモバイル端末では、scrollイベントが発生するタイミングがスクロール終了時のみのようで、挙動がおかしくなってしまいました。モバイル端末では、scroll eventを用いるアニメーションは工夫がいるようです。現在はモバイル端末では、scroll eventでの文字をアニメーションは停止されています。
デモページのデザイン
デモページのデザインを見栄えよく改善することも進めたいです。
動画ぼかしレイヤーの追加
現在動画はそのまま表示されています。文字の視認性を高めるために、動画にぼかしレイヤーを追加しようと思ったのですが、今の設計では動画とぼかしレイヤーのアニメーションの同期を取るのが難しく、実現するためには、大きく修正しなければいけないかなと思います。
感想
今回このプログラムの作成に取り組んで、全てのブラウザでしっかりと動くプログラムを作る難しさを実感しました。同じコードでも、ブラウザによってうまく動かないものがあり、手こずりました。プログラムを作成していくときは、コードを書く前に、そのコードが全てのブラウザで使用可能なものなのかどうかを調査してから実装しようと思います。