自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

圖形編輯器開發(fā):最基礎(chǔ)但卻復雜的選擇工具

開發(fā) 前端
選擇工具,是一款圖形設(shè)計軟件最基礎(chǔ)的功能。它的作用是選中的圖形,對它們進行操作,目的是 更新指定圖形屬性。最基礎(chǔ)的操作是移動,接著是通過控制點實現(xiàn)的增強操作。控制點操作的兩個基本能力是旋轉(zhuǎn)和縮放。然后我們會根據(jù)不同類型的圖形,去實現(xiàn)不同的控制點邏輯。

大家好,我是前端西瓜哥。

對于一個圖形設(shè)計軟件,它最基礎(chǔ)的工具是什么?選擇工具。

但這個選擇工具,卻是相當?shù)膹碗s。這次我來和各位,細說細說選擇工具的一些彎彎道道。

我正在開發(fā)的圖形設(shè)計工具:

https://github.com/F-star/suika

線上體驗:

https://blog.fstars.wang/app/suika/

單選

最基本的,要做到單個圖形的選中。

光標停留在圖形上方,按下鼠標左鍵,這個圖形就被選中了。這就是一個簡單的選中了單個圖形的場景。

注意必須是 mousedown,不是 click。后面會說為什么。

在代碼層,我們會使用 “圖形拾取” 算法確定光標落在哪個圖形的點擊區(qū)域上,注意考慮隱藏、鎖定、組的情況。

隱藏和鎖定的圖形會被忽略,如果點的是組下的一個元素,要將整個組的所有元素都選中。

清空 被選中圖形集合(暫且叫做 selectSet),然后把這個圖形添加進去。

selectSet.clear()
selectSet.add(targetEl)

選中集合保存的是被選中的圖形,可以保存 id,也可以是圖形對象。

在渲染層,會對被選中的圖形進行輪廓高亮,讓用戶有感知。

此外還會有一個 矩形選中框,上面還會有控制點,讓用戶可以縮放和旋轉(zhuǎn)圖形。

選中框是圖形的包圍盒,通常是 帶旋轉(zhuǎn)的 OBB 包圍盒。

如果點擊到空白區(qū)域,要將 selectSet 清空。

圖片

多選

有時候我們希望選中出多個圖形。

通常的做法是,按住 Shift 鍵,然后點擊一個圖形。注意是在鼠標按下時就按住

同時也要 支持取消選中:原來被選中的一個圖形,我按住 Shift 再

代碼的核心邏輯是:

如果這個圖形不在 selectSet 中,將其加入;如果這個圖形在 selectSet,將其移除。

if (event.shiftKey) {
  if (selectSet.has(targetEl)) {
    selectSet.delete(targetEl)
  } else {
    selectSet.add(targetEl)
  }
}

多個圖形被選中了,除了給它們高亮輪廓線,我們還需要用一個更大的矩形選中框包裹所有被選中圖形。

一個小點:如果是取消選中的邏輯,需要鼠標釋放后才更新 selectSet。因為要防止和后面會說的按住 Shift 水平垂直拖拽沖突。

圖片

框選

框選,提供了 一次性選中大量特定區(qū)域內(nèi)圖形 的能力。

在空白區(qū)域按下鼠標拖拽,然后釋放,可以構(gòu)造出一個矩形,這個矩形我們稱為 “選區(qū)”。

圖片

選區(qū)矩形會和圖形進行碰撞檢測判斷,決定將哪些圖形是被框選中的。

碰撞檢測有三種方案:

  1. 選區(qū)矩形和選中圖形的包圍盒屬于 包含(contain)關(guān)系;
  2. 選區(qū)矩形和選中圖形的包圍盒屬于 相交(intersect)關(guān)系;
  3. 不使用包圍盒,精準判斷是否有真正的 像素上的相交;

個人比較推薦相交的判斷方案,figma 也選擇了該方案。

框選可以和多選結(jié)合。即你可以按住 Shift 鍵,然后去框選。

它的效果是和按住 Shift 一個個去選中圖形的效果是一樣的。

核心代碼實現(xiàn):

if (!event.shiftKey) {
  selectSet.clear();
}

for (const el of elementsInScence) {
  // 判斷是否碰撞,這個方法
  if (isRectIntersect(selectionBox, el)) {
    // 普通框選
    if (!event.shiftKey) {
      selectSet.add(el);
    }
    // 連續(xù)和框選的組合
    else {
      if (selectSet.has(el)) {
        selectSet.delete(el);
      } else {
        selectSet.add(el);
      }
    }
  }
}

移動

選擇工具,主要是用來選擇,選中后一個很普遍的操作是:移動選中元素。

所以這也是它有時候也被叫做 移動工具 的原因。

移動的交互過程:

  1. 光標停留在已經(jīng)被選中的圖形上,按下鼠標不放。
  2. 然后拖拽鼠標,被選中圖形跟隨光標移動。
  3. 釋放鼠標,表示移動到目標位置,移動結(jié)束。

圖片

代碼核心實現(xiàn):

  1. 移動前此時記錄圖形的位置,和起始位置。
  2. 拖拽時計算相對位移,更新圖形的位置。
  3. 釋放時重置狀態(tài),以及記錄到歷史記錄中。
// 圖形移動前位置
let elStartCoords = [];
// 鼠標按下事件的光標位置,計算偏移量時作為基準
let startCoord = { x: undefined, y: undefined };

const onStart = (e) => {
  // 記錄初始坐標
  elStartCoords = elements.map((el) => ({ x: el.x, y: el.y }));
  startCoord.x = e.clientX;
  startCoord.y = e.clientY;
};

const onDrag = (e) => {
  // 計算偏移量,更新坐標
  const dx = e.clientX - startCoord.x;
  const dy = e.clientY - startCoord.y;
  elements.forEach((el, i) => {
    el.x = elStartCoords[i].x + dx;
    el.y = elStartCoords[i].y + dy;
  });
};

const onEnd = () => {
  // 重置狀態(tài)
  elStartCoords = [];
  startCoord = { x: undefined, y: undefined };
};

按住 Shift 鍵的垂直水平移動

假設(shè)我們做好了幾個對齊的圖形,當我們移動其中一個圖形的時候,希望能夠保持原來的對齊。

這時候,限制移動為水平或垂直方向就很有用。

通常通過在拖拽時按住 Shift 來開啟這個能力。

圖片

要點:

  1. 拖拽的中途從沒按住 Shift 到按住,要立即響應(yīng),代碼實現(xiàn)上要補一個鍵盤事件監(jiān)聽,而不是靠鼠標移動事件,因為你不移動鼠標,被選中元素就不會更新。
  2. 比較 dx 和 dy 的大小。dx 大,水平移動;dy 大,垂直移動。這樣圖形就能盡量靠近十字線(水平線+垂直線)

對齊到像素網(wǎng)格

對齊到網(wǎng)格,開啟后,讓圖形在移動的時候,讓圖片盡量貼到網(wǎng)格線上。

圖片

做法是將一個或多個圖形的包圍盒(AABB)的左上角坐標,進行取余,得到一個落在網(wǎng)格線上的位置,用這位置去更新選中圖形。

擴展能力:控制點

選中圖形,是為了對它們進行操作。

這些 操作的實現(xiàn),要通過控制點來落地。

常見的有:

  • 縮放控制點,在圖形選中框的 4 個角上。
  • 旋轉(zhuǎn)控制點,拖拽它設(shè)置圖形的旋轉(zhuǎn),旋轉(zhuǎn)控制點。
  • 給圖形設(shè)置漸變填充色,需要指定兩種顏色的顏色和位置,需要的 漸變色控制點

下面是 figma 的縮放和旋轉(zhuǎn)演示,我開發(fā)的編輯器還沒實現(xiàn)完整。

圖片

此外,不同圖形繪制工具可能會有它們獨有的操作方式,這些都需要你根據(jù)圖形的特性去設(shè)計。

看看 Figma 對不同圖形的特殊控制點邏輯。

圖片

所以選擇工具模塊在設(shè)計上,要提供 注冊各種類型圖形控制點邏輯 的能力。

在 “圖形拾取” 時,要把控制點也考慮進來,光標是否點在控制點上。

如果點在控制點上,拖拽邏輯就要走控制點的邏輯,不再走選擇工具的基礎(chǔ)邏輯。

其他

還有一些可考慮實現(xiàn)的增強能力:

  • 雙擊,進入編輯模式,進行一些更復雜的操作,比如可以變成貝塞爾曲線操作任意點。
  • 移動時,用線條顯示和其他圖形的點(比如中點、選中框角落的 4 個點)的距離,并在很接近時吸附過去。

結(jié)尾

總結(jié)一下,選擇工具,是一款圖形設(shè)計軟件最基礎(chǔ)的功能。

它的作用是選中的圖形,對它們進行操作,目的是 更新指定圖形屬性。

最基礎(chǔ)的操作是移動,接著是通過控制點實現(xiàn)的增強操作。

控制點操作的兩個基本能力是旋轉(zhuǎn)和縮放。然后我們會根據(jù)不同類型的圖形,去實現(xiàn)不同的控制點邏輯。

說是工具的一種,但它其實的定位更多是底層的基礎(chǔ)建設(shè)。

責任編輯:姜華 來源: 前端西瓜哥
相關(guān)推薦

2023-09-07 08:24:35

圖形編輯器開發(fā)繪制圖形工具

2023-10-19 10:12:34

圖形編輯器開發(fā)縮放圖形

2023-02-06 16:59:57

Canvas編輯器

2023-09-26 07:39:21

2023-08-31 11:32:57

圖形編輯器contain

2023-10-08 08:11:40

圖形編輯器快捷鍵操作

2024-01-08 08:30:05

光標圖形編輯器開發(fā)游標

2023-09-11 09:02:31

圖形編輯器模塊間的通信

2023-04-07 08:02:30

圖形編輯器對齊功能

2023-01-18 08:30:40

圖形編輯器元素

2023-02-01 09:21:59

圖形編輯器標尺

2023-08-28 08:10:50

Hex圖形編輯器

2023-10-10 16:04:30

圖形編輯器格式轉(zhuǎn)換

2023-07-07 13:56:01

圖形編輯器畫布縮放

2024-01-03 08:43:17

圖形編輯器旋轉(zhuǎn)控制點縮放控制點

2023-04-10 08:45:44

圖形編輯器排列移動功能

2023-07-31 08:46:07

圖形編輯器圖形自動對齊

2023-02-02 14:07:00

圖形編輯器Canvas

2023-08-08 08:12:25

圖形編輯器幾何算法

2023-05-09 08:15:32

圖形編輯器撤銷重做功能
點贊
收藏

51CTO技術(shù)棧公眾號