- 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);