MediaGroup
MediaGroup 是 AtDoc 用於描述多媒體資源集合與其視覺排列方式的語義容器。
MediaGroup 不會將多個媒體資源實際合併為單一檔案,而是透過結構化語義描述:
- 媒體資源集合
- 媒體排列方式
- 尺寸與比例
- 間距
- 對齊方式
- 響應式行為
- 個別媒體在版面中的佔位
- 未來可擴充的版面策略
因此,MediaGroup 所產生的是一個媒體版面(Media Layout),而非一張經過 Flatten 的圖片。
基本結構
@media-group(layout="grid")
@image(src="./1.png")
@image(src="./2.png")
@image(src="./3.png")
@end概念 AST:
MediaGroup
├── layout: grid
├── Image
├── Image
└── ImageMediaGroup 的子節點仍然保持獨立,因此 Renderer 可以針對每個媒體資源進行:
- 點擊
- 放大
- 拖曳
- 載入
- Lazy Loading
- 替代文字
- Metadata
- 動態更新
layout
layout 定義 MediaGroup 的主要排列策略。
@media-group(layout="grid")layout 不應直接綁定特定 CSS 實作,而應代表 AtDoc 層級的語義排列策略。
Renderer 可以依據平台自行決定實際實作方式。
Grid
規則網格排列。
@media-group(layout="grid", columns=3)
@image(src="./1.png")
@image(src="./2.png")
@image(src="./3.png")
@image(src="./4.png")
@image(src="./5.png")
@image(src="./6.png")
@end結果:
┌───────┬───────┬───────┐
│ 1 │ 2 │ 3 │
├───────┼───────┼───────┤
│ 4 │ 5 │ 6 │
└───────┴───────┴───────┘可擴充參數:
columns
rows
gap
aspect-ratio
alignmentMasonry
瀑布流排列。
@media-group(layout="masonry", columns=3)
@image(src="./1.png")
@image(src="./2.png")
@image(src="./3.png")
@image(src="./4.png")
@end適合:
- 相簿
- Pinterest 類型內容
- 不同比例圖片
- 動態內容列表
Stack
將媒體依序堆疊。
@media-group(layout="stack")
@image(src="./1.png")
@image(src="./2.png")
@image(src="./3.png")
@end可支援:
vertical
horizontal
overlay例如:
@media-group(layout="stack", direction="horizontal")Split
將媒體區域依比例切割。
@media-group(layout="split")
@image(src="./main.png", span="2")
@image(src="./side.png", span="1")
@end概念:
┌────────────────┬────────┐
│ │ │
│ Main │ Side │
│ │ │
└────────────────┴────────┘適合:
- 主圖 + 次圖
- 封面
- Editorial Layout
- Landing Page
Featured
指定一個或多個媒體作為主要內容。
@media-group(layout="featured")
@image(src="./cover.png", featured=true)
@image(src="./1.png")
@image(src="./2.png")
@image(src="./3.png")
@endRenderer 可以根據 featured 自動產生較大的版面。
Custom
當既有 Layout 無法滿足需求時,可以使用自訂排列。
@media-group(layout="custom")
@image(src="./1.png", position="a")
@image(src="./2.png", position="b")
@image(src="./3.png", position="c")
@endCustom Layout 不應成為一般使用者的主要方式,而應作為:
- 高度客製化版面
- Renderer 擴充
- 第三方 Layout Provider
- 未來 Layout Engine
的基礎。
Media Item
MediaGroup 的子節點不限定只能使用圖片。
MediaGroup
├── Image
├── Image
├── Video
├── Audio
└── Media例如:
@media-group(layout="grid", columns=2)
@image(src="./cover.png")
@video(src="./demo.mp4")
@image(src="./architecture.png")
@video(src="./preview.mp4")
@end因此 MediaGroup 是媒體容器,而不是圖片容器。
Span
個別媒體可以指定在 Layout 中佔據的空間。
@media-group(layout="grid", columns=3)
@image(src="./1.png", span="2x2")
@image(src="./2.png")
@image(src="./3.png")
@image(src="./4.png")
@endspan 的語義:
1x1
2x1
1x2
2x2
3x2Renderer 決定實際如何將其映射至 Grid、CSS Grid 或其他 Layout Engine。
gap
定義媒體之間的間距。
@media-group(
layout="grid",
columns=3,
gap="12px"
)也可以在語義層使用抽象值:
gap="small"
gap="medium"
gap="large"Renderer 再依照平台 Theme 決定實際尺寸。
aspect-ratio
控制媒體在 Layout 中的顯示比例。
@media-group(
layout="grid",
columns=3,
aspect-ratio="1/1"
)個別 Media 可以覆寫:
@image(
src="./cover.png",
aspect-ratio="16/9"
)alignment
定義媒體在其 Layout 區域中的對齊方式。
@media-group(
layout="grid",
alignment="center"
)可支援:
start
center
end
stretchresponsive
MediaGroup 可以定義不同 viewport 下的 Layout 行為。
@media-group(
layout="grid",
columns=3,
responsive=true
)Renderer 可以根據環境自動調整:
Desktop → 3 columns
Tablet → 2 columns
Mobile → 1 column未來也可以進一步描述:
@media-group(layout="grid")
@responsive(min="1200px", columns=4)
@responsive(min="768px", columns=2)
@responsive(columns=1)
...
@endLayout 與 Renderer
AtDoc 不應將 Layout 語義直接限制在 HTML/CSS。
例如:
AtDoc
↓
Semantic AST
↓
MediaGroup
↓
Layout Definition
↓
Renderer不同 Renderer 可以將相同 AtDoc 結構轉換成不同平台:
Web Renderer
→ CSS Grid
Native Renderer
→ Native Layout
PDF Renderer
→ Fixed Layout
Terminal Renderer
→ Text-based Layout
Future Renderer
→ Custom Layout Engine因此:
layout描述「如何排列」,而不是「使用什麼技術排列」。
Layout Registry
未來可以建立 Layout Registry。
LayoutRegistry
grid
masonry
stack
split
featured
custom第三方 Renderer 可以註冊新的 Layout:
LayoutRegistry
├── core:grid
├── core:masonry
├── core:stack
├── core:split
├── core:featured
└── extension:xxxAtDoc Parser 不需要知道所有 Layout 的實際視覺實作。
Parser 只需要保留:
layout = "xxx"是否支援則交由 Renderer 決定。
Unknown Layout
如果 Renderer 不支援指定的 Layout:
@media-group(layout="future-layout")
...
@end不應導致整份 AtDoc 解析失敗。
Parser 應保留該語義:
MediaGroup
└── layout: future-layoutRenderer 可以:
- 使用 fallback Layout
- 顯示原始內容
- 忽略 Layout 屬性
- 提示 Renderer 不支援
如此可以維持 AtDoc 文件的向前相容性。
未來擴充方向
MediaGroup 未來可以擴充:
Layout
grid
masonry
stack
split
featured
carousel
gallery
justified
timeline
flow
customMedia
image
video
audio
embed
document
interactiveInteraction
click
zoom
lightbox
drag
reorder
fullscreenLoading
lazy
eager
priority
placeholderAccessibility
alt
caption
description
labelResponsive
breakpoint
columns
direction
visibilityPresentation
gap
alignment
aspect-ratio
radius
crop
object-fit設計原則
MediaGroup 應遵循以下原則:
- 媒體本身保持獨立
- Layout 與 Media 分離
- Layout 是語義,不是 CSS
- Renderer 決定實際呈現
- 未知 Layout 不應阻止 Parser 工作
- 允許 Renderer 擴充 Layout
- 支援 Responsive Layout
- 允許個別 Media 覆寫 Group 設定
- 避免將 Layout 綁死於 Image
- 保持未來 Video、Audio、Embed 等媒體的擴充能力
Concept
MediaGroup 最終可以抽象成:
MediaGroup
│
├── Layout
│ ├── Strategy
│ ├── Configuration
│ └── Responsive Rules
│
└── Media[]
├── Media
├── Media
├── Media
└── ...因此 AtDoc 描述的不是:
「把九張圖片合成一張圖片」而是:
「將九個獨立 Media 資源,
按照指定 Layout 組成一個可渲染的媒體版面。」這使 MediaGroup 可以成為 AtDoc 的通用語義結構,並在未來擴展至 Gallery、Video Grid、Interactive Media、Responsive Layout 與第三方 Renderer。