iT邦幫忙

2026 iThome 鐵人賽

DAY 19
0
Software Development

從零打造網頁簡報編輯器系列 第 19 篇

Day 19|用同一套渲染器加入圖形與箭頭

  • 分享至 

  • xImage
  •  

系列:一張投影片背後的工程:從零打造網頁簡報編輯器

對應程式版本:Git tag v0.4.0

版本說明:本文記錄矩形、橢圓、線段與箭頭共用資料模型與渲染元件的第一版。

加入圖形時,最容易形成兩套實作:編輯畫布畫一套,縮圖、播放與 PDF 再各畫一套。功能剛完成時看不出差異,之後調整顏色、線寬或箭頭造型,畫面就可能開始不一致。

先把圖形保存成資料

文件只記錄圖形種類、位置、尺寸與樣式,不保存 JSX 或 DOM:

export type ShapeKind = 'rectangle' | 'ellipse' | 'line' | 'arrow'

export interface ShapeElement extends ElementFrame {
  type: 'shape'
  shape: ShapeKind
  style: { fill: string; stroke: string; strokeWidth: number }
}

矩形與橢圓(選單中的「圓形」)預設為 360 × 220;線段(選單中的「直線」)與箭頭則使用較寬、較低的 420 × 80 frame。它們仍是一般投影片物件,因此選取、拖曳、調整大小、群組與圖層排序都能沿用既有流程。

編輯與輸出共用 ShapeGraphic

ShapeGraphic 只負責依資料畫出圖形。矩形與橢圓都用背景色和邊框繪製,橢圓只多了 border-radius: 50%;線段與箭頭則在 frame 的垂直中央畫一條水平線,粗細等於線寬,箭頭再加上由 CSS 邊框形成的三角形尖端。

互動畫布由 ShapeElementView 包住 ShapeGraphic,加入選取框與拖曳控制;靜態的 SlideRenderer 也直接使用同一個元件:

if (element.type === 'shape') {
  return (
    <div key={element.id} className="static-slide-element" style={frameStyle}>
      <ShapeGraphic element={element} />
    </div>
  )
}

縮圖、播放與列印都走 SlideRenderer,所以圖形外觀只需要維護一處。編輯介面的控制點仍留在外層,不會出現在播放或 PDF。

兩條路徑有一處不同:不透明度套用的位置。CSS 的 opacity 會連同子元素一起變淡,所以編輯畫布把它套在內層的 .element-visual,外層的選取框與控制點維持清楚;靜態渲染器沒有控制點,直接寫在物件外框的樣式上。圖形本身在兩邊呈現的透明度相同。

用操作測試確認它仍是一般物件

介面測試先從「新增圖形」加入矩形,和文字一起群組後按 Ctrl+D 建立副本,再複製貼上;另一個測試加入箭頭,框選文字與箭頭後剪下,貼到新的投影片。這些測試不只確認圖形能出現,也確認它能走過既有的多選與文件更新流程。

第一版的線段與箭頭只能水平,也不會連接到其他物件。箭頭尖端固定是寬 22、高 28 的 CSS 三角形,不會跟著線寬縮放:線寬超過 28 時線會比尖端還粗,設為 0 時線條消失、尖端仍在。線段與箭頭也只使用「外框」顏色與「外框寬度」,面板上的「填滿」對它們沒有作用。這幾點到 v0.15.0 仍未調整。

回頭看,共用資料與渲染路徑的效果在 v0.6.0 加入旋轉時最明顯:縮圖、播放與 PDF 只在 SlideRenderer 的 frame 樣式多了一行 transform,ShapeGraphic、PresentationMode 與 PrintDocument 都沒有修改;編輯畫布的三種物件元件也各只多一行。水平線旋轉之後,就能畫出斜線或垂直線。

參考資料


上一篇
Day 18|用穩定順序處理物件圖層
系列文
從零打造網頁簡報編輯器 共 19 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言