指數縮放讓滾輪手感平滑

縮放倍率用 scale *= exp(-deltaY * k) 取代 scale += deltaY * k,每次滾輪改變的是「乘以幾倍」而不是「加多少」,讓使用者在大倍率跟小倍率下手感一致。

做法

const zoomFactor = Math.exp(-e.deltaY * 0.0015)
const nextScale  = Math.min(MAX_SCALE, Math.max(MIN_SCALE, vp.scale * zoomFactor))

deltaY > 0(往下滾)→ zoomFactor < 1 → 縮小;反之放大。

為什麼線性縮放不行

scale += 0.1

  • scale = 0.2 時加一格變 0.3(+50%),畫面跳一大塊
  • scale = 5.0 時加一格變 5.1(+2%),幾乎沒感覺

人對縮放的感受是「比例」不是「絕對量」,所以縮放要乘不要加。

指數的好處

scale * exp(-deltaY * k)

不管目前 scale 多少,每滾一格都是「乘以同一個倍率」(例如每格 × 1.0075),視覺上每格放大的「感覺」一致。同樣的數學模型也用在音量控制(dB)、相機光圈、地圖縮放級別。

常數選擇

  • k = 0.0015 在一般滑鼠滾輪(deltaY ≈ ±100/格)下,每格約 ±15%,手感舒適
  • 觸控板 deltaY 很小(每像素一個事件),同一公式也通用,會變成連續滑順縮放

相關