UNPKG

leaflet

Version:

JavaScript library for mobile-friendly interactive maps

92 lines (70 loc) 2.69 kB
import {Map} from '../Map.js'; import {Handler} from '../../core/Handler.js'; import * as DomEvent from '../../dom/DomEvent.js'; /* * Handler.ScrollWheelZoom is used by Map to enable mouse scroll wheel zoom on the map. */ // @namespace Map // @section Interaction Options Map.mergeOptions({ // @section Mouse wheel options // @option scrollWheelZoom: Boolean|String = true // Whether the map can be zoomed by using the mouse wheel. If passed `'center'`, // it will zoom to the center of the view regardless of where the pointer was. scrollWheelZoom: true, // @option wheelDebounceTime: Number = 40 // Limits the rate at which a wheel can fire (in milliseconds). By default, the // user can't zoom via wheel more often than once per 40 ms. wheelDebounceTime: 40, // @option wheelPxPerZoomLevel: Number = 60 // How many scroll pixels (as reported by [DomEvent.getWheelDelta](#domevent-getwheeldelta)) // mean a change of one full zoom level. Smaller values will make wheel-zooming // faster (and vice versa). wheelPxPerZoomLevel: 60 }); export class ScrollWheelZoom extends Handler { addHooks() { DomEvent.on(this._map._container, 'wheel', this._onWheelScroll, this); this._delta = 0; } removeHooks() { DomEvent.off(this._map._container, 'wheel', this._onWheelScroll, this); clearTimeout(this._timer); } _onWheelScroll(e) { const delta = DomEvent.getWheelDelta(e); const debounce = this._map.options.wheelDebounceTime; this._delta += delta; this._lastMousePos = this._map.pointerEventToContainerPoint(e); if (!this._startTime) { this._startTime = +new Date(); } const left = Math.max(debounce - (+new Date() - this._startTime), 0); clearTimeout(this._timer); this._timer = setTimeout(this._performZoom.bind(this), left); DomEvent.stop(e); } _performZoom() { const map = this._map, zoom = map.getZoom(), snap = this._map.options.zoomSnap ?? 0; map._stop(); // stop panning and fly animations if any // map the delta with a sigmoid function to -4..4 range leaning on -1..1 const d2 = this._delta / (this._map.options.wheelPxPerZoomLevel * 4), d3 = 4 * Math.log(2 / (1 + Math.exp(-Math.abs(d2)))) / Math.LN2, d4 = snap ? Math.ceil(d3 / snap) * snap : d3, delta = map._limitZoom(zoom + (this._delta > 0 ? d4 : -d4)) - zoom; this._delta = 0; this._startTime = null; if (!delta) { return; } if (map.options.scrollWheelZoom === 'center') { map.setZoom(zoom + delta); } else { map.setZoomAround(this._lastMousePos, zoom + delta); } } } // @section Handlers // @property scrollWheelZoom: Handler // Scroll wheel zoom handler. Map.addInitHook('addHandler', 'scrollWheelZoom', ScrollWheelZoom);