Masonry Gallery(瀑布流圖庫)
Masonry Gallery(瀑布流圖庫)用於展示寬高比例不同的圖片。每張圖片會保留原始比例並放入目前最短的欄;使用者向下捲動頁面時,控制項會自動載入下一頁,不會在控制項內產生另一條捲軸。
它適合靈感圖庫、作品集、旅遊照片、媒體素材和視覺案例,與 CardSet 的用途不同。CardSet 著重業務記錄摘要、狀態、後設資料及操作;Masonry Gallery 著重圖片和連續瀏覽。
| 控制項 | 主要目標 | 資料與版面 |
|---|---|---|
| Masonry Gallery | 以圖片為主,保留不同比例並連續瀏覽 | 分頁圖片記錄 + 頁面層級無限捲動 |
| CardSet | 顯示業務記錄摘要、狀態、後設資料與操作 | 統一卡片範本 + Pagination 或 Load More |
| Grid | 手動編排頁面區域與控制項 | 固定 24 欄版面,不重複資料記錄 |
1. 新增控制項
- 進入 Page Designer,展開 Containers。
- 將 Masonry Gallery 拖入頁面。
- 先設定 Data Source,再完成欄位對應。
- 設定穩定名稱,例如
portfolioGallery。
設計畫布會顯示不同比例的示意卡片。Preview 才會讀取真實資料,且最多自動讀取兩頁,避免編輯期間持續載入。
2. 設定資料來源
支援 Model Data Source、Custom API、Media Library 和 Object Storage。Model 與 Custom API 回傳業務記錄;後兩種資料來源會透過後端 Media Connector 查詢。
2.1 Custom API 範例
POST /spark/api/sample/masonry-gallery/images
| 屬性 | 值 |
|---|---|
| URL | /spark/api/sample/masonry-gallery/images |
| Request Method | POST |
| Rows Path | data.records |
| Total Path | data.total |
| Current Page Path | data.current |
| Page Size Path | data.pageSize |
使用 Test & Import 請求一頁資料並匯入 Response Fields:
| Field Path | Data Type | 用途 |
|---|---|---|
id | TEXT | 記錄唯一鍵 |
imageUrl | URL | 圖片網址 |
title | TEXT | 圖片標題 |
caption | TEXT | 補充說明 |
badge | TEXT | 分類標籤 |
alt | TEXT | 圖片替代文字 |
width | NUMBER | 圖片原始寬度 |
height | NUMBER | 圖片原始高度 |
請求本文會包含分頁資訊:
{"current": 1, "pageSize": 6}
{
"success": true,
"data": {
"current": 1,
"pageSize": 6,
"total": 24,
"records": [{
"id": "gallery-1",
"imageUrl": "/spark/api/sample/masonry-gallery/assets/coastal-architecture.jpg",
"title": "Coastal Geometry",
"caption": "Sunlit concrete forms above a quiet blue sea.",
"badge": "Architecture",
"alt": "White coastal architecture above the sea",
"width": 1200,
"height": 1200
}]
}
}
total 是最可靠的結束條件。若沒有 total,當某頁記錄少於 Items Per Request 時也會結束。Row Unique Key 必須在所有頁面中唯一;重複鍵會被移除。
2.1 Media Library 與 Object Storage
先在 App Settings → Integrations → Media Connections 建立可重用的連線:
- 在 Console Secret Management 建立憑證。OSS/S3/MinIO 使用
OBJECT_STORAGE,媒體平台使用MEDIA_PROVIDER。 - 在 Media Connections 選擇 Provider 與既有 Secret。表單只會顯示該 Provider 真正需要的設定;自動使用的官方 API Endpoint 不會顯示。
- 在 Masonry Gallery 的 Data Source 選擇 Media Library 或 Object Storage,只參照 Connection,再設定 Collection/Container、Path、篩選條件與 Page Size。
- 點選 Test。測試、設計預覽與執行態使用相同的 Media Gateway 和回應解析邏輯。
目前正式可用的 Provider:
| Provider | Secret Management | Media Connection 設定 |
|---|---|---|
| Cloudinary | MEDIA_PROVIDER;API Key 填入 API Key,API Secret 填入 API Secret | Cloud Name 必填,Root Folder 選填 |
| ImageKit | MEDIA_PROVIDER;Public API Key 填入 API Key,Private API Key 填入 API Secret | Root Folder 選填;官方 API Endpoint 自動使用 |
| Aliyun OSS / AWS S3 / MinIO | OBJECT_STORAGE;填寫 Access Key 與 Access Secret | 依儲存服務設定 Endpoint、預設 Bucket 與 Root Prefix |
Spark Sample Media Library 只用於不依賴外部帳號的開發測試。Cloudinary 與 ImageKit 是正式 Media Library Connector;Bynder、AEM Assets 與完整 Spark Media Library 尚未開放。
頁面 JSON 不會保存 secretId、Access Key 或臨時簽名 URL。後端會把結果正規化為 records、nextCursor、hasMore 與可選的 total。卡片使用 thumbnailUrl,全螢幕預覽使用 imageUrl。
{
"records": [{
"id": "asset-001",
"imageUrl": "https://cdn.example/full.webp",
"thumbnailUrl": "https://cdn.example/card.webp",
"title": "Summer campaign",
"alt": "Summer campaign launch",
"width": 1600,
"height": 1067
}],
"nextCursor": "opaque-next-cursor",
"hasMore": true,
"total": null
}
可執行範例位於 spark-sample 的 SampleMasonryMediaConnector.java、masonry-gallery-media-connection.json 與 masonry-gallery-media-page.json。
3. 設定欄位對應
| 控制項屬性 | 建議對應 | 是否必要 |
|---|---|---|
| Row Unique Key | id | 是 |
| Image URL Field | imageUrl | 是 |
| Title Field | title | 否 |
| Caption Field | caption | 否 |
| Badge Field | badge | 否 |
| Alternative Text Field | alt | 建議設定 |
| Image Width Field | width | 建議設定 |
| Image Height Field | height | 建議設定 |
Width 與 Height 位於 Advanced。兩者一起設定後,圖片下載前就能保留正確比例,減少版面跳動。Alternative Text 應描述圖片內容,未提供時會回退到 Title。
4. 響應式版面
| 屬性 | 建議值 | 說明 |
|---|---|---|
| Desktop Columns | 4 | 寬螢幕欄數 |
| Tablet Columns | 3 | 中等寬度欄數 |
| Mobile Columns | 2;長標題較多時可改為 1 | 手機欄數 |
| Spacing | DEFAULT | COMPACT、DEFAULT 或 RELAXED |
| Items Per Request | 6 或 12 | 單次載入數量 |
欄數會隨頁面寬度變化,圖片不會被裁成相同高度。
5. 捲動載入
距離目前內容末端約一個半畫面時,控制項開始讀取下一頁。同一時間只會有一個分頁請求,並顯示載入、可 Retry 的錯誤與完成狀態。短時間內返回頁面時,會恢復已載入記錄與捲動位置。
不要把 Masonry Gallery 放在具有內部捲軸的狹窄固定高度容器中。
6. 全螢幕預覽與互動
開啟 Enable Fullscreen Preview 後,點擊圖片會開啟檢視器。支援左右按鈕、方向鍵、Escape、Tab、Enter 和 Space。
執行 onClick 前,控制項會把目前記錄寫入 Current Record:
record.id
record.imageUrl
record.title
record.badge
一次點擊可以同時開啟預覽並執行 onClick。若互動會立刻跳轉頁面,建議關閉 Fullscreen Preview。
| 函數 | 用途 |
|---|---|
reloadGallery | 清除分頁狀態,從第一頁重新請求 |
setGalleryData | 直接替換記錄,並停止自動翻頁 |
7. 頁面請求上下文與後端除錯
Data Source 測試、設計預覽與執行頁面使用相同請求邏輯,Spark 會自動加入:
| Header | 值 |
|---|---|
X-Spark-Page-Environment | DEV、TEST 或 PROD |
X-Spark-Page-Render-Mode | DESIGN_PREVIEW 或 RUNTIME |
不需要在 Data Source 中手動新增。後端使用 SparkPageRequestHeaders.resolve 解析,並可在設計預覽回傳較短的資料集:
@PostMapping
public ApiResult<ProTablePageResult<MasonryGalleryImageDTO>> queryByPost(
@RequestBody(required = false) MasonryGalleryQueryRequest request,
@RequestHeader(value = SparkPageRequestHeaders.ENVIRONMENT, required = false) String environment,
@RequestHeader(value = SparkPageRequestHeaders.RENDER_MODE, required = false) String renderMode) {
return SparkApiResultHelper.success(
Locale.ENGLISH,
galleryService.query(request,
SparkPageRequestHeaders.resolve(environment, renderMode)),
"SPARK-SAMPLE-MASONRY-GALLERY-0001");
}
Service 會依照渲染模式選擇資料量:
int total = requestContext != null
&& requestContext.getRenderMode() == SparkPageRenderMode.DESIGN_PREVIEW
? 12
: 24;
Java 範例、頁面 JSON 與圖片都位於 spark-sample。完整規範請參閱頁面請求上下文。
8. 效能與資料建議
- 提供適合顯示尺寸的壓縮圖片,並使用 CDN 或同源快取。
- 始終回傳穩定的
id、width、height和有意義的alt。 - 每次請求建議 6~20 筆,後端排序必須穩定。
- 圖片請求失敗與資料 API 失敗應分開排查;單張圖片失敗不會中止後續分頁。
9. 常見問題
- 一直重複載入同一批圖片: 確認後端使用
current與pageSize做真實分頁,並檢查回應路徑。 - 捲動後沒有繼續請求: 檢查
total、短頁面,或上一次請求是否失敗並等待 Retry。 - 圖片載入後版面明顯跳動: 回傳並對應
width、height。 - 圖片顯示為預留位置: 檢查 Image URL Field、圖片網址、認證與 CORS。
- 需要業務按鈕、狀態操作和複雜後設資料: 使用 CardSet;Masonry Gallery 不提供 Card Actions。