パララックスを
極める

image: パララックスを極める
Mastering parallax

現実世界の視差をWEBで再現する

 | 2024/03/08

考え方

二次元世界にjavascriptで パースペクティブ環境を構築
  • パララックスとは…視差のこと

    パララックス効果は現実世界でも身近に経験する現象です。
    例えば列車に乗っている時、手前の景色はどんどん過ぎ去っていきますが遠くの風景ほどゆっくりと後方へ動いていきます。
    これが視差で、異なる速度で動く要素が重なり合うことで生じる奥行き感のことです。
    ウェブデザインではこの視差を利用したエフェクトをパララックス効果といいます。
    この効果は、ユーザーに動きや立体感を与え、ウェブページをより魅力的に見せるために利用されます。
    今では普通にWEBサイトで使われていますね。
    以下でこの効果を実装し開発経緯を解説します。

  • CSSとJavaScriptで再現する

    JavaScriptは要素のスクロール位置を検知し、それに応じて要素の位置やスタイルを変更することで、パララックス効果を実現します。一方、CSSは要素のスタイルやアニメーションを制御し、視覚的な表現を補完します。この組み合わせにより、滑らかで魅力的なパララックス効果を目指します。

  • 他の方法でパララックス

    視差を利用しなくてもオブジェクトのスクロール量を調整することで疑似的にパララックス効果を表現することが可能です。
    オブジェクト個別にスクロールによる移動量を変更することで見た目の視差効果を得られます。
    これはこれでシンプルな方法ですが、本プロジェクトでは現実世界の視差を利用した効果をしょうかいしとりあげます。
    また、慣性スクロールが付いてるパララックスライブラリも多いですが、これは副次的なものでパララックスとは別の効果になります。

  • パララックスの基本的なサンプル

    MDNのサンプルキューブをスクロールでperspective-origin値を変更させるサンプル。
    perspective-origin値を変更するだけでパララックス効果を表現できるサンプルです。
    このサンプルを見てわかるのは枠があるとパララックス効果は現実とは逆に感じるということです。
    実際のピクセル値は手前ほど多く、遠景ほどゆっくりなのですが、画面自体が上下するため、子要素と画面との相対距離が短い手前ほどゆっくり、相対距離が長い遠景ほど、速く動いていく様に見えるということです。
    これを現実と同じく見えるようにするには、要素の枠を”overflow: visible”で消せば問題ありません。
    パララックスの基礎をキューブで考える:https://labo.studio-happyvalley.com/parallaxImg/basic/

実装と 要点

CSSとJSでのコーディング
  • HTMLコードのポイント

    最初にパースペクティブ環境を構築します。つまり世界の構築です。
    パララックス効果を付与した要素がいわば世界で、その要素に格納された子要素が視差効果を表現するオブジェクト要素になります。
    下図ではパララックス世界の中にテキストと画像を配置しています。

    <div class="parallax">
    	<div class="textArea">テキスト</div>
    	<img class="imgArea” src="image.webp">
    </div>
  • CSSコードのポイント

    CSSではパースペクティブ環境を構築します。
    パララックス効果を付与した要素はいわば世界で、その要素に格納された子要素が視差効果を表現する要素になります。
    使用するプロパティはperspectiveとperspective-originです。
    両者は3D変換に使用されるCSSプロパティであり、要素が3D空間内でどのように見えるかを制御します。
    以下に、それぞれのプロパティの違いを分かりやすく説明します。

  • perspective:

    perspectiveプロパティは、視点から見た3D空間の遠近法(遠近効果)を定義します。
    要約すると視点からの距離を決定します。
    このプロパティは、親要素に適用されると、その親要素内のすべての子要素が3D変換を受ける際の視点として機能します。
    値は、視点からの距離を表し、その距離が短いほど、3D変換の効果が強くなり、要素がより大きく見えます。

  • perspective-origin:

    perspective-originプロパティは、3D変換の視点(視線の始点)を指定します。
    つまり視点の位置を決定するプロパティです。
    このプロパティは、perspectiveプロパティと組み合わせて使用されることが一般的で、視点がどこにあるかを指定します。
    値は、X軸とY軸の位置を指定し、要素が3D変換される際の視点の位置を定義します。

  • 実際のCSSコーディングは

    パララックス効果を付与したい親要素に次のスタイルを設定します。

    parallax {
     perspective: 3000px;/* 自由に設定 */
     perspective-origin: center 0;/* 重要、視差の基点となる。水平方向の視差の場合、右側の数値が天地方向の位置 */
     transform-style: preserve-3d;
    }
  • 過ぎ去る速さは現実とは逆に見える

    また、パララックス効果を付けたい子要素には視点からの奥行をtranslateのZ軸で指定します。
    このサンプルは画面が上下移動するため、現実とは逆にZ値が長い(遠く)ほど早く動き、Z値が短い(近い)ほどゆっくり過ぎ去るように見えます。

    .near{/*近い要素*/
      transform: translate3d(0px, 0px, -200px);
    }
    .far{/*遠い要素*/
      transform: translate3d(0px, 0px, -1000px);
    }
    
  • Javascriptコードのポイント

    JavaScriptは親要素のスクロール位置を検知し、それに応じてperspective-origin値を変更することで、パララックス効果を実現します。
    サンプルでは、パララックス効果を付けたい要素が表示されるだいたいの範囲をスクロールする距離とします。
    その場合パララックス効果要素の下端を0%、上端を100%と考えることができます。
    つまり、スクロール値が要素の天地いっぱいに達した時100%になるような式を作ればよいことになります。
    次がそのコードです。

    /* 
     * #parallax: パララックス効果を適用する要素
     * #container: スクロールさせたいおおよその距離を内包する要素
     * #containerの下段にスクロールが達した時、perspective-origin値が約100%になります。
     */
    const el= document.querySelector('#parallax');
    const reEl= el.getBoundingClientRect();
    const container= document.querySelector('#container');
    const reContainer= container.getBoundingClientRect();
    const dif= reContainer.height - reEl.bottom;
    
    window.addEventListener('scroll', (e) => {
    		const pscrollY= parseInt( (window.scrollY*100/dif));
    		el.style.perspectiveOrigin = `center ${pscrollY}%`;
    }, true);
    

今後の 課題

問題と課題
  • 世界の構築がかなり面倒

    パララックス世界の子要素に個別にZ値を設定すると現実世界と同じように遠くにあるようになるため実際より小さくなります。
    これを最初のデザイン案と同様の大きさや位置になるように調整するのがかなり面倒です。
    これはそのうちプログラム化しようと思います。

  • スクロールの速さの調整がポイント

    ブラウザの仕様上スクロールのスピードはほぼ決まっているため、何もしないとかなり早くパララックス効果が上へ隠れてしまいます。
    それをもっと長く表示するためには、スクロールのスピードを意図的に遅くなどが必要です。
    このページのサンプルはスクロール値は変更してません。
    また、パララックス効果を設定した要素を”overflow: hidden”で囲うと、画面が最も早く移動するため、近いほどゆっくり、遠いほど早く感じます。
    これを現実と同じようにするには、’overflow: visible’で枠を消す必要があります。

  • 他の課題

    他にもスマホの場合、横より縦が長いため新たにパララックスの世界を構築し直す必要があります。
    以下はちょっと複雑なサンプル。
    浮遊する部屋:https://labo.studio-happyvalley.com/parallaxImg/real/

『パララックスを極める』関連のお薦め

このページで紹介しているプログラムやビジュアルなどご依頼いただければ実装を賜ります。
お問い合わせはこちら