iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0
Software Development

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

Day 17|複製、剪下與跨投影片貼上

  • 分享至 

  • xImage
  •  

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

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

版本說明:本文記錄第一版的編輯器內剪貼簿;它可跨投影片使用,但不等同於作業系統剪貼簿。

複製物件的難點不是再放一份相同資料,而是避免 ID 重複、避免新副本錯連到舊群組,也不要把同一張圖片的二進位資料複製很多次。第一版先把範圍控制在同一個編輯器工作階段內,用 useRef 保存內部剪貼簿。

複製的是快照,不是文件中的參考

按下 Ctrl/Cmd+C 時,程式把目前選取集合做深層複製:

const copySelection = () => {
  clipboardRef.current = structuredClone(selectedElements)
}

剪下先複製,再以 element/delete-many 刪除原物件。貼上時不直接加入剪貼簿內容,而是走 duplicateElements:每個元素用 crypto.randomUUID() 產生新 ID,座標增加 24 個邏輯單位後再限制在畫布內。

文字與圖形的 style 會建立新物件;圖片保留既有 assetId,所以新副本仍引用同一份 IndexedDB 資產,而不是再存一份 Blob。

群組必須重新對應

若複製集合中有群組,不能沿用舊 groupId,否則新舊物件會被當成同一組。程式用 Map 為每個來源群組建立一個新 ID:同一來源群組的副本仍會聚在一起,不同來源群組則不會混在一起。

貼上後,內部剪貼簿更新為這一批新副本。連續貼上會每次再偏移 24 單位,使用者能看見新物件而不會完全重疊。

跨投影片的範圍與證據

全域快捷鍵支援 Ctrl/Cmd+C、X、V、D,且在文字輸入、組字或表單欄位焦點中不攔截原生行為。介面測試先框選文字與箭頭,剪下後確認原投影片沒有物件;新增投影片再貼上,確認新頁出現兩個物件。

這裡的「跨投影片」只代表同一個瀏覽器頁面、同一次編輯工作階段。重新整理、關閉分頁或貼到其他應用程式不會保留這個內部剪貼簿;若要支援系統剪貼簿,還需要處理瀏覽器權限與可攜資料格式。

參考資料


上一篇
Day 16|對齊、平均分布與快速版型
系列文
從零打造網頁簡報編輯器 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言