iT邦幫忙

2026 iThome 鐵人賽

DAY 15
0
Software Development

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

Day 15|拖曳吸附參考線如何計算

  • 分享至 

  • xImage
  •  

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

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

版本說明:本文描述第一版以未旋轉矩形外框計算的吸附規則。

自由拖曳讓物件容易靠近,卻很難剛好對齊。吸附功能不能只比較游標位置:使用者看的是物件的左、中、右與上、中、下是否對齊,群組移動時還必須把整組當成一個外框。

先限制在畫布,再尋找最近錨點

constrainAndSnapMove 先算出選取集合的外框,將原始位移限制在 1600 × 900 邏輯畫布內。接著建立兩組目標:畫布的左、中、右與上、中、下,以及其他物件的對應三個錨點。

const xTargets = [0, canvas.width / 2, canvas.width].concat(
  otherElements.flatMap((element) => [
    element.x,
    element.x + element.width / 2,
    element.x + element.width,
  ]),
)

移動外框也取左、中、右三個值,逐一比較與所有目標的差距。只有差距不超過 10 個邏輯單位,才採用絕對值最小的 offset。X、Y 分開吸附;套用 offset 後再限制一次,確保吸附不會把物件推出畫布。

參考線只是預覽狀態

函式回傳兩種結果:真正要提交的 delta,以及可能的 guides。畫面把 guides.x、guides.y 畫成垂直或水平線;放開或取消拖曳時,兩者都清空。參考線不寫進文件,重新整理後不會留下過期的輔助線。

https://ithelp.ithome.com.tw/upload/images/20260925/20182759iWfH7yZQBN.png

拖曳物件接近畫布中心時,編輯器顯示水平與垂直的暫時吸附參考線。

純函式測試有一個具體例子:寬度 100、起點 X 為 100 的物件收到 (295, -95) 位移時,結果被修正成 (300, -100),並回傳 { x: 500, y: 0 }。它剛好對齊另一個物件的 X=500 與畫布頂端。

縮放下仍以邏輯座標決定結果

拖曳事件在進入吸附函式前,已先除以目前畫布比例。因此 50%、100%、125% 都會得到相同的邏輯座標與對齊結果。第一版的 10 單位門檻同樣是邏輯單位,所以畫面上的可吸附距離會隨縮放改變:50% 約為 5 個螢幕像素,125% 約為 12.5 個像素。這是刻意保留的簡化;若未來希望手感固定,可把目標螢幕像素門檻除以 scale。

目前規則只使用未旋轉的外框。旋轉後的視覺邊界需要另一套幾何計算,不能假裝仍然完全準確。

參考資料


上一篇
Day 14|群組物件為什麼必須一起移動
下一篇
Day 16|對齊、平均分布與快速版型
系列文
從零打造網頁簡報編輯器 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言