指數縮放讓滾輪手感平滑
縮放倍率用 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 很小(每像素一個事件),同一公式也通用,會變成連續滑順縮放