特性
安装
图标
lucide-angular 作为图标。如果你想换一套图标库,可以用 rkLightboxControls 和 rkLightboxNavigation 模板插槽提供自己的实现。基本用法
把样式和独立组件 RkLightboxOverlayComponent 引入组件的 imports 数组。
模板插槽
四个模板插槽指令让你完全定制浮层界面,无需 fork 组件。每个插槽都会收到带完整类型的上下文对象。
| 指令 | 上下文类型 | 说明 |
|---|---|---|
| [rkLightboxControls] | LightboxControlsContext | 替换顶部控件栏(关闭按钮、计数、全屏开关) |
| [rkLightboxNavigation] | LightboxNavContext | 替换上一张 / 下一张导航箭头 |
| [rkLightboxInfo] | LightboxInfoContext | 替换底部的标题 / 描述渐变浮层 |
| [rkLightboxSlide] | LightboxSlideContext | 替换单张幻灯片的内容(视频幻灯片必须提供) |
| [rkLightboxLoading] | { $implicit: activeIndex, item } | 自定义加载提示 |
| [rkLightboxError] | { $implicit: activeIndex, item } | 自定义错误提示 |
视频支持
视频幻灯片需要通过 rkLightboxSlide 模板插槽和 RkLightboxVideoSlideComponent显式启用。这样设计是为了让只需要图片的画廊不必打包视频播放器。
全屏
使用 fullscreenSignal, requestFullscreen、 exitFullscreen from @reelkit/angular 来观察或切换全屏状态。
URL 状态
RkLightboxUrlOverlayComponent 是一个独立组件,它的打开状态存放在地址栏里。用 createOverlayUrlState 构建控制器,再作为 [controller]传进去:参数指向某张幻灯片时画廊自己打开,参数消失时关闭。链接可以分享,返回键关闭的是画廊而不是离开页面。
请在注入上下文中调用它 —— 字段初始化器或构造函数。它会立即挂载,并通过 DestroyRef释放,因此画廊打开期间组件被销毁也不会留下监听器。完整选项见 Angular API 参考.
- 打开时压入 一条 历史记录。翻页则是 替换 它,因此走 N 步也不会多出记录,退一步永远就是离开画廊。
- 只有从应用内部打开画廊时返回键才会关闭它 —— 因为那次链接压入了一条记录。在新标签页里直接打开的分享链接背后没有历史,浏览器返回会离开站点;这时用 ✕ 按钮或 Escape 就地移除参数并留在页面上。
- 指向不存在幻灯片的参数 —— 过期的书签、手改的值 —— 会从 URL 中移除,而不是继续声称一张打不开的幻灯片。
- 模板插槽用法不变:url 组件自己执行六次插槽查询,并把每个模板转发给画廊,因此
rkLightboxControls以及它的兄弟指令放在它内部,和放在rk-lightbox-overlay. - 带路由的应用请传入基于
Router构建的适配器。绕过 Router 直接写历史会让它的 location 过期,下一次导航就会把参数丢掉。
带路由的应用请传入适配器。 绕过 Router 直接写历史会让它的 location 过期,下一次导航就会把参数丢掉,所以请基于 Router 构建适配器并作为 adapter:
稳定的链接。 索引是按位置的 —— 收藏下来的 ?photo=3 在列表重新排序后就会打开另一张图片。 urlStableIdKey 按每个条目稳定的 id来寻址,扫描当前列表 —— 一次调用就覆盖了常见场景。
传入 hashCodec: base64UrlCodec 即可把 URL 中的 id 做 base64url 编码 —— 这是可逆的混淆,不是加密哈希。
想按别的字段(比如 slug)来寻址,或者用 locateAsync给无限信息流翻页,就自己构建 codec (传输格式)和 locator (查找):
无限或分页画廊。 locate 是同步的,因此只能回答已经加载过的图片 —— 只加载了 20 张时,指向第 400 张的分享链接就查不到。 locateAsync 是兜底,只有在 locate 未命中时才调用:把需要的页拉进来,再返回该身份最终对应的索引。在它未完成期间,画廊保持关闭,参数也不动,因此深链能熬过这次请求; null 或请求被拒绝则会移除参数。
快捷键
id来寻址?那就不必手写编解码器和定位器 —— 直接把 locateAsync 传给 urlStableIdKey({ items, locateAsync }) (未命中时它会去拉取,然后返回索引)。下面更完整的写法是给按别的字段寻址、或者需要完全掌控的场景准备的。RkLightboxUrlOverlayComponent 输入
接受 rk-lightbox-overlay 的所有输入,除了 isOpen,它被控制器取代。输出与 closed 和 slideChange相同;关闭由 URL 驱动,因此 closed 只是一个通知,而不是关闭机制本身。
| 输入 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| controller | UrlStateController | 必填 | 来自 createOverlayUrlState 的控制器。它的 position 决定画廊是否打开、显示哪一张;组件会在切换幻灯片和关闭时通过它写回。 |
RkLightboxOverlayComponent 输入
| 输入 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| isOpen | boolean | 必填 | 控制显示;为 false 时浮层会从 DOM 中移除 |
| items | LightboxItem[] | 必填 | Lightbox条目数组(图片或视频) |
| initialIndex | number | 0 | 初始可见条目的索引(从 0 开始) |
| transitionFn | TransitionTransformFn | slideTransition | 幻灯片过渡函数。可以引入内置的(slideTransition、flipTransition、lightboxFadeTransition、lightboxZoomTransition),也可以传自定义的。省略时默认为 slideTransition。 |
| showInfo | boolean | true | 是否渲染标题 / 描述信息浮层 |
| showControls | boolean | true | 是否渲染顶部控件栏(关闭、计数、全屏) |
| showNavigation | boolean | true | 是否渲染上一张 / 下一张导航箭头 |
| transitionDuration | number | 300 | 幻灯片动画时长(毫秒) |
| swipeDistanceFactor | number | 0.12 | 触发切换所需的最小滑动距离占比(0–1) |
| swipeToCloseDirection | 'up' | 'down' | 'up' | 移动端滑动关闭手势的方向 |
| loop | boolean | false | 滑动器是否从最后一张绕回第一张 |
| enableNavKeys | boolean | true | 启用键盘方向键导航 |
| enableWheel | boolean | true | 启用鼠标滚轮导航 |
| wheelDebounceMs | number | 200 | 滚轮事件的防抖时长(毫秒) |
| ariaLabel | string | 'Image gallery' | 对话框区域的无障碍标签 |
RkLightboxOverlayComponent 输出
| 输出 | 类型 | 说明 |
|---|---|---|
| closed | EventEmitter<void> | 用户关闭Lightbox时发出 |
| slideChange | EventEmitter<number> | 当前幻灯片索引变化时发出 |
LightboxItem 接口
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| src | string | yes | 图片或视频的 URL |
| type | 'image' | 'video' | no | Item type. Defaults to 'image' |
| poster | string | no | 视频条目的缩略图 |
| title | string | no | 信息浮层中显示的标题 |
| description | string | no | 标题下方显示的描述 |
| width | number | no | 图片固有宽度(像素) |
| height | number | no | 图片固有高度(像素) |
模板插槽上下文类型
| 类型 | 字段 |
|---|---|
| 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 } |
过渡动画
把任意 TransitionTransformFn 通过 transitionFn 输入传入。只引入你用到的那个过渡,打包器就能把其余的摇掉。省略时默认为 slideTransition 。
| 函数 | 来源 | 说明 |
|---|---|---|
| slideTransition | @reelkit/angular-lightbox | 标准横向滑动(默认) |
| lightboxFadeTransition | @reelkit/angular-lightbox | 图片之间交叉淡入淡出 |
| flipTransition | @reelkit/angular-lightbox | 3D 翻卡效果 |
| lightboxZoomTransition | @reelkit/angular-lightbox | 从缩小状态放大到正常尺寸 |
内容加载与错误处理
使用 rkLightboxSlide 模板插槽接管渲染时,上下文里有三个生命周期回调可用于上报加载状态。Lightbox会逐张跟踪状态,并据此显示转圈动画或错误图标。内容预加载器会缓存损坏的 URL,因此再次访问失败的幻灯片不会重试。
生命周期回调
| 回调 | 类型 | 说明 |
|---|---|---|
| onReady | () => void | 通知幻灯片内容已成功加载(例如图片解码完成) |
| onWaiting | () => void | 通知幻灯片内容正在加载 / 缓冲(显示转圈动画) |
| onError | () => void | 通知幻灯片内容加载失败(显示错误图标) |
在 rkLightboxSlide 中接上回调
自定义加载模板
Use the rkLightboxLoading 指令替换默认的转圈动画。
自定义错误模板
Use the rkLightboxError 指令替换默认的错误图标。
CSS 类名
所有 CSS 类名都是普通类名(没有 scoped),因此可以在 @reelkit/angular-lightbox/styles.css之后加载的样式表里用更高优先级的选择器覆盖它们。若只是改颜 色、尺寸和 z-index,请优先使用下面 主题定制 一节。
| 类名 | 组件 | 说明 |
|---|---|---|
| .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 | 控制内容 | 左上角控件容器 |
| .rk-lightbox-btn | 控制内容 | 控制按钮(全屏等) |
| .rk-lightbox-close | 控制内容 | 关闭按钮 |
| .rk-lightbox-counter | 控制内容 | 图片计数标签 |
| .rk-lightbox-nav | 导航 | 导航箭头(上一张和下一张) |
| .rk-lightbox-nav-prev | 导航 | 上一张箭头 |
| .rk-lightbox-nav-next | 导航 | 下一张箭头 |
| .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 (或Lightbox的任意祖先元素)上覆盖,即可在不改组件源码的情况下换主题。这些变量与 React Lightbox保持一致,因此覆盖样式可以在不同框架绑定之间通用。
| 变量 | 默认值 | 控制内容 |
|---|---|---|
| --rk-lightbox-overlay-bg | #000 | Full-screen backdrop color |
| --rk-lightbox-overlay-z | 9999 | Overlay z-index |
| --rk-lightbox-top-shade-height | 80px | Top gradient scrim height |
| --rk-lightbox-top-shade-bg | linear-gradient(rgba(0,0,0,0.6), transparent) | Top gradient scrim color |
| --rk-lightbox-edge-padding | 16px | Edge inset for close / nav / top-left controls |
| --rk-lightbox-controls-gap | 12px | Gap between top-left controls |
| --rk-lightbox-transition | 0.2s | Button hover transition duration |
| --rk-lightbox-blur | 8px | Backdrop blur radius for buttons / chips |
| --rk-lightbox-btn-bg | rgba(0, 0, 0, 0.5) | Default background for close, nav, small buttons |
| --rk-lightbox-btn-bg-hover | rgba(255, 255, 255, 0.2) | Hover background for close, nav, small buttons |
| --rk-lightbox-btn-fg | #fff | Icon color for close, nav, small buttons |
| --rk-lightbox-btn-size | 36px | Small button size (fullscreen toggle, etc.) |
| --rk-lightbox-close-size | 40px | Close button size |
| --rk-lightbox-nav-size | 48px | Prev/next arrow size |
| --rk-lightbox-nav-opacity | 0.7 | Idle opacity of prev/next arrows |
| --rk-lightbox-counter-fg | #fff | Counter text color |
| --rk-lightbox-counter-bg | rgba(0, 0, 0, 0.5) | Counter chip background |
| --rk-lightbox-counter-size | 14px | Counter font size |
| --rk-lightbox-counter-padding | 6px 12px | Counter chip padding |
| --rk-lightbox-counter-radius | 20px | Counter chip border-radius |
| --rk-lightbox-spinner-size | 28px | Default spinner width/height |
| --rk-lightbox-spinner-duration | 0.8s | Spinner rotation duration |
| --rk-lightbox-error-fg | rgba(255, 255, 255, 0.4) | Error icon + text color |
| --rk-lightbox-info-bg | linear-gradient(transparent, rgba(0,0,0,0.8)) | Caption scrim gradient |
| --rk-lightbox-info-padding | 24px | Caption inner padding |
| --rk-lightbox-title-size | 18px | Title font size |
| --rk-lightbox-description-size | 14px | Description font size |
| --rk-lightbox-hint-fg | rgba(255, 255, 255, 0.5) | Swipe hint text color |
| --rk-lightbox-hint-bg | rgba(0, 0, 0, 0.3) | Swipe hint chip background |
| --rk-lightbox-video-bg | #000 | Letterbox background behind <video> |
把下面这段放进在 @reelkit/angular-lightbox/styles.css.
无障碍
浮层根节点是一个模态对话框(role="dialog", aria-modal="true"). Set the ariaLabel 输入可以改变屏幕阅读器的播报内容,默认是 “Image gallery”。每张幻灯片都带有 role="group", aria-roledescription="slide",以及 aria-label ,由图片标题加上位置推导而来。
Lightbox打开时捕获焦点,关闭时把焦点还给触发元素。Tab 和 Shift+Tab 在内部的可聚焦元素之间循环;跑出去的焦点(点击外部、程序化聚焦)会被拉回来。实现基于 captureFocusForReturn 和 createFocusTrap from @reelkit/core.
键盘快捷键
| Key | 作用 |
|---|---|
| ArrowLeft | Previous image |
| ArrowRight | Next image |
| Escape | Close lightbox (or exit fullscreen if active) |