Angular Lightbox
@reelkit/angular-lightbox で作られた、Angular 用のフルスクリーンの画像と動画のギャラリーです。
機能
インストール
npm install @reelkit/angular-lightbox @reelkit/angular lucide-angularスタイルシートを一度だけ登録します:
// Anywhere that runs at startup — main.ts, app.config.ts, a component file.
import '@reelkit/angular-lightbox/styles.css';
// Or, if you keep CSS out of TypeScript, from your global stylesheet:
// @import '@reelkit/angular-lightbox/styles.css';
// Or register it in angular.json:
// "styles": ["node_modules/@reelkit/angular-lightbox/styles.css"]アイコン
デフォルトのコントロールはアイコンに lucide-angular を使います。別のアイコンライブラリを使いたい場合は、rkLightboxControls と rkLightboxNavigation のテンプレートスロットで独自のものを渡してください。
クイックスタート
スタイルとスタンドアロンの RkLightboxOverlayComponent を、コンポーネントの imports 配列にインポートします。
import { Component } from '@angular/core';
import {
RkLightboxOverlayComponent,
type LightboxItem,
} from '@reelkit/angular-lightbox';
import '@reelkit/angular-lightbox/styles.css';
const images: LightboxItem[] = [
{
src: '/cdn/samples/images/image-01.jpg',
title: 'Mountain River',
description: 'A beautiful mountain river',
},
{
src: '/cdn/samples/images/image-02.jpg',
title: 'Snowy Peaks',
},
{
src: '/cdn/samples/images/image-03.jpg',
title: 'Misty Forest',
description: 'Morning fog over the forest canopy',
},
{
src: '/cdn/samples/images/image-04.jpg',
title: 'Autumn Trail',
},
{
src: '/cdn/samples/images/image-05.jpg',
title: 'Ocean Cliff',
description: 'Dramatic cliffs above the Pacific',
},
{
src: '/cdn/samples/images/image-06.jpg',
title: 'Desert Dunes',
},
];
@Component({
selector: 'app-root',
standalone: true,
imports: [RkLightboxOverlayComponent],
template: `
<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:8px">
@for (img of images; track img.src; let i = $index) {
<button (click)="openIndex = i" style="aspect-ratio:4/3;cursor:pointer">
<img [src]="img.src" style="width:100%;height:100%;object-fit:cover" />
</button>
}
</div>
<rk-lightbox-overlay
[isOpen]="openIndex !== null"
[items]="images"
[initialIndex]="openIndex ?? 0"
(closed)="openIndex = null"
/>
`,
})
export class AppComponent {
images = images;
openIndex: number | null = null;
}オーバーレイが描画される場所
オーバーレイを document.body の末尾へ移す React と Vue の lightbox と違い、rk-lightbox-overlay は置いた場所に描画され、position: fixed で画面を覆います。transform、perspective、filter、will-change: transform を持つ祖先の中には置かないでください。その祖先がオーバーレイの包含ブロックになり、lightbox はビューポートではなくその祖先の大きさになり、祖先の overflow で切り取られます。独自のスタッキングコンテキストを作る祖先も、--rk-lightbox-overlay-z で lightbox をどこまで持ち上げられるかを制限します。その代わり、どの祖先に設定した --rk-lightbox-* トークンも lightbox に届きます。
テンプレートスロット
4 つのテンプレートスロットのディレクティブで、コンポーネントを複製せずにオーバーレイの UI を自由にカスタマイズできます。各スロットは厳密に型付けされたコンテキストのオブジェクトを受け取ります。
| ディレクティブ | コンテキストの型 | 説明 |
|---|---|---|
| [rkLightboxControls] | LightboxControlsContext | 上部のコントロールバー(閉じるボタン、カウンター、フルスクリーン切り替え)を置き換えます |
| [rkLightboxNavigation] | LightboxNavContext | 前後のナビゲーション矢印を置き換えます |
| [rkLightboxInfo] | LightboxInfoContext | 下部のタイトルと説明のグラデーションのオーバーレイを置き換えます |
| [rkLightboxSlide] | LightboxSlideContext | 個々のスライドの内容を置き換えます(動画スライドに必要) |
| [rkLightboxLoading] | LightboxLoadingContext | 独自の読み込み表示。ディレクティブのクラスは RkLightboxLoadingDirective です |
| [rkLightboxError] | LightboxErrorContext | 独自のエラー表示。ディレクティブのクラスは RkLightboxErrorDirective です |
import {
RkLightboxOverlayComponent,
RkLightboxControlsDirective,
RkLightboxNavigationDirective,
RkLightboxInfoDirective,
RkCloseButtonComponent,
RkCounterComponent,
RkFullscreenButtonComponent,
type LightboxItem,
type LightboxControlsContext,
type LightboxNavContext,
} from '@reelkit/angular-lightbox';
@Component({
selector: 'app-root',
standalone: true,
imports: [
RkLightboxOverlayComponent,
RkLightboxControlsDirective,
RkLightboxNavigationDirective,
RkLightboxInfoDirective,
RkCloseButtonComponent,
RkCounterComponent,
RkFullscreenButtonComponent,
],
template: `
<rk-lightbox-overlay [isOpen]="isOpen" [items]="images" (closed)="isOpen = false">
<!-- Custom controls bar -->
<ng-template rkLightboxControls
let-onClose="onClose"
let-activeIndex="activeIndex"
let-count="count"
let-isFullscreen="isFullscreen"
let-onToggleFullscreen="onToggleFullscreen">
<div style="position:absolute;top:0;left:0;right:0;padding:12px;
display:flex;align-items:center;justify-content:space-between">
<rk-close-button (clicked)="onClose()" />
<rk-counter [currentIndex]="activeIndex + 1" [count]="count" />
<rk-fullscreen-button
[isFullscreen]="isFullscreen"
(toggled)="onToggleFullscreen()" />
</div>
</ng-template>
<!-- Custom navigation -->
<ng-template rkLightboxNavigation
let-onPrev="onPrev"
let-onNext="onNext"
let-activeIndex="activeIndex"
let-count="count">
<button (click)="onPrev()" [disabled]="activeIndex === 0">←</button>
<button (click)="onNext()" [disabled]="activeIndex === count - 1">→</button>
</ng-template>
<!-- Custom info overlay -->
<ng-template rkLightboxInfo let-item let-index="index">
<div style="position:absolute;bottom:0;left:0;right:0;padding:16px;
background:linear-gradient(transparent,rgba(0,0,0,0.6))">
<h3 style="color:#fff">{{ item.title }}</h3>
<p style="color:rgba(255,255,255,0.7)">{{ item.description }}</p>
</div>
</ng-template>
</rk-lightbox-overlay>
`,
})
export class AppComponent {
images: LightboxItem[] = [];
isOpen = false;
}動画のサポート
動画スライドを使うには、rkLightboxSlide のテンプレートスロットと RkLightboxVideoSlideComponent でオプトインする必要があります。画像だけでよいギャラリーに動画プレイヤーをバンドルしないための設計です。
組み込みのサウンドボタンは、SoundStateService が <rk-lightbox-overlay> の上で提供されているときだけ表示されます。スライドはあなたのテンプレートから描画されるので、その共有インスタンスだけが切り替えを動画まで届けます。ないときは setLightboxVideoMuted で要素を直接操作してください。
import {
RkLightboxOverlayComponent,
RkLightboxSlideDirective,
RkLightboxVideoSlideComponent,
type LightboxItem,
type LightboxSlideContext,
} from '@reelkit/angular-lightbox';
@Component({
selector: 'app-root',
standalone: true,
imports: [
RkLightboxOverlayComponent,
RkLightboxSlideDirective,
RkLightboxVideoSlideComponent,
],
template: `
<rk-lightbox-overlay [isOpen]="isOpen" [items]="items" (closed)="isOpen = false">
<ng-template rkLightboxSlide
let-item
let-index="index"
let-size="size"
let-isActive="isActive"
let-autoAdvance="autoAdvance"
let-onReady="onReady"
let-onEnded="onEnded">
@if (item.type === 'video') {
<!-- With autoAdvance the video plays once and reports its end -->
<rk-lightbox-video-slide
[src]="item.src"
[poster]="item.poster"
[slideKey]="'lightbox-' + index"
[size]="size"
[isActive]="isActive"
[loop]="!autoAdvance"
[onReady]="onReady"
[onEnded]="onEnded"
/>
} @else {
<img [src]="item.src"
[style.width.px]="size[0]"
[style.height.px]="size[1]"
style="object-fit:contain" />
}
</ng-template>
</rk-lightbox-overlay>
`,
})
export class AppComponent {
isOpen = false;
items: LightboxItem[] = [
{ src: '/photo.jpg', title: 'Photo' },
{ src: '/clip.mp4', type: 'video', poster: '/clip-thumb.jpg', title: 'Video' },
];
}フルスクリーン
フルスクリーンの状態を監視したり切り替えたりするには、@reelkit/angular の fullscreenSignal、requestFullscreen、exitFullscreen を使います。
import { fullscreenSignal, requestFullscreen, exitFullscreen } from '@reelkit/angular';
@Component({ ... })
export class AppComponent {
readonly isFullscreen = fullscreenSignal();
toggle(container: HTMLElement): void {
if (this.isFullscreen()) {
exitFullscreen();
} else {
requestFullscreen(container);
}
}
}URL の状態
ライブデモを見る →RkLightboxUrlOverlayComponent は、開閉状態をアドレスバーに持つ別のコンポーネントです。createOverlayUrlState でコントローラーを作り、[controller] として渡します。パラメーターがスライドを指すとギャラリーは自分で開き、なくなると閉じます。リンクは共有でき、戻るボタンはページを離れる代わりにギャラリーを閉じます。
組み込みのキー
スライドは組み込みのキーで指せます。urlIndexKey(位置で指す)か urlStableIdKey(安定した id で指す)をコントローラーに展開してください。どちらも @reelkit/angular から再エクスポートされています。URL の状態のガイド と Core API を参照してください。
import { RkLightboxUrlOverlayComponent } from '@reelkit/angular-lightbox';
import { createOverlayUrlState, urlIndexKey, urlStableIdKey } from '@reelkit/angular';
@Component({
imports: [RkLightboxUrlOverlayComponent, RouterLink],
template: `
@for (image of images(); track image.src; let i = $index) {
<a [routerLink]="[]" [queryParams]="{ photo: i }">
<img [src]="image.src" alt="" />
</a>
}
<rk-lightbox-url-overlay [controller]="photo" [items]="images()" />
`,
})
export class GalleryComponent {
protected readonly images = signal(photos);
protected readonly photo = createOverlayUrlState({
param: 'photo',
...urlIndexKey(() => this.images().length),
});
}インジェクションコンテキスト(フィールドの初期化子かコンストラクター)の中で呼んでください。すぐに接続し、DestroyRef で解放されるので、ギャラリーが開いたままコンポーネントが破棄されてもリスナーは残りません。すべてのオプションは Angular API リファレンス にあります。
- 開くと履歴エントリーを 1 つ 積みます。スライドを送るとそれを 置き換え るので、N 回移動してもエントリーは増えず、1 回戻れば必ずギャラリーから出られます。
- 戻るで閉じるのは、アプリ内からギャラリーを開いた場合だけです(リンクがエントリーを積んだ場合)。新しいタブで直接開いた共有リンクには前の履歴がないので、ブラウザーの戻るではサイトを離れます。✕ ボタンか Escape なら、その場でパラメーターを取り除いてページにとどまります。
- どのスライドも指さないパラメーター(古いブックマークや手で書き換えた値)は、開けないスライドを指したままにならないよう、URL から取り除かれます。
- テンプレートスロットはそのまま使えます。URL のコンポーネントが 6 つのスロットの問い合わせを自分で行い、それぞれのテンプレートをギャラリーへ渡すので、
rkLightboxControlsなどはrk-lightbox-overlayの中と同じように置けます。 - ルーティングを使うアプリケーションでは、
Routerの上に作ったアダプターを渡してください。Router の裏で履歴を書くと、その位置情報が古くなり、次のナビゲーションでパラメーターが消えます。
ルーターを使うアプリでは、アダプターを渡します。 Router の裏で履歴を書くと、その位置情報が古くなり、次のナビゲーションでパラメーターが消えます。Router の上にアダプターを作り、adapter として渡してください:
import { createRouterUrlAdapter } from '@reelkit/angular/ng-router-url-adapter';
const adapter = createRouterUrlAdapter();
const photo = createOverlayUrlState({
param: 'photo',
adapter,
...urlIndexKey(() => this.images().length),
});安定したリンク。 インデックスは位置なので、ブックマークした ?photo=3 はリストが並べ替えられると別の画像を開きます。urlStableIdKey は各アイテムの安定した id で指し、現在のリストを走査します。よくあるケースは 1 回の呼び出しで済みます。
const photo = createOverlayUrlState({
param: 'photo',
...urlStableIdKey({ items: () => this.images() }),
});hashCodec: base64UrlCodec を渡すと、URL の id を base64url でエンコードします。元に戻せる難読化で、暗号学的ハッシュではありません。
別のフィールド(slug)で指したい場合や、locateAsync で無限フィードをページングしたい場合は、codec(通信形式)と locator(検索)を自分で作ります:
const photo = createOverlayUrlState({
param: 'photo',
codec: { decode: (raw) => raw, encode: (id) => id },
locator: {
locate: (id) => this.images().findIndex((x) => x.id === id),
identify: (index) => this.images()[index].id,
},
});無限またはページングされたギャラリー。 locate は同期なので、読み込み済みの画像にしか答えません。20 件を読み込んだフィードの 400 番目の画像への共有リンクは見つかりません。locateAsync はフォールバックで、locate が見つけられなかったときだけ呼ばれます。必要なページを読み込み、その識別子が最終的に持ったインデックスを返してください。保留中のあいだギャラリーは閉じたままで、パラメーターはそのまま残るので、ディープリンクは取得のあいだも失われません。null か reject でパラメーターは取り除かれます。
近道
アイテムの id で指すなら、codec と locator を手書きする必要はありません。locateAsync をそのまま urlStableIdKey({ items, locateAsync }) に渡してください(見つからなければ取得してからインデックスを返します)。下のより完全な例は、別のフィールドで指す場合や、すべてを自分で制御したい場合のものです。
const photo = createOverlayUrlState({
param: 'photo',
codec: { decode: (raw) => raw, encode: (id) => id },
locator: {
locate: (id) => this.images().findIndex((x) => x.id === id),
identify: (index) => this.images()[index].id,
locateAsync: async (id) => {
const loaded = await loadById(id); // or loadUntil(id) — fetch just that one, or page up to it
if (!loaded) return null; // exhausted — link names no item
this.images.set(loaded); // commit; the overlay renders from this
return loaded.findIndex((x) => x.id === id); // wherever it landed
},
},
});自動送り
[autoAdvance]="true" を指定すると、ギャラリーが開いたときにスライドショーとして再生します。デフォルトではオフなので、既存の Lightbox の描画と動作は変わりません。
- 画像は
autoAdvanceInterval(デフォルトは 5000 ms)のあいだ表示されます。画像の読み込みが終わった時点から数えるので、遅い画像が誰にも見られないまま飛ばされることはありません。読み込みに失敗した画像は、そのエラーの時点から数えます。 - 動画はループせずに 1 回だけ再生し、終わると次へ進みます。
rkLightboxSlideテンプレートでは、動画のサポートのようにrk-lightbox-video-slideに[loop]="!autoAdvance"と[onEnded]="onEnded"をバインドしてください。 - 待機するのは、マウスがコントロール(ボタン、リンク、キャプション)の上にあるあいだ、スワイプ中、ページが非表示のあいだです。そのあとは止まったところから続けます。
- 手で移動すると(矢印、キー、ホイール、スワイプ)、新しいスライドの間隔は 0 から始まります。スライドショーはオンのままです。
- 最後のスライドでは、
loopが指定されていない限り止まります。コントロールの再生/一時停止ボタンが状態を示し、閲覧者が切り替えられます。
スライドショーは Angular のゾーンの外で動くので、そのアニメーションフレームは変更検知を起こしません。独自の rkLightboxControls テンプレートは isAutoAdvancing を受け取り、autoAdvance がオンのときだけ onToggleAutoAdvance も受け取ります。それがあるときは rk-play-pause-button を描画してください。タイミング自体は @reelkit/core の createSlideshowController です。自動再生ガイドと Core API を参照してください。
import { Component } from '@angular/core';
import {
RkCloseButtonComponent,
RkLightboxControlsDirective,
RkLightboxOverlayComponent,
RkPlayPauseButtonComponent,
type LightboxItem,
} from '@reelkit/angular-lightbox';
@Component({
selector: 'app-gallery',
imports: [
RkLightboxOverlayComponent,
RkLightboxControlsDirective,
RkPlayPauseButtonComponent,
RkCloseButtonComponent,
],
template: `
<rk-lightbox-overlay
[isOpen]="isOpen"
[items]="items"
[autoAdvance]="true"
[autoAdvanceInterval]="4000"
(closed)="isOpen = false"
>
<!-- Optional: a custom bar shows the toggle only when its handler is there -->
<ng-template rkLightboxControls let-ctx>
@if (ctx.onToggleAutoAdvance) {
<rk-play-pause-button
[playing]="ctx.isAutoAdvancing"
(toggled)="ctx.onToggleAutoAdvance()"
/>
}
<rk-close-button (clicked)="ctx.onClose()" />
</ng-template>
</rk-lightbox-overlay>
`,
})
export class GalleryComponent {
isOpen = false;
items: LightboxItem[] = [{ src: '/beach.jpg' }, { src: '/forest.jpg' }];
}ダウンロード
[showDownload]="true" を指定すると、コントロールにダウンロードボタンが加わります。アクティブなアイテムを downloadUrl(なければ src)から、downloadName(なければ URL の最後の部分)という名前で保存します。
ファイルは fetch してから保存します。別オリジンのリンクでは、ブラウザーは download 属性を無視してファイルを開いてしまうからです。fetch が失敗したとき(よくあるのは CORS ヘッダーを送らない別オリジンのサーバーです)は、ファイルを新しいタブで開くので、閲覧者はそこから保存できます。ワンクリックで保存できるようにするには、ファイルを Access-Control-Allow-Origin 付きで配信してください。ダウンロード中はボタンが無効になります。
独自の rkLightboxControls テンプレートは isDownloading を受け取り、showDownload がオンのときだけ onDownload も受け取ります。それがあるときは rk-download-button を描画してください。ヘルパーは @reelkit/core の downloadFile です。ダウンロードガイドを参照してください。
import { Component } from '@angular/core';
import {
RkCloseButtonComponent,
RkDownloadButtonComponent,
RkLightboxControlsDirective,
RkLightboxOverlayComponent,
type LightboxItem,
} from '@reelkit/angular-lightbox';
@Component({
selector: 'app-gallery',
imports: [
RkLightboxOverlayComponent,
RkLightboxControlsDirective,
RkDownloadButtonComponent,
RkCloseButtonComponent,
],
template: `
<rk-lightbox-overlay
[isOpen]="isOpen"
[items]="items"
[showDownload]="true"
(closed)="isOpen = false"
>
<!-- Optional: a custom bar shows the button only when its handler is there -->
<ng-template rkLightboxControls let-ctx>
@if (ctx.onDownload) {
<rk-download-button
[downloading]="ctx.isDownloading"
(pressed)="ctx.onDownload()"
/>
}
<rk-close-button (clicked)="ctx.onClose()" />
</ng-template>
</rk-lightbox-overlay>
`,
})
export class GalleryComponent {
isOpen = false;
items: LightboxItem[] = [
{
src: '/beach-1600.jpg',
// Save the original rather than the resized preview
downloadUrl: '/beach-original.jpg',
downloadName: 'beach.jpg',
},
];
}コントロールのボタン
| コンポーネント | セレクター | 入力/出力 | 説明 |
|---|---|---|---|
RkPlayPauseButtonComponent | rk-play-pause-button | [playing], (toggled) | スライドショーの切り替えボタン(Play/Pause のアイコン、再生中は aria-pressed)。autoAdvance のときにデフォルトのコントロールが表示します。 |
RkDownloadButtonComponent | rk-download-button | [downloading], (pressed) | ダウンロードボタン。downloading のあいだは無効になります。showDownload のときにデフォルトのコントロールが表示します。 |
RkSoundButtonComponent | rk-sound-button | [muted], (toggled) | 動画の要素向けのミュート切り替え。動画スライドではデフォルトのコントロールが表示します。残すには、独自の rkLightboxControls テンプレートに置きます。 |
RkLightboxUrlOverlayComponent の入力
rk-lightbox-overlay の入力をすべて受け取りますが、isOpen の代わりにコントローラーを使います。出力は同じ closed と slideChange です。閉じるのは URL が行うので、closed は仕組みではなく通知です。
| 入力 | 型 | デフォルト | 説明 |
|---|---|---|---|
controller | UrlStateController | 必須 | createOverlayUrlState のコントローラー。その位 置で、ギャラリーが開いているかどうかと、どのスライドを表示するかが決まります。コンポーネントはスライドの切り替え時と閉じるときに、これを通じて書き戻します。 |
RkLightboxOverlayComponent の入力
| 入力 | 型 | デフォルト | 説明 |
|---|---|---|---|
isOpen | boolean | 必須 | 表示を制御します。false のときオーバーレイは DOM から取り除かれます |
items | LightboxItem[] | 必須 | ギャラリーのアイテム(画像または動画)の配列 |
initialIndex | number | 0 | 最初に表示するアイテムの 0 始まりのインデックス |
transitionFn | TransitionTransformFn | slideTransition | スライドのトランジション関数。組み込みのもの(slideTransition、flipTransition、lightboxFadeTransition、lightboxZoomTransition)をインポートするか、独自のものを渡します。省略すると slideTransition になります。 |
showInfo | boolean | true | タイトルと説明の情報オーバーレイを描画するかどうか |
showControls | boolean | true | 上部のコントロールバー(閉じる、カウンター、フルスクリーン)を描画するかどうか |
showNavigation | boolean | true | 前後のナビゲーション矢印を描画するかどうか |
transitionDuration | number | 300 | スライドのアニメーションの長さ(ms) |
swipeDistanceFactor | number | 0.12 | スライドを切り替えるのに必要なスワイプ距離の最小の割合(0–1) |
swipeToCloseDirection | 'up' | 'down' | 'up' | モバイルでスワイプして閉じるジェスチャーの方向 |
loop | boolean | false | 最後のスライドから最初のスライドへ戻るかどうか |
enableNavKeys | boolean | true | キーボードの矢印キーによる操作を有効にします |
enableWheel | boolean | true | マウスホイールでの操作を有効にします |
wheelDebounceMs | number | 200 | ホイールイベントのデバウンス時間(ms) |
autoAdvance | boolean | false | ギャラリーをスライドショーとして再生します。自動送りを参照してください。 |
autoAdvanceInterval | number | 5000 | スライドショーで各画像を表示しておく長さ(ms)。読み込みが終わった時点から数えます |
showDownload | boolean | false | アクティブなアイテムのダウンロードボタンを加えます。ダウンロードを参照してください。 |
ariaLabel | string | 'Image gallery' | ダイアログ領域のアクセシブルなラベル |
上のスライダーの入力(transitionDuration、swipeDistanceFactor、loop、enableNavKeys、enableWheel、wheelDebounceMs)の型は ReelProxyProps です。それらを Lightbox に転送するラッパーコンポーネントの型付 けに使います。
RkLightboxOverlayComponent の出力
| 出力 | 型 | 説明 |
|---|---|---|
closed | EventEmitter<void> | ユーザーがギャラリーを閉じたときに発行されます |
slideChange | EventEmitter<number> | アクティブなスライドのインデックスが変わったときに発行されます |
LightboxItem インターフェース
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
src | string | はい | 画像または動画の URL |
type | 'image' | 'video' | いいえ | アイテムの種類。デフォルトは 'image' です |
poster | string | いいえ | 動画アイテムのサムネイル画像 |
title | string | いいえ | 情報オーバーレイに表示するタイトル |
description | string | いいえ | タイトルの下に表示する説明 |
width | number | いいえ | 画像の本来の幅(ピクセル) |
height | number | いいえ | 画像の本来の高さ(ピクセル) |
downloadUrl | string | いいえ | ダウンロードボタンが保存するもの。デフォルトは src |
downloadName | string | いいえ | 保存するファイル名。デフォルト は URL のパスの最後の部分 |
テンプレートスロットのコンテキスト型
| 型 | フィールド |
|---|---|
LightboxControlsContext | { item, activeIndex, count, isFullscreen, isAutoAdvancing, isDownloading, onClose, onToggleFullscreen, onToggleAutoAdvance?, onDownload? } |
LightboxNavContext | { item, onPrev, onNext, activeIndex, count } |
LightboxInfoContext | { $implicit: LightboxItem, index } |
LightboxSlideContext | { $implicit: LightboxItem, index, size: [number, number], isActive, autoAdvance, onReady, onWaiting, onError, onEnded } |
LightboxLoadingContext | { $implicit: activeIndex, item }。rkLightboxLoading テンプレートが受け取るも の |
LightboxErrorContext | { $implicit: activeIndex, item }。rkLightboxError テンプレートが受け取るもの |
トランジション
任意の TransitionTransformFn を transitionFn 入力で渡します。使うトランジションだけをインポートすれば、残りはバンドラーがツリーシェイキングします。省略すると slideTransition になります。
| 関数 | 提供元 | 説明 |
|---|---|---|
slideTransition | @reelkit/angular-lightbox | 標準的な横方向のスライド(デフォルト) |
lightboxFadeTransition | @reelkit/angular-lightbox | 画像どうしをクロスフェード |
flipTransition | @reelkit/angular-lightbox | 3D でカードをめくる効果 |
lightboxZoomTransition | @reelkit/angular-lightbox | 小さいサイズから通常のサイズへズームイン |
import {
RkLightboxOverlayComponent,
lightboxFadeTransition,
} from '@reelkit/angular-lightbox';
@Component({
imports: [RkLightboxOverlayComponent],
template: `
<rk-lightbox-overlay
[isOpen]="isOpen"
[items]="images"
[transitionFn]="lightboxFadeTransition"
(closed)="isOpen = false"
/>
`,
})
export class GalleryComponent {
protected readonly lightboxFadeTransition = lightboxFadeTransition;
}コンテンツの読み込みとエラー処理
rkLightboxSlide のテンプレートスロットを使う場合、読み込み状態を報告するための 3 つのライフサイクルのコールバックがコンテキストで使えます。ギャラリーはスライドごとの状態を追跡し、それに応じてスピナーかエラーアイコンを表示します。コンテンツのプリローダーは壊れた URL をキャッシュするので、失敗したスライドを再訪しても再試行はしません。
ライフサイクルのコールバック
| コールバック | 型 | 説明 |
|---|---|---|
onReady | () => void | スライドの内容の読み込みに成功したことを伝えます(たとえば画像のデコードが終わった) |
onWaiting | () => void | スライドの内容が読み込み中またはバッファリング中であることを伝えます(スピナーを表示) |
onError | () => void | スライドの内容の読み込みに失敗したことを伝えます(エラーアイコンを表示) |
rkLightboxSlide でコールバックをつなぐ
<rk-lightbox-overlay [isOpen]="isOpen" [items]="items" (closed)="isOpen = false">
<ng-template rkLightboxSlide
let-item
let-size="size"
let-isActive="isActive"
let-onReady="onReady"
let-onWaiting="onWaiting"
let-onError="onError">
@if (item.type === 'video') {
<rk-lightbox-video-slide
[item]="item"
[size]="size"
[isActive]="isActive"
/>
} @else {
<img [src]="item.src"
[style.width.px]="size[0]"
[style.height.px]="size[1]"
style="object-fit:contain"
(load)="onReady()"
(error)="onError()" />
}
</ng-template>
</rk-lightbox-overlay>独自の読み込みテンプレート
rkLightboxLoading ディレクティブで、デフォルトのスピナーを置き換えます。
<rk-lightbox-overlay [isOpen]="isOpen" [items]="items" (closed)="isOpen = false">
<ng-template rkLightboxLoading let-index let-item="item">
<div style="display:flex;flex-direction:column;align-items:center;color:#fff">
<span>Loading image {{ index + 1 }}...</span>
<span style="opacity:0.6">{{ item.title }}</span>
</div>
</ng-template>
</rk-lightbox-overlay>独自のエラーテンプレート
rkLightboxError ディレクティブで、デフォルトのエラーアイコンを置き換えます。
<rk-lightbox-overlay [isOpen]="isOpen" [items]="items" (closed)="isOpen = false">
<ng-template rkLightboxError let-index let-item="item">
<div style="display:flex;flex-direction:column;align-items:center;color:#ef4444">
<span>Failed to load</span>
<span style="opacity:0.6">{{ item.title ?? item.src }}</span>
</div>
</ng-template>
</rk-lightbox-overlay>CSS クラス
CSS クラスはすべて通常のクラス(スコープなし)なので、@reelkit/angular-lightbox/styles.css のあとに読み込むスタイルシートで、詳細度の 高いセレクターを使って指定できます。色、サイズ、z-index を変えるなら、下の テーマ設定 で説明している CSS カスタムプロパティを使ってください。
| クラス | コンポーネント | 説明 |
|---|---|---|
.rk-lightbox-overlay | Overlay | ルートのコンテナー(フルスクリーンの背景) |
.rk-lightbox-top-shade | Overlay | コントロールの後ろの上部のグラデーション |
.rk-lightbox-spinner | Overlay | デフォルトの読み込みスピナー |
.rk-lightbox-img-error | Overlay | エラー状態のコンテナー(壊れた画像) |
.rk-lightbox-img-error-text | Overlay | エラー状態のテキストラベル |
.rk-lightbox-swipe-hint | Overlay | モバイルでのスワイプのヒント |
.rk-lightbox-empty | Overlay | 空の状態のテキスト |
.rk-lightbox-controls-left | Controls | 左上のコントロールのコンテナー |
.rk-lightbox-btn | Controls | コントロールのボタン(フルスクリーンなど) |
.rk-lightbox-play-pause | Controls | スライドショーの再生/一時停止ボタン(.rk-lightbox-btn と併用) |
.rk-lightbox-download | Controls | ダウンロードボタン(.rk-lightbox-btn と併用) |
.rk-lightbox-close | Controls | 閉じるボタン |
.rk-lightbox-counter | Controls | 画像のカウンターのチップ |
.rk-lightbox-nav | Navigation | ナビゲーションの矢印(前へ・次への両方) |
.rk-lightbox-nav-prev | Navigation | 前へ の矢印 |
.rk-lightbox-nav-next | Navigation | 次へ の矢印 |
.rk-lightbox-info | Info | タイトルと説明のコンテナー |
.rk-lightbox-title | Info | 画像のタイトル |
.rk-lightbox-description | Info | 画像の説明 |
.rk-lightbox-slide | Slide | スライドのコンテナー |
.rk-lightbox-img | Slide | 画像要素 |
.rk-lightbox-video-container | VideoSlide | 動画スライドのコンテナー(オプトイン) |
.rk-lightbox-video-element | VideoSlide | 動画要素(オプトイン) |
.rk-lightbox-video-poster | VideoSlide | 動画のポスター画像(オプトイン) |
.rk-lightbox-video-error | VideoSlide | 動画のエラー状態のコンテナー |
テーマ設定
色、サイズ、z-index、トランジションはすべて CSS カスタムプロパティにあります。:root(またはギャラリーの任意の祖先)で 1 つでも複数でも上書きすれば、コンポーネントのソースに触れずにテーマを変えられます。トークンは React のギャラリーと共通なので、上書きはバインディング間でそのまま使えます。
| トークン | デフォルト | 制御するもの |
|---|---|---|
--rk-lightbox-overlay-bg | #000 | フルスクリーンの背景色 |
--rk-lightbox-overlay-z | 9999 | オーバーレイの z-index |
--rk-lightbox-top-shade-height | 80px | 上部のグラデーションの高さ |
--rk-lightbox-top-shade-bg | linear-gradient(rgba(0,0,0,0.6), transparent) | 上部のグラデーションの色 |
--rk-lightbox-edge-padding | 16px | 閉じる、ナビゲーション、左上のコントロールの端からの距離 |
--rk-lightbox-controls-gap | 12px | 左上のコントロールの間隔 |
--rk-lightbox-transition | 0.2s | ボタンのホバーのトランジションの長さ |
--rk-lightbox-blur | 8px | ボタンやチップの背景のぼかしの半径 |
--rk-lightbox-btn-bg | rgba(0, 0, 0, 0.5) | 閉じる、ナビゲーション、小さいボタンのデフォルトの背景 |
--rk-lightbox-btn-bg-hover | rgba(255, 255, 255, 0.2) | 閉じる、ナビゲーション、小さいボタンのホバー時の背景 |
--rk-lightbox-btn-fg | #fff | 閉じる、ナビゲーション、小さいボタンのアイコンの色 |
--rk-lightbox-btn-size | 36px | 小さいボタンの大きさ(フルスクリーン切り替えなど) |
--rk-lightbox-btn-disabled-opacity | 0.5 | 無効になった小さいボタンの不透明度(ダウンロード中) |
--rk-lightbox-close-size | 40px | 閉じるボタンの大きさ |
--rk-lightbox-nav-size | 48px | 前後の矢印の大きさ |
--rk-lightbox-nav-opacity | 0.7 | 前後の矢印の通常時の不透明度 |
--rk-lightbox-counter-fg | #fff | カウンターのテキストの色 |
--rk-lightbox-counter-bg | rgba(0, 0, 0, 0.5) | カウンターのチップの背景 |
--rk-lightbox-counter-size | 14px | カウンターの文字サイズ |
--rk-lightbox-counter-padding | 6px 12px | カウンターのチップの余白 |
--rk-lightbox-counter-radius | 20px | カウンターのチップの角丸 |
--rk-lightbox-spinner-size | 28px | デフォルトのスピナーの幅と高さ |
--rk-lightbox-spinner-duration | 0.8s | スピナーの回転の長さ |
--rk-lightbox-error-fg | rgba(255, 255, 255, 0.4) | エラーアイコンとテキストの色 |
--rk-lightbox-info-bg | linear-gradient(transparent, rgba(0,0,0,0.8)) | キャプションの背景のグラデーション |
--rk-lightbox-info-padding | 24px | キャプションの内側の余白 |
--rk-lightbox-title-size | 18px | タイトルの文字サイズ |
--rk-lightbox-description-size | 14px | 説明の文字サイズ |
--rk-lightbox-hint-fg | rgba(255, 255, 255, 0.5) | スワイプのヒントのテキストの色 |
--rk-lightbox-hint-bg | rgba(0, 0, 0, 0.3) | スワイプのヒントのチップの背景 |
--rk-lightbox-video-bg | #000 | <video> の後ろのレターボックスの背景 |
下のスニペットを、@reelkit/angular-lightbox/styles.css のあとに読み込むスタイルシートに入れてください。
/* Brand the lightbox */
:root {
--rk-lightbox-overlay-bg: #0f172a;
--rk-lightbox-btn-bg: rgba(99, 102, 241, 0.65);
--rk-lightbox-btn-bg-hover: rgba(168, 85, 247, 0.85);
--rk-lightbox-nav-size: 56px;
--rk-lightbox-counter-bg: rgba(99, 102, 241, 0.65);
--rk-lightbox-info-bg: linear-gradient(
transparent,
rgba(99, 102, 241, 0.55) 60%,
rgba(168, 85, 247, 0.85)
);
}アクセシビリティ
オーバーレイのルートはモーダルダイアログ(role="dialog"、aria-modal="true")です。ariaLabel 入力を指定すると、スクリーンリーダーの読み上げが変わります。デフォルトは「Image gallery」です。各スライドは role="group"、aria-roledescription="slide"、そして画像のタイトルと位置から作られる aria-label を持ちます。
ギャラリーは開くとフォーカスを取り込み、閉じるとトリガーに戻します。Tab と Shift+Tab は中のフォーカス可能な要素を循環し、外へ出たフォーカス(外側のクリック、プログラムからのフォーカス)は引き戻されます。@reelkit/core の captureFocusForReturn と createFocusTrap で実装されています。
キーボードショートカット
| キー | 動作 |
|---|---|
ArrowLeft | 前の画像 |
ArrowRight | 次の画像 |
Escape | ギャラリーを閉じる(フルスクリーン中ならフルスクリーンを終了) |