OpenPress

Slides

建立簡報

使用 OpenPress 建立可移植的 slide workspace:Press marker、template registry、slide source、theme,以及 core Object API。

OpenPress 的 slide workspace 不是由大型 layout wrapper 組成。新的方向是:先建立可複製的 template,再由 CLI 或 Workbench 依 template 複製出新的 slide source。

Template 內部應使用 SlideFrameTextLineMediaObject 等 core objects 組裝。視覺樣式放在 theme CSS;可編輯內容放在 Text children;固定位置使用 box;需要排列約束時使用 Frame layout

步驟 1:初始化 Workspace

npm create @open-press@latest <project-name> -- --type slides

這會建立一個 slide Press,預設 page geometry 為 16:9。OpenPress 的 slide coordinate system 以 1920 x 1080 為基準。

步驟 2:Press 只註冊 slide marker

press/<slug>/press.tsx 應維持簡單:它描述 deck 順序,不承載每張 slide 的實際 layout。

import { Press, Slide } from "@open-press/core";

export default function SlidePress() {
  return (
    <Press slug="slide" title="Deck Title" type="slides" page="slide-16-9">
      <Slide id="cover" />
      <Slide id="agenda" />
      <Slide id="statement" />
    </Press>
  );
}

步驟 3:用 template 建立 slide

Template 由 press/<slug>/slide-style/manifest.json 註冊。新增 slide 時,CLI 會從 slide-style/templates/<template>/ 複製基礎檔案到 slides/<id>/

node packages/core/engine/cli.mjs slide . add intro --press slide --template cover

常見結構:

press/slide/
  press.tsx
  theme/default.css
  slide-style/
    manifest.json
    theme/default.css
    templates/
      cover/slide.tsx
      agenda/slide.tsx
  slides/
    intro/slide.tsx

slide-style/theme/default.css 是 template package 的來源樣式;新增或同步到 workspace 後,實際 deck 會使用 press/<slug>/theme/default.css

步驟 4:撰寫 slide source

Slide source 應直接使用 core objects,而不是把內容藏在抽象 wrapper 的 props 裡。

import { Frame, Line, Slide, Text } from "@open-press/core";

export default function CoverSlide() {
  return (
    <Slide id="cover" className="op-source-deck-slide">
      <Frame frameKey="canvas" chrome={false} className="op-source-deck-canvas">
        <Text as="p" label="date" box={{ x: 100, y: 80 }} className="op-source-deck-date">
          26 JUNE 2024
        </Text>
        <Text as="h1" label="title" box={{ x: 100, y: 360, w: 1155 }} className="op-source-deck-title">
          A line is length without breadth.
        </Text>
        <Line label="red-rule" box={{ x: 100, y: 774, w: 270, h: 4 }} className="op-source-deck-red-rule" />
      </Frame>
    </Slide>
  );
}

步驟 5:驗證

npm run build

開發時可使用 Workbench 預覽:

npm run dev:workspace

更多物件定位、labelboxFrame layout 規則請參考 Core Object API