← 一覧へ

mediaLoader / CLoading

ページ内の <img> / <video>(+任意の非同期処理)の読み込みを監視し、進捗(0〜100%)と完了フラグを提供する。
使い方は2通り。
関数版 mediaLoader() は進捗の受け取り方(onProgress/onComplete/promise)や対象スコープを細かく制御できる低レベルAPI。
コンポーネント版 <CLoading> はその mediaLoader をエンジンに、全画面ローディング(プリローダー)のマークアップ・初期化・フェードアウトまで内包した、ページ先頭に置くだけのドロップイン。
どちらも失敗を進捗に算入し必ず完了に到達し、tasks(canvas 初期化など)を同じ進捗に合流できる。

mediaLoader Options

Option Type Default Description
target Document | Element document 走査スコープ。特定セクション内だけを対象にしたい場合に要素を渡す
images boolean true <img> を監視対象に含めるか
videos boolean true <video> を監視対象に含めるか
selector string 未指定 指定時はこのセレクタで対象を集める(images/videos より優先)
videoEvent 'loadeddata' | 'canplay' | 'canplaythrough' 'loadeddata' 動画を「読み込み完了」とみなす基準。既定は先頭フレーム表示可(loadeddata)
forceVideoLoad boolean false 未読み込みの <video> に load() を呼び読み込みを促す(preload="none"/metadata 対策。再生中は先頭に戻る)
tasks (Promise | (() => Promise))[] [] メディア以外に待つ非同期処理(canvas初期化など)。均等1ユニットとして進捗に算入し、全完了までゲートする。解決/拒否とも完了扱い
timeout number 未指定 ms。経過後は未完了ユニット(メディア・tasks)を完了扱いにしてハングを防ぐ
onProgress (percent, detail) => void 未指定 進捗コールバック。percent は 0〜100、detail は { loaded, total, element, type }
onComplete (detail) => void 未指定 全完了コールバック。detail は { loaded, total }

mediaLoader(関数)

低レベルAPI。「読み込みを開始」を押すと、キャッシュを回避して画像・動画を取得し直し、擬似 canvas 初期化(約1.2秒)も待機して、進捗バー・パーセンテージ・完了フラグの変化を確認できる。

進捗・パーセンテージ・完了フラグ(tasks 合流)

mediaLoader をギャラリー要素をスコープにして実行し、tasks に擬似 canvas 初期化を渡している。onProgress で進捗バーとパーセンテージ(total にタスク分が加算される)を、onComplete で完了フラグ(バッジ)を更新している。

0% (0/0) 未完了
コードを見る
import { mediaLoader } from 'form-snippets';

const loader = mediaLoader({
target: gallery,
timeout: 10000,
// canvas 初期化などの非同期処理も同じ進捗に合流させる
tasks: [() => new Promise((resolve) => setTimeout(resolve, 1200))],
onProgress: (percent, { loaded, total }) => {
bar.style.width = percent + '%';
label.textContent = percent + '% (' + loaded + '/' + total + ')';
},
onComplete: () => {
badge.textContent = '完了';
badge.classList.add('is-complete');
},
});

// await loader.promise; で完了を待つこともできる

CLoading Props

Prop Type Default Description
min number 0 最低表示時間(ms)。読み込みが速すぎて一瞬で消えるのを防ぐ
timeout number 10000 経過後は未完了分を完了扱いにしてハングを防ぐ(mediaLoader へ委譲)
target string document 監視スコープのセレクタ。未指定ならページ全体
videoEvent 'loadeddata' | 'canplay' | 'canplaythrough' 'loadeddata' 動画を「読み込み完了」とみなす基準
forceVideoLoad boolean false 未読み込みの <video> に load() を呼び読み込みを促す
showBar / showPercent boolean true 進捗バー / パーセンテージ表示の有無
bare boolean false fixed 全画面ではなく absolute(親いっぱい)にする。body スクロールもロックしない(埋め込み・デモ用)

CLoading(コンポーネント)

mediaLoader を内包した全画面ローディング。「再生」を押すと、実際の <CLoading>(bare で枠内表示)がローディング表示 → 完了フェードアウトする流れを確認できる。

ページ先頭に置くだけ

本番はページ先頭に を置くだけで全画面ローディングになる。下のプレビューは実際の を bare(枠内)で動かしている。

0 %

コードを見る
---
import CLoading from 'form-snippets/CLoading.astro';
---

<CLoading min={800} />

canvas 初期化なども待たせる

CLoading より前に window.__C_LOADING_TASKS へ Promise / () => Promise を積むと、メディアと同じ進捗に合流し、それらの完了までローディングを継続する。

上のプレビューでも擬似 canvas 初期化タスク(約1.2秒)を積んでおり、画像・動画が出揃っても タスク完了までフェードアウトしない挙動を確認できる。

コードを見る
<script>
  // CLoading は window.__C_LOADING_TASKS を読み、メディアと同じ進捗に合流させる
  window.__C_LOADING_TASKS = [() => initCanvas()];
</script>
<CLoading min={800} timeout={10000} />