iT邦幫忙

2026 iThome 鐵人賽

DAY 13
0
Software Development

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

Day 13|從單選走到框選與多選

  • 分享至 

  • xImage
  •  

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

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

版本說明:本文採用進階編排功能與位置鎖定都已具備的穩定版本。

單一物件的選取只要記住一個 ID;開始框選後,卻同時出現兩種狀態:哪些物件被選到,以及框選動作目前走到哪裡。若把它們都寫進簡報文件,重新整理後會留下不該保存的操作痕跡。

選取狀態只保存 ID

編輯器把 selectedElementIds 放在元件 state,真正的物件則從目前投影片推導:

const selectedElements = activeSlide.elements.filter(
  (element) => selectedElementIds.includes(element.id),
)

這樣文件只保存投影片內容,選取、框選起點與預覽框都是暫時介面狀態。從投影片依 ID 推導出的 selectedElements 會保留物件順序,後面的群組、對齊與圖層操作都可重用同一份集合。

框選判斷的是矩形是否相交

只有從空白畫布按下主要按鍵才開始框選。程式先用畫布目前比例把游標換回邏輯座標,再把起點與目前位置正規化成左、上、右、下四條邊。物件只要和框選矩形有面積重疊便命中:

const hitElements = activeSlide.elements.filter((element) =>
  element.x < bounds.right &&
  element.x + element.width > bounds.left &&
  element.y < bounds.bottom &&
  element.y + element.height > bounds.top,
)

這不是「整個物件必須包進框內」的規則。按住 Shift、Ctrl 或 Cmd 時,命中 ID 會和既有選取集合合併;沒有輔助鍵則先清空原選取。框選期間使用 Pointer Capture,所以游標離開畫布內容區仍能完整結束操作。

https://ithelp.ithome.com.tw/upload/images/20260923/20182759f6L6R96fyj.png

框選後,編輯器會同時選取兩個物件,並提供群組、對齊與圖層操作。

位置鎖定是要保存的資料

選取本身不保存,但 positionLocked 必須跟著物件存入文件:使用者重開簡報後,鎖定仍要有效。鎖定後,屬性面板欄位和控制點會停用;reducer 也會拒絕 movetranslateset-frame 與批次 frame 更新,避免只靠按鈕停用卻被快捷鍵繞過。

介面測試以 800 × 450 的顯示畫布框選兩個物件,確認顯示「已選取 2 個物件」;另一個測試鎖定文字框後按方向鍵,X 座標仍維持 180。這同時驗證框選和鎖定不是只有視覺效果。

下一篇會把多選的物件以同一個 groupId 關聯,讓一次拖曳成為一筆完整的群組移動。

參考資料


上一篇
Day 12|用屬性面板調整座標與文字樣式
系列文
從零打造網頁簡報編輯器13
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言