
画像にマスク効果を施し、マスクの形や位置をアニメーションで動かすことで作成します。
基本のHTMLとCSS
まず、画像にアイリスアウトのアニメーションを適用するための基本的なHTMLとCSSを準備します。
<div class="mask"> <img src="your-image.jpg" alt="masked image"> <div class="message">とほほ・・・<br>もうこりごりなのだ</div> </div>
.mask { background-color: black; overflow: hidden; position: relative; } .mask img { width: 100%; height: 100%; object-fit: cover; --x: 72%; --y: 55%; --inner-radius: 800px; --outer-radius: 810px; mask-image: radial-gradient( circle at var(--x) var(--y), black var(--inner-radius), transparent var(--outer-radius) ); -webkit-mask-image: radial-gradient( circle at var(--x) var(--y), black var(--inner-radius), transparent var(--outer-radius) ); } .message { position: absolute; top: 30%; left: 72%; transform: translate(-50%, -50%); font-size: 24px; color: white; display: none; /* 初期状態では非表示 */ } /*media Queries スマホサイズ(599px)以下で適応したいCSS - スマホのみ ---------------------------------------------------------------------------------------------------*/ @media print, screen and (max-width: 599px) { .message { font-size: 12px; }
ここでは、最初に画像に円形のマスクを設定しています。
--inner-radius と --outer-radius を使って、マスクのサイズを変更できるようにしています。
スクロールでアイリスアウトを開始
次に、スクロールして画像がビューポート内に現れたタイミングで、アイリスアウトアニメーションを開始する方法を紹介します。
document.addEventListener('DOMContentLoaded', () => { const img = document.querySelector('.mask img'); const message = document.querySelector('.message'); let radius = 100; let decayFactor = 0.99; // Intersection Observerを使ってスクロールで要素がビューポート内に現れるタイミングを検出 const observer = new IntersectionObserver(entries => { entries.forEach(entry => { if (entry.isIntersecting) { // 画像がビューポートに完全に表示されたタイミングでアニメーション開始 animate(); observer.disconnect(); // アニメーション開始後、監視を停止 } }); }, { threshold: 1.0 }); // 1.0 は要素が100%表示されたとき // 画像がビューポートに現れたらアニメーションを開始するよう監視 observer.observe(img); function animate() { function step() { radius = radius * decayFactor; if (radius <= 10) { radius = 10; message.style.display = 'block'; // 円が縮んだらメッセージを表示 } img.style.setProperty('--inner-radius', `${radius}%`); img.style.setProperty('--outer-radius', `${radius + 1}%`); decayFactor *= 0.999; // 減少速度を遅くする requestAnimationFrame(step); } step(); } });
コードの解説
アイリスアウト効果の実現:
画像のマスクに使用する mask-image に radial-gradient を使い、円形の透明部分と黒部分で画像を切り取ります。--inner-radius と --outer-radius を使って、この円の半径を動的に変更し、アイリスアウトのアニメーションを実現しています。
Intersection Observer API:
IntersectionObserver を使って、画像がビューポートに現れたタイミングでアニメーションを開始します。threshold: 1.0 は要素が完全にビューポート内に入った時にアニメーションがトリガーされるようにしています。
animate() 関数:
radius を減少させていくことで、画像の中央部分から外側に向かってフェードアウトしていくエフェクトが実現されます。requestAnimationFrame を使用して、スムーズなアニメーションを作り出します。
減少速度の調整:
decayFactor の値を使って、アニメーションの減少速度を徐々に遅くすることができます。これにより、最初は速く、最後は遅くなるような自然な動きを作り出します。
まとめ
スクロールによって画像にアイリスアウトのアニメーションを適用する方法をご紹介しました。
Intersection Observer APIを使うことで、スクロールのタイミングでアニメーションを開始し、視覚的に魅力的な効果を実現できます。
この方法を使えば、ウェブサイトのインタラクションをよりダイナミックにすることができます。