Webデザインやインタラクションの設計において、スクロールに応じてマスクや要素のサイズを動的に変化させる手法は、視覚的なインパクトを高めるだけでなく、ユーザーエクスペリエンスの向上にも貢献します。本記事では、スクロールに応じたサイズ変更の実装方法を紹介します。
1. CSSとJavaScriptを使った基本的な実装
HTMLの基本構造
<div class="mask_area">
<div class="mask"></div>
<div class="scaling-element"></div>
</div>
CSS
.mask_area {
margin: 0;
height: 300px;
background: linear-gradient(to bottom, #fff, #ccc);
overflow: hidden;
}
.mask {
width: 100%;
height: 300px;
overflow: hidden;
position: relative;
background: #333;
transition: height 0.3s ease;
}
.scaling-element {
width: 100px;
height: 100px;
background: red;
margin: 50px auto;
transform: scale(1);
transition: transform 0.3s ease;
}
</style>
Javascript
<script>
window.addEventListener("scroll", function() {
const scrollY = window.scrollY;
const mask = document.querySelector(".mask");
const newHeight = Math.max(100, 300 - scrollY * 0.5); // 最小サイズを100pxに制限
mask.style.height = `${newHeight}px`;
const element = document.querySelector(".scaling-element");
const scale = Math.max(0.5, 1 - scrollY * 0.001); // 最小スケールを0.5に制限
element.style.transform = `scale(${scale})`;
});
</script>
2. Intersection Observerを活用したパフォーマンス向上
Intersection Observerとは?
Intersection Observer
は、指定した要素がビューポート内に入ったかどうかを検知するAPIです。従来の scroll
イベントを利用した方法と比べて、パフォーマンスの向上や不要なイベント処理の削減が可能になります。
メリット:
- スクロールイベントの連続処理を減らせるため、パフォーマンスが向上
- 画面内に入った要素のみ処理できる
- ビューポート外の要素に対して不要な計算を回避できる
JavaScriptの実装
const target = document.querySelector(".mask");
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const scrollY = window.scrollY;
const newHeight = Math.max(100, 300 - scrollY * 0.5);
entry.target.style.height = `${newHeight}px`;
}
});
});
observer.observe(target);
スクロール要素とマスクサイズの設定
1. window.scrollY
を使用したスクロール量の取得
const scrollY = window.scrollY;
window.scrollY
を使って現在のスクロール位置を取得しています。
2. マスクサイズの変更
const newHeight = Math.max(100, 300 - scrollY * 0.5); // 最小サイズを100pxに制限
mask.style.height = `${newHeight}px`;
scrollY * 0.5
でスクロール量に応じてmask
の高さを減少させています。Math.max(100, ...)
で最小値を100pxに制限。
3. 要素のスケール変更
const scale = Math.max(0.5, 1 - scrollY * 0.001); // 最小スケールを0.5に制限
element.style.transform = `scale(${scale})`;
scrollY * 0.001
によってscale()
を徐々に小さくしています。Math.max(0.5, ...)
で最小値を0.5
に制限。
4. Intersection Observer による制御
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const scrollY = window.scrollY;
const newHeight = Math.max(100, 300 - scrollY * 0.5);
entry.target.style.height = `${newHeight}px`;
}
});
});
observer.observe(target);
.mask
要素が画面に表示されているときのみ高さを変更することで、パフォーマンスを向上。
このように、スクロールの値 (scrollY
) を取得し、計算を適用することでサイズやスケールを動的に変更しています。調整したい場合は、scrollY
にかける係数 (0.5
や 0.001
) を変えると動きが変わります!
まとめ
スクロールに応じたマスクサイズや要素サイズの変更は、インタラクティブなデザインにおいて非常に有効なテクニックです。CSSの transform
を活用したスケール変更や、 Intersection Observer
を使った最適化を取り入れることで、スムーズなアニメーションを実現しつつ、パフォーマンスを維持することができます。ぜひ、プロジェクトに活用してみてください!