要素をランダムに配置するメモ JavaScript
概要
jQuery jRumbleを使用した際に、合わせて試してみたJavaScriptになります。
個人的に試してみたところ意外にも気に入られました。
使用したコード
<script> document.addEventListener("DOMContentLoaded", () => { // すべてのセクションとデコレーション要素を取得 const sections = document.querySelectorAll("section"); const decorations = document.querySelectorAll(".decoration"); // セクション内のランダムな位置を計算する関数 const getRandomPosition = (section) => { const sectionRect = section.getBoundingClientRect(); const decorationSize = 100; const minX = -4; const maxX = 104; const minY = -4; const maxY = 104; // ランダムな位置をパーセントで計算 const xPercent = Math.random() * (maxX - minX) + minX; const yPercent = Math.random() * (maxY - minY) + minY; // セクション内の実際のピクセル位置を計算 const x = (sectionRect.width * xPercent) / 100 - decorationSize / 2; const y = (sectionRect.height * yPercent) / 100 - decorationSize / 2; return { x, y, xPercent, yPercent }; }; // デコレーションをセクション内の指定された位置に配置する関数 const placeDecoration = (decoration, section) => { const { xPercent, yPercent } = getRandomPosition(section); // デコレーションのスタイルを設定(位置と表示) decoration.style.left = `${xPercent}%`; decoration.style.top = `${yPercent}%`; decoration.classList.add("visible"); // セクションの種類に応じてデコレーションのスタイルを変更 if (section.classList.contains("top-cast") || section.classList.contains("top-staff")) { decoration.classList.add("white-decoration"); } else { decoration.classList.remove("white-decoration"); } console.log(`Placed decoration in ${section.className} at (${xPercent}%, ${yPercent}%)`); }; // Intersection Observer の初期化 const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { const section = entry.target; const decorationCount = parseInt(section.getAttribute("data-decoration-count"), 10); // デコレーションを配列から選択してセクションに追加 const sectionDecorations = Array.from(decorations).splice(0, decorationCount); sectionDecorations.forEach((decoration) => { placeDecoration(decoration, section); section.appendChild(decoration); }); } }); }, { threshold: 0, rootMargin: "100px" } // オブザーバーが発火するタイミングを調整 ); // 各セクションにデコレーション数を設定し、オブザーバーに追加 sections.forEach((section, index) => { const decorationCounts = [3, 1, 0, 2, 0, 0, 4, 2]; // 各セクションのデコレーション数を設定 section.setAttribute("data-decoration-count", decorationCounts[index]); observer.observe(section); // セクションをオブザーバーに渡す }); }); </script>
各部分の説明
- DOMContentLoaded イベントリスナー:
- DOM の読み込みが完了したタイミングでコードを実行します。これにより、セクションやデコレーション要素が正しく取得されます。
getRandomPosition
関数:- 各セクション内で、デコレーションがランダムな位置に配置されるように座標を計算します。
- セクション内に収まるように適切なパーセント範囲(
minX
からmaxX
)でランダムな位置を計算します。
placeDecoration
関数:getRandomPosition
で計算された位置にデコレーション要素を配置します。- また、セクションの特定のクラスに応じて、デコレーションのスタイルを変更するロジックも含んでいます。
- Intersection Observer:
- ページ内のセクションが画面内に入ったときにデコレーションを配置します。
- これにより、スクロールに応じて動的にエフェクトが適用され、パフォーマンスの向上も図れます。
- デコレーション数の設定:
data-decoration-count
属性を各セクションに設定し、それぞれのセクションに何個のデコレーションを表示するか決めています。