<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.0/leaflet.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.0/leaflet.js"></script>
<title>smooth zoom demo</title>
</head>
<style>
* {
margin: 0;
padding: 0;
}
#mapid {
width: 100vw;
height: 100vh;
}
#info_container{
position: absolute;
z-index: 999;
top: 0;
left: 50%;
margin-top: 8px;
padding: 8px;
transform: translateX(-50%);
width: 200px;
height: 64px;
background: rgba(0, 0, 0, 0.8);
color: white;
text-align: center;
}
#info_container span{
font-size: 24px;
}
</style>
<body>
<div id="mapid"></div>
<div id="info_container"></div>
<script src="script.js"></script>
<script>
var mymap = L.map('mapid', {
scrollWheelZoom: false,
smoothWheelZoom: true,
smoothSensitivity: 1,
}).setView([38.0, 140.0], 13);
mymap.scrollWheelZoom = true;
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(mymap);
mymap.on("zoom", function() {
showZoom();
})
function showZoom() {
document.getElementById('info_container').innerHTML = "zoom<br/>" + "<span>" + mymap.getZoom().toFixed(2) + "</span>";
}
showZoom();
</script>
</body>
</html>
L.Map.mergeOptions({
smoothWheelZoom: true,
smoothSensitivity: 1
});
L.Map.SmoothWheelZoom = L.Handler.extend({
addHooks: function() {
L.DomEvent.on(this._map._container, 'mousewheel', this._onWheelScroll, this);
},
removeHooks: function() {
L.DomEvent.off(this._map._container, 'mousewheel', this._onWheelScroll, this);
},
_onWheelScroll: function(e) {
if (!this._isWheeling)
{
this._onWheelStart(e);
}
this._onWheeling(e);
},
_onWheelStart: function(e) {
var map = this._map;
this._isWheeling = true;
this._wheelMousePosition = map.mouseEventToContainerPoint(e);
this._centerPoint = map.getSize()._divideBy(2);
this._startLatLng = map.containerPointToLatLng(this._centerPoint);
this._wheelStartLatLng = map.containerPointToLatLng(this._wheelMousePosition);
this._startZoom = map.getZoom();
this._moved = false;
this._zooming = true;
map._stop();
if (map._panAnim) map._panAnim.stop();
this._goalZoom = map.getZoom();
this._prevCenter = map.getCenter();
this._prevZoom = map.getZoom();
this._zoomAnimationId = requestAnimationFrame(this._updateWheelZoom.bind(this));
},
_onWheeling: function(e) {
var map = this._map;
this._goalZoom = this._goalZoom - e.deltaY * 0.003 * map.options.smoothSensitivity;
if (this._goalZoom < map.getMinZoom() || this._goalZoom > map.getMaxZoom())
{
this._goalZoom = map._limitZoom(this._goalZoom);
}
this._wheelMousePosition = this._map.mouseEventToContainerPoint(e);
clearTimeout(this._timeoutId);
this._timeoutId = setTimeout(this._onWheelEnd.bind(this), 200);
},
_onWheelEnd: function(e) {
this._isWheeling = false;
cancelAnimationFrame(this._zoomAnimationId);
},
_updateWheelZoom: function() {
var map = this._map;
if ((!map.getCenter().equals(this._prevCenter)) || map.getZoom() != this._prevZoom) return;
this._zoom = map.getZoom() + (this._goalZoom - map.getZoom()) * 0.3;
this._zoom = Math.floor(this._zoom * 100) / 100;
var delta = this._wheelMousePosition.subtract(this._centerPoint);
if (delta.x === 0 && delta.y === 0) return;
if (map.options.smoothWheelZoom === 'center')
{
this._center = this._startLatLng;
}
else
{
this._center = map.unproject(map.project(this._wheelStartLatLng, this._zoom).subtract(delta), this._zoom);
}
if (!this._moved)
{
map._moveStart(true, false);
this._moved = true;
}
map._move(this._center, this._zoom);
this._prevCenter = map.getCenter();
this._prevZoom = map.getZoom();
this._zoomAnimationId = requestAnimationFrame(this._updateWheelZoom.bind(this));
}
});
L.Map.addInitHook('addHandler', 'smoothWheelZoom', L.Map.SmoothWheelZoom);
/* Styles go here */