Angular Lightbox

@reelkit/angular-lightbox で作られた、Angular 用のフルスクリーンの画像と動画のギャラリーです。

ライブデモを見る →

機能

画像と動画
動画スライドを標準でサポート
タッチジェスチャー
スワイプで移動
スワイプで閉じる
上にスワイプして閉じる
キーボード操作
矢印キーと Escape
フルスクリーン
ブラウザー間で動く API
トランジション
スライド、フェード、フリップ、ズームイン
先読み
隣の画像を事前に取得
サウンド切り替え
スライドごとのミュート
読み込み状態
スピナーと独自のスロット
エラー処理
エラーアイコンと独自のスロット
テンプレートスロット
カスタマイズできる 6 つのスロット領域
OnPush
Angular のシグナルと OnPush
URL の状態
共有もブックマークもできるリンク

インストール

bash
アイコン

デフォルトのコントロールはアイコンに lucide-angular を使います。別のアイコンライブラリを使いたい場合は、rkLightboxControlsrkLightboxNavigation のテンプレートスロットで独自のものを渡してください。

基本的な使い方

スタイルとスタンドアロンの RkLightboxOverlayComponent を、コンポーネントの imports 配列にインポートします。

gallery.component.ts

テンプレートスロット

4 つのテンプレートスロットのディレクティブで、コンポーネントを複製せずにオーバーレイの UI を自由にカスタマイズできます。各スロットは厳密に型付けされたコンテキストのオブジェクトを受け取ります。

ディレクティブコンテキストの型説明
[rkLightboxControls]LightboxControlsContext上部のコントロールバー(閉じるボタン、カウンター、フルスクリーン切り替え)を置き換えます
[rkLightboxNavigation]LightboxNavContext前後のナビゲーション矢印を置き換えます
[rkLightboxInfo]LightboxInfoContext下部のタイトルと説明のグラデーションのオーバーレイを置き換えます
[rkLightboxSlide]LightboxSlideContext個々のスライドの内容を置き換えます(動画スライドに必要)
[rkLightboxLoading]{ $implicit: activeIndex, item }独自の読み込み表示
[rkLightboxError]{ $implicit: activeIndex, item }独自のエラー表示
typescript

動画のサポート

動画スライドを使うには、rkLightboxSlide のテンプレートスロットと RkLightboxVideoSlideComponent でオプトインする必要があります。画像だけでよいギャラリーに動画プレイヤーをバンドルしないための設計です。

typescript

フルスクリーン

フルスクリーンの状態を監視したり切り替えたりするには、@reelkit/angularfullscreenSignalrequestFullscreenexitFullscreen を使います。

typescript

URL の状態

ライブデモを見る →

RkLightboxUrlOverlayComponent は、開閉状態をアドレスバーに持つ別のコンポーネントです。createOverlayUrlState でコントローラーを作り、[controller] として渡します。パラメーターがスライドを指すとギャラリーは自分で開き、なくなると閉じます。リンクは共有でき、戻るボタンはページを離れる代わりにギャラリーを閉じます。

組み込みのキー

スライドは組み込みのキーで指せます。urlIndexKey(位置で指す)か urlStableIdKey(安定した id で指す)をコントローラーに展開してください。どちらも @reelkit/angular から再エクスポートされています。URL の状態のガイドCore API を参照してください。

typescript

インジェクションコンテキスト(フィールドの初期化子かコンストラクター)の中で呼んでください。すぐに接続し、DestroyRef で解放されるので、ギャラリーが開いたままコンポーネントが破棄されてもリスナーは残りません。すべてのオプションは Angular API リファレンス にあります。

  • 開くと履歴エントリーを 1 つ 積みます。スライドを送るとそれを 置き換え るので、N 回移動してもエントリーは増えず、1 回戻れば必ずギャラリーから出られます。
  • 戻るで閉じるのは、アプリ内からギャラリーを開いた場合だけです(リンクがエントリーを積んだ場合)。新しいタブで直接開いた共有リンクには前の履歴がないので、ブラウザーの戻るではサイトを離れます。✕ ボタンか Escape なら、その場でパラメーターを取り除いてページにとどまります。
  • どのスライドも指さないパラメーター(古いブックマークや手で書き換えた値)は、開けないスライドを指したままにならないよう、URL から取り除かれます。
  • テンプレートスロットはそのまま使えます。URL のコンポーネントが 6 つのスロットの問い合わせを自分で行い、それぞれのテンプレートをギャラリーへ渡すので、rkLightboxControls などは rk-lightbox-overlay の中と同じように置けます。
  • ルーティングを使うアプリケーションでは、Router の上に作ったアダプターを渡してください。Router の裏で履歴を書くと、その位置情報が古くなり、次のナビゲーションでパラメーターが消えます。

ルーターを使うアプリでは、アダプターを渡します。 Router の裏で履歴を書くと、その位置情報が古くなり、次のナビゲーションでパラメーターが消えます。Router の上にアダプターを作り、adapter として渡してください:

typescript

安定したリンク。 インデックスは位置なので、ブックマークした ?photo=3 はリストが並べ替えられると別の画像を開きます。urlStableIdKey は各アイテムの安定した id で指し、現在のリストを走査します。よくあるケースは 1 回の呼び出しで済みます。

typescript

hashCodec: base64UrlCodec を渡すと、URL の id を base64url でエンコードします。元に戻せる難読化で、暗号学的ハッシュではありません。

別のフィールド(slug)で指したい場合や、locateAsync で無限フィードをページングしたい場合は、codec(通信形式)と locator(検索)を自分で作ります:

typescript

無限またはページングされたギャラリー。 locate は同期なので、読み込み済みの画像にしか答えません。20 件を読み込んだフィードの 400 番目の画像への共有リンクは見つかりません。locateAsync はフォールバックで、locate が見つけられなかったときだけ呼ばれます。必要なページを読み込み、その識別子が最終的に持ったインデックスを返してください。保留中のあいだギャラリーは閉じたままで、パラメーターはそのまま残るので、ディープリンクは取得のあいだも失われません。null か reject でパラメーターは取り除かれます。

近道

アイテムの id で指すなら、codec と locator を手書きする必要はありません。locateAsync をそのまま urlStableIdKey({ items, locateAsync }) に渡してください(見つからなければ取得してからインデックスを返します)。下のより完全な例は、別のフィールドで指す場合や、すべてを自分で制御したい場合のものです。

typescript

RkLightboxUrlOverlayComponent の入力

rk-lightbox-overlay の入力をすべて受け取りますが、isOpen の代わりにコントローラーを使います。出力は同じ closedslideChange です。閉じるのは URL が行うので、closed は仕組みではなく通知です。

入力デフォルト説明
controllerUrlStateController必須createOverlayUrlState のコントローラー。その位置で、ギャラリーが開いているかどうかと、どのスライドを表示するかが決まります。コンポーネントはスライドの切り替え時と閉じるときに、これを通じて書き戻します。

RkLightboxOverlayComponent の入力

入力デフォルト説明
isOpenboolean必須表示を制御します。false のときオーバーレイは DOM から取り除かれます
itemsLightboxItem[]必須ギャラリーのアイテム(画像または動画)の配列
initialIndexnumber0最初に表示するアイテムの 0 始まりのインデックス
transitionFnTransitionTransformFnslideTransitionスライドのトランジション関数。組み込みのもの(slideTransition、flipTransition、lightboxFadeTransition、lightboxZoomTransition)をインポートするか、独自のものを渡します。省略すると slideTransition になります。
showInfobooleantrueタイトルと説明の情報オーバーレイを描画するかどうか
showControlsbooleantrue上部のコントロールバー(閉じる、カウンター、フルスクリーン)を描画するかどうか
showNavigationbooleantrue前後のナビゲーション矢印を描画するかどうか
transitionDurationnumber300スライドのアニメーションの長さ(ms)
swipeDistanceFactornumber0.12スライドを切り替えるのに必要なスワイプ距離の最小の割合(0–1)
swipeToCloseDirection'up' | 'down''up'モバイルでスワイプして閉じるジェスチャーの方向
loopbooleanfalse最後のスライドから最初のスライドへ戻るかどうか
enableNavKeysbooleantrueキーボードの矢印キーによる操作を有効にします
enableWheelbooleantrueマウスホイールでの操作を有効にします
wheelDebounceMsnumber200ホイールイベントのデバウンス時間(ms)
ariaLabelstring'Image gallery'ダイアログ領域のアクセシブルなラベル

RkLightboxOverlayComponent の出力

出力説明
closedEventEmitter<void>ユーザーがギャラリーを閉じたときに発行されます
slideChangeEventEmitter<number>アクティブなスライドのインデックスが変わったときに発行されます

LightboxItem インターフェース

フィールド必須説明
srcstringはい画像または動画の URL
type'image' | 'video'いいえアイテムの種類。デフォルトは 'image' です
posterstringいいえ動画アイテムのサムネイル画像
titlestringいいえ情報オーバーレイに表示するタイトル
descriptionstringいいえタイトルの下に表示する説明
widthnumberいいえ画像の本来の幅(ピクセル)
heightnumberいいえ画像の本来の高さ(ピクセル)

テンプレートスロットのコンテキスト型

フィールド
LightboxControlsContext{ item, onClose, activeIndex, count, isFullscreen, onToggleFullscreen }
LightboxNavContext{ item, onPrev, onNext, activeIndex, count }
LightboxInfoContext{ $implicit: LightboxItem, index }
LightboxSlideContext{ $implicit: LightboxItem, index, size: [number, number], isActive, onReady, onWaiting, onError }

トランジション

任意の TransitionTransformFntransitionFn 入力で渡します。使うトランジションだけをインポートすれば、残りはバンドラーがツリーシェイキングします。省略すると slideTransition になります。

関数提供元説明
slideTransition@reelkit/angular-lightbox標準的な横方向のスライド(デフォルト)
lightboxFadeTransition@reelkit/angular-lightbox画像どうしをクロスフェード
flipTransition@reelkit/angular-lightbox3D でカードをめくる効果
lightboxZoomTransition@reelkit/angular-lightbox小さいサイズから通常のサイズへズームイン
typescript

コンテンツの読み込みとエラー処理

rkLightboxSlide のテンプレートスロットを使う場合、読み込み状態を報告するための 3 つのライフサイクルのコールバックがコンテキストで使えます。ギャラリーはスライドごとの状態を追跡し、それに応じてスピナーかエラーアイコンを表示します。コンテンツのプリローダーは壊れた URL をキャッシュするので、失敗したスライドを再訪しても再試行はしません。

ライフサイクルのコールバック

コールバック説明
onReady() => voidスライドの内容の読み込みに成功したことを伝えます(たとえば画像のデコードが終わった)
onWaiting() => voidスライドの内容が読み込み中またはバッファリング中であることを伝えます(スピナーを表示)
onError() => voidスライドの内容の読み込みに失敗したことを伝えます(エラーアイコンを表示)

rkLightboxSlide でコールバックをつなぐ

html

独自の読み込みテンプレート

rkLightboxLoading ディレクティブで、デフォルトのスピナーを置き換えます。

html

独自のエラーテンプレート

rkLightboxError ディレクティブで、デフォルトのエラーアイコンを置き換えます。

html

CSS クラス

CSS クラスはすべて通常のクラス(スコープなし)なので、@reelkit/angular-lightbox/styles.css のあとに読み込むスタイルシートで、詳細度の高いセレクターを使って指定できます。色、サイズ、z-index を変えるなら、下の テーマ設定 で説明している CSS カスタムプロパティを使ってください。

クラスコンポーネント説明
.rk-lightbox-overlayOverlayルートのコンテナー(フルスクリーンの背景)
.rk-lightbox-top-shadeOverlayコントロールの後ろの上部のグラデーション
.rk-lightbox-spinnerOverlayデフォルトの読み込みスピナー
.rk-lightbox-img-errorOverlayエラー状態のコンテナー(壊れた画像)
.rk-lightbox-img-error-textOverlayエラー状態のテキストラベル
.rk-lightbox-swipe-hintOverlayモバイルでのスワイプのヒント
.rk-lightbox-emptyOverlay空の状態のテキスト
.rk-lightbox-controls-leftControls左上のコントロールのコンテナー
.rk-lightbox-btnControlsコントロールのボタン(フルスクリーンなど)
.rk-lightbox-closeControls閉じるボタン
.rk-lightbox-counterControls画像のカウンターのチップ
.rk-lightbox-navNavigationナビゲーションの矢印(前へ・次への両方)
.rk-lightbox-nav-prevNavigation前へ の矢印
.rk-lightbox-nav-nextNavigation次へ の矢印
.rk-lightbox-infoInfoタイトルと説明のコンテナー
.rk-lightbox-titleInfo画像のタイトル
.rk-lightbox-descriptionInfo画像の説明
.rk-lightbox-slideSlideスライドのコンテナー
.rk-lightbox-imgSlide画像要素
.rk-lightbox-video-containerVideoSlide動画スライドのコンテナー(オプトイン)
.rk-lightbox-video-elementVideoSlide動画要素(オプトイン)
.rk-lightbox-video-posterVideoSlide動画のポスター画像(オプトイン)
.rk-lightbox-video-errorVideoSlide動画のエラー状態のコンテナー

テーマ設定

色、サイズ、z-index、トランジションはすべて CSS カスタムプロパティにあります。:root(またはギャラリーの任意の祖先)で 1 つでも複数でも上書きすれば、コンポーネントのソースに触れずにテーマを変えられます。トークンは React のギャラリーと共通なので、上書きはバインディング間でそのまま使えます。

トークンデフォルト制御するもの
--rk-lightbox-overlay-bg#000フルスクリーンの背景色
--rk-lightbox-overlay-z9999オーバーレイの z-index
--rk-lightbox-top-shade-height80px上部のグラデーションの高さ
--rk-lightbox-top-shade-bglinear-gradient(rgba(0,0,0,0.6), transparent)上部のグラデーションの色
--rk-lightbox-edge-padding16px閉じる、ナビゲーション、左上のコントロールの端からの距離
--rk-lightbox-controls-gap12px左上のコントロールの間隔
--rk-lightbox-transition0.2sボタンのホバーのトランジションの長さ
--rk-lightbox-blur8pxボタンやチップの背景のぼかしの半径
--rk-lightbox-btn-bgrgba(0, 0, 0, 0.5)閉じる、ナビゲーション、小さいボタンのデフォルトの背景
--rk-lightbox-btn-bg-hoverrgba(255, 255, 255, 0.2)閉じる、ナビゲーション、小さいボタンのホバー時の背景
--rk-lightbox-btn-fg#fff閉じる、ナビゲーション、小さいボタンのアイコンの色
--rk-lightbox-btn-size36px小さいボタンの大きさ(フルスクリーン切り替えなど)
--rk-lightbox-close-size40px閉じるボタンの大きさ
--rk-lightbox-nav-size48px前後の矢印の大きさ
--rk-lightbox-nav-opacity0.7前後の矢印の通常時の不透明度
--rk-lightbox-counter-fg#fffカウンターのテキストの色
--rk-lightbox-counter-bgrgba(0, 0, 0, 0.5)カウンターのチップの背景
--rk-lightbox-counter-size14pxカウンターの文字サイズ
--rk-lightbox-counter-padding6px 12pxカウンターのチップの余白
--rk-lightbox-counter-radius20pxカウンターのチップの角丸
--rk-lightbox-spinner-size28pxデフォルトのスピナーの幅と高さ
--rk-lightbox-spinner-duration0.8sスピナーの回転の長さ
--rk-lightbox-error-fgrgba(255, 255, 255, 0.4)エラーアイコンとテキストの色
--rk-lightbox-info-bglinear-gradient(transparent, rgba(0,0,0,0.8))キャプションの背景のグラデーション
--rk-lightbox-info-padding24pxキャプションの内側の余白
--rk-lightbox-title-size18pxタイトルの文字サイズ
--rk-lightbox-description-size14px説明の文字サイズ
--rk-lightbox-hint-fgrgba(255, 255, 255, 0.5)スワイプのヒントのテキストの色
--rk-lightbox-hint-bgrgba(0, 0, 0, 0.3)スワイプのヒントのチップの背景
--rk-lightbox-video-bg#000<video> の後ろのレターボックスの背景

下のスニペットを、@reelkit/angular-lightbox/styles.css のあとに読み込むスタイルシートに入れてください。

css

アクセシビリティ

オーバーレイのルートはモーダルダイアログ(role="dialog"aria-modal="true")です。ariaLabel 入力を指定すると、スクリーンリーダーの読み上げが変わります。デフォルトは「Image gallery」です。各スライドは role="group"aria-roledescription="slide"、そして画像のタイトルと位置から作られる aria-label を持ちます。

ギャラリーは開くとフォーカスを取り込み、閉じるとトリガーに戻します。Tab と Shift+Tab は中のフォーカス可能な要素を循環し、外へ出たフォーカス(外側のクリック、プログラムからのフォーカス)は引き戻されます。@reelkit/corecaptureFocusForReturncreateFocusTrap で実装されています。

キーボードショートカット

キー動作
ArrowLeft前の画像
ArrowRight次の画像
Escapeギャラリーを閉じる(フルスクリーン中ならフルスクリーンを終了)