圖形編輯器:場景坐標、視口坐標以及它們之間的轉換
大家好,我是前端西瓜哥。
圖形編輯器的坐標系有兩種。
一個是場景(scene)坐標系,一個是 視口(viewport)坐標系。視口就是場景的一個子區(qū)域。
假設我們的視口的原點,離場景原點的坐標水平和垂直距離分別為 scrollX 和 scrollY。
先 不考慮縮放,假設我們在視口坐標上的某個地方點擊了一下,這個坐標是 ??(x, y)?
?。這個坐標在場景坐標系中,就是:
挺簡單。
視口坐標轉換為場景坐標
下面我們引入畫布縮放,即畫布可以縮小和放大,對應的一個比例值 zoom。
視口中的某個坐標 (x, y) 在場景坐標系,則是 :
之所以要用 x 除以 zoom,是因為此時視口中展示的是縮放后的圖形,里面的坐標都是縮放后的值。所以需要先轉換為 zoom 值為 1 對應的真實值。
場景坐標轉換為視口坐標
然后我們反過來,如何從場景坐標 (x, y) 轉換為視口坐標?將前面的公式做等式變換即可:
我們通常是使用按鍵加滾輪的方式讓畫布以光標為中心進行縮放,或按按鈕進行縮放,
為了讓縮放后的場景還能對上縮放前光標的位置,我們需要計算縮放后的 scrollX 和 scrollY,進行校準。
核心思路是 保持縮放前點到視口左上角距離(視口坐標系)相同。
再說點別的。
可能會有這么一種情況,就是實際的視口區(qū)域的原點坐標有一些偏移,偏移了 offsetX 和 offsetY,見下圖。
我們只需要將前面代碼中的 scrollX 變成 (scrollX + offsetX),scrollY 變成 (scrollY + offsetY),其他不變。
就這些了。
總結一下,視口坐標是場景坐標平移并縮放后的結果,所以視口轉場景,需要除以 zoom 再加上偏移值。在圖形編輯器中,會有相當多的坐標系轉換邏輯,這兩個坐標系的關系需要好好消化理解。