系列:一張投影片背後的工程:從零打造網頁簡報編輯器
對應程式版本:Git tag
v0.4.0版本說明:本文使用物件陣列順序做為第一版的持久圖層資料,不為每個物件另存數字型 z-index。
兩個物件重疊時,誰在前面必須在編輯、縮圖、播放和 PDF 中一致。替每個物件維護可任意增加的 z-index 很容易產生空洞、重複值與重新編號問題。這個專案採用更直接的規則:slide.elements 的陣列順序就是保存的圖層順序。
共用的 SlideRenderer 依序 map 每個元素。較後面的節點在相同堆疊情境中會覆蓋較前面的節點,因此文件陣列可同時驅動縮圖、播放與列印。選取框的暫時視覺效果屬於編輯介面,不額外寫入文件圖層資料。
這種資料模型只需保存一件事:元素的相對排列,而不是保存一串可能失效的數字。它也讓備份、還原與 reducer 測試直接比較陣列順序即可。
element/reorder 支援置頂、上移一層、下移一層與置底。置頂、置底用兩次 filter 合併陣列,選取集合內的順序保持不變:
if (direction === 'front') {
return [
...elements.filter((element) => !selected.has(element.id)),
...elements.filter((element) => selected.has(element.id)),
]
}
上移一層從右往左交換,下移一層從左往右交換。反向迴圈很重要:例如 [A, B, C, D] 中選取 B、C 後上移,結果是 [A, D, B, C];B、C 沒有彼此交換順序,也各自只跨過一個未選取物件。
測試先建立文字、矩形、橢圓三個元素,將文字與矩形群組後置頂。預期順序為 shape-2、text-1、shape-1,群組內原本的文字在矩形前方仍然成立。若命令不會造成順序改變,reducer 回傳原本文件,避免無意義的歷史紀錄和儲存。
目前的限制是每張投影片只有單一扁平圖層序列。未來若加入真正的巢狀群組或遮罩,再評估是否需要更複雜的堆疊模型;第一版不先引入它。