leaflet から MapLibre への置き換えを検討している。
置き換えでぶち当たった仕様の差異の吸収方法を残しておく。
MapLibreでマウスホイールによるズームが多段階になってしまう
leafletの Map には zoomDelta オプションでズームレベルを離散的というか等間隔になる仕様がある。
そもそも、この zoomDelta のデフォルトが 1 であり、何も指定しないとズームレベルは 1 の整数倍となる。
翻って、MapLibreでは、 leafletでいう zoomDelta にあたる設定ができない・・・。
実際に動かしてみると、マウスホイールをぐりぐり動かすとズームレベルに小数が含まれてしまうことが分かった。
表面上の仕様はあまり変えたくなかったので、ズームレベルを整数倍にする方法を検討した。
解決方法1 zoomend で整数倍に強制
生成AIの回答は、zoomend 時に補正すればいいとのこと。まあ、そうなんだけど、安易じゃない?トライしてみるけどさ。
生成AI謹製コードは、単に四捨五入しただけだったけど、0.5未満の変更でズームレベルが元に戻るのが気持ち悪いので、zoomの方向を確認して切り上げか切り捨てかを決めることにした。
let zoom = map.getZoom();
map.on('zoomstart', () => {
zoom = map.getZoom();
});
map.on('zoomend', () => {
const currentZoom = map.getZoom();
if (zoom < currentZoom) {
map.setZoom(Math.ceil(currentZoom));
}
else if(this.zoom > currentZoom) {
map.setZoom(Math.floor(currentZoom));
}
});
解決方法1の 問題点
この方法には問題点がある。
それは、zoomstart から zoomend へのアニメーションがぬるっと動いた後に、アニメーションなしに整数倍のズームレベルに切り替わる不自然さがあることにある。
解決方法2 マウスホイールによるズームの速度を変更する
ScrollZoomHandler に setWheelZoomRate() というマウスホイールの単位操作幅に対する ズームレベル変化レートを指定できる。
このズームレベルの変化レートの変更は、ズームの速度の変更を目的としている。ただし、 setWheelZoomRate() の引数を 1/20 以上にすると、ブラックボックス的に見る限りでは、ズームレベルが整数倍になるようだ。(Chromeで確認)
map.scrollZoom.setWheelZoomRate(1/20);
加えて、 NavigationControl の拡大縮小も、ダブルクリックによる拡大縮小も 仕様として増分は 1 (または ―1 )で小数にはならないので、マウスホイールだけケアすれば、すべてのズームレベルは整数倍になりそう。
解決方法2の 問題点
問題点はずばり2点。
- これが正攻法の解決なのか、わからない(おそらく邪道)
- 1の整数倍以外(e.g. 0.5倍ごと)はこの方法では処理できない
node_modulesの中をざっくり見てみたけど、私の理解力では読み解けなかった。
結論
- 解決方法1 と 解決方法2を両方実装する