screenToWorld 與 worldToScreen 座標轉換

兩套座標互轉的公式,核心只有「平移」與「縮放」兩步。

公式

// screen → world:先扣位移,再除縮放
world.x = (screen.x - offsetX) / scale
world.y = (screen.y - offsetY) / scale
 
// world → screen:先乘縮放,再加位移
screen.x = world.x * scale + offsetX
screen.y = world.y * scale + offsetY
  • offset 是畫布被拖了多少(screen 單位)
  • scale 是縮放倍率

直覺記法

想像 viewport 對世界做了「先縮放、再平移」兩件事。要還原就反順序:先扣位移、再除縮放。

實務上常常只需要單向

事件進來時要把 clientX/Y 轉成世界座標,所以 screenToWorld 一定要實作。但「世界座標 → 螢幕」多半被外層 CSS transform 隱性處理掉了(瀏覽器幫你算),程式碼裡可能根本沒有 worldToScreen 函式。需要它的場合通常是:HUD 顯示游標目前世界座標、自動對齊輔助線、把世界中某點 scroll 到視窗中央。

範例

畫布縮放 200%、向右拖 100px:viewport = { offsetX: 100, offsetY: 0, scale: 2 }

滑鼠點在螢幕 (300, 200)

world.x = (300 - 100) / 2 = 100
world.y = (200 - 0) / 2 = 100

實際點到的是世界座標 (100, 100)。在那放一個 100×100 矩形,就存 x=100, y=100, width=100, height=100。下次畫布縮回 100% 拖回原點,矩形仍會出現在世界 (100, 100)

相關