MediaGroup

以語義化方式定義多個媒體資源的排列、版面與呈現方式

  • #layout
  • #image
  • #gallery
  • #collage

MediaGroup

MediaGroup 是 AtDoc 用於描述多媒體資源集合與其視覺排列方式的語義容器。

MediaGroup 不會將多個媒體資源實際合併為單一檔案,而是透過結構化語義描述:

  • 媒體資源集合
  • 媒體排列方式
  • 尺寸與比例
  • 間距
  • 對齊方式
  • 響應式行為
  • 個別媒體在版面中的佔位
  • 未來可擴充的版面策略

因此,MediaGroup 所產生的是一個媒體版面(Media Layout),而非一張經過 Flatten 的圖片。


基本結構

atdoc
@media-group(layout="grid")
    @image(src="./1.png")
    @image(src="./2.png")
    @image(src="./3.png")
@end

概念 AST:

text
MediaGroup
├── layout: grid
├── Image
├── Image
└── Image

MediaGroup 的子節點仍然保持獨立,因此 Renderer 可以針對每個媒體資源進行:

  • 點擊
  • 放大
  • 拖曳
  • 載入
  • Lazy Loading
  • 替代文字
  • Metadata
  • 動態更新

layout

layout 定義 MediaGroup 的主要排列策略。

atdoc
@media-group(layout="grid")

layout 不應直接綁定特定 CSS 實作,而應代表 AtDoc 層級的語義排列策略

Renderer 可以依據平台自行決定實際實作方式。


Grid

規則網格排列。

atdoc
@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

結果:

text
┌───────┬───────┬───────┐
│   1   │   2   │   3   │
├───────┼───────┼───────┤
│   4   │   5   │   6   │
└───────┴───────┴───────┘

可擴充參數:

text
columns
rows
gap
aspect-ratio
alignment

Masonry

瀑布流排列。

atdoc
@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

將媒體依序堆疊。

atdoc
@media-group(layout="stack")
    @image(src="./1.png")
    @image(src="./2.png")
    @image(src="./3.png")
@end

可支援:

text
vertical
horizontal
overlay

例如:

atdoc
@media-group(layout="stack", direction="horizontal")

Split

將媒體區域依比例切割。

atdoc
@media-group(layout="split")
    @image(src="./main.png", span="2")
    @image(src="./side.png", span="1")
@end

概念:

text
┌────────────────┬────────┐
│                │        │
│      Main      │  Side  │
│                │        │
└────────────────┴────────┘

適合:

  • 主圖 + 次圖
  • 封面
  • Editorial Layout
  • Landing Page

Featured

指定一個或多個媒體作為主要內容。

atdoc
@media-group(layout="featured")
    @image(src="./cover.png", featured=true)
    @image(src="./1.png")
    @image(src="./2.png")
    @image(src="./3.png")
@end

Renderer 可以根據 featured 自動產生較大的版面。


Custom

當既有 Layout 無法滿足需求時,可以使用自訂排列。

atdoc
@media-group(layout="custom")
    @image(src="./1.png", position="a")
    @image(src="./2.png", position="b")
    @image(src="./3.png", position="c")
@end

Custom Layout 不應成為一般使用者的主要方式,而應作為:

  • 高度客製化版面
  • Renderer 擴充
  • 第三方 Layout Provider
  • 未來 Layout Engine

的基礎。


Media Item

MediaGroup 的子節點不限定只能使用圖片。

text
MediaGroup
├── Image
├── Image
├── Video
├── Audio
└── Media

例如:

atdoc
@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 中佔據的空間。

atdoc
@media-group(layout="grid", columns=3)
    @image(src="./1.png", span="2x2")
    @image(src="./2.png")
    @image(src="./3.png")
    @image(src="./4.png")
@end

span 的語義:

text
1x1
2x1
1x2
2x2
3x2

Renderer 決定實際如何將其映射至 Grid、CSS Grid 或其他 Layout Engine。


gap

定義媒體之間的間距。

atdoc
@media-group(
    layout="grid",
    columns=3,
    gap="12px"
)

也可以在語義層使用抽象值:

atdoc
gap="small"
gap="medium"
gap="large"

Renderer 再依照平台 Theme 決定實際尺寸。


aspect-ratio

控制媒體在 Layout 中的顯示比例。

atdoc
@media-group(
    layout="grid",
    columns=3,
    aspect-ratio="1/1"
)

個別 Media 可以覆寫:

atdoc
@image(
    src="./cover.png",
    aspect-ratio="16/9"
)

alignment

定義媒體在其 Layout 區域中的對齊方式。

atdoc
@media-group(
    layout="grid",
    alignment="center"
)

可支援:

text
start
center
end
stretch

responsive

MediaGroup 可以定義不同 viewport 下的 Layout 行為。

atdoc
@media-group(
    layout="grid",
    columns=3,
    responsive=true
)

Renderer 可以根據環境自動調整:

text
Desktop → 3 columns
Tablet  → 2 columns
Mobile  → 1 column

未來也可以進一步描述:

atdoc
@media-group(layout="grid")
    @responsive(min="1200px", columns=4)
    @responsive(min="768px", columns=2)
    @responsive(columns=1)

    ...
@end

Layout 與 Renderer

AtDoc 不應將 Layout 語義直接限制在 HTML/CSS。

例如:

text
AtDoc
  ↓
Semantic AST
  ↓
MediaGroup
  ↓
Layout Definition
  ↓
Renderer

不同 Renderer 可以將相同 AtDoc 結構轉換成不同平台:

text
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。

text
LayoutRegistry

grid
masonry
stack
split
featured
custom

第三方 Renderer 可以註冊新的 Layout:

text
LayoutRegistry
├── core:grid
├── core:masonry
├── core:stack
├── core:split
├── core:featured
└── extension:xxx

AtDoc Parser 不需要知道所有 Layout 的實際視覺實作。

Parser 只需要保留:

text
layout = "xxx"

是否支援則交由 Renderer 決定。


Unknown Layout

如果 Renderer 不支援指定的 Layout:

atdoc
@media-group(layout="future-layout")
    ...
@end

不應導致整份 AtDoc 解析失敗。

Parser 應保留該語義:

text
MediaGroup
└── layout: future-layout

Renderer 可以:

  1. 使用 fallback Layout
  2. 顯示原始內容
  3. 忽略 Layout 屬性
  4. 提示 Renderer 不支援

如此可以維持 AtDoc 文件的向前相容性。


未來擴充方向

MediaGroup 未來可以擴充:

Layout

text
grid
masonry
stack
split
featured
carousel
gallery
justified
timeline
flow
custom

Media

text
image
video
audio
embed
document
interactive

Interaction

text
click
zoom
lightbox
drag
reorder
fullscreen

Loading

text
lazy
eager
priority
placeholder

Accessibility

text
alt
caption
description
label

Responsive

text
breakpoint
columns
direction
visibility

Presentation

text
gap
alignment
aspect-ratio
radius
crop
object-fit

設計原則

MediaGroup 應遵循以下原則:

  1. 媒體本身保持獨立
  2. Layout 與 Media 分離
  3. Layout 是語義,不是 CSS
  4. Renderer 決定實際呈現
  5. 未知 Layout 不應阻止 Parser 工作
  6. 允許 Renderer 擴充 Layout
  7. 支援 Responsive Layout
  8. 允許個別 Media 覆寫 Group 設定
  9. 避免將 Layout 綁死於 Image
  10. 保持未來 Video、Audio、Embed 等媒體的擴充能力

Concept

MediaGroup 最終可以抽象成:

text
MediaGroup
│
├── Layout
│   ├── Strategy
│   ├── Configuration
│   └── Responsive Rules
│
└── Media[]
    ├── Media
    ├── Media
    ├── Media
    └── ...

因此 AtDoc 描述的不是:

text
「把九張圖片合成一張圖片」

而是:

text
「將九個獨立 Media 資源,
按照指定 Layout 組成一個可渲染的媒體版面。」

這使 MediaGroup 可以成為 AtDoc 的通用語義結構,並在未來擴展至 Gallery、Video Grid、Interactive Media、Responsive Layout 與第三方 Renderer。