Atlaslog
Atlaslog / Examples / Leaflet / Inertia
Leaflet · Runnable Example

Inertia

Runnable Leaflet example: Inertia. Open the live demo, read the complete source, and copy the file into your project. No build step or API key.

Open standalone → Chinese notes All Leaflet examples
/demos/leaflet-inertia.htmlLIVE
single HTML file · CDN dependencies onlyinterface may contain Chinese labels

Source

demos/leaflet-inertia.html
<!--
  示例:惯性拖拽
  要点:inertia / inertiaDeceleration / inertiaMaxSpeed / easeLinearity 的效果差异、松手后滑行距离测量
  依赖:Leaflet 1.9.4 · jsDelivr CDN
-->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta name="robots" content="noindex,follow">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>惯性拖拽</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.css">
<style>
  html,body{height:100%;margin:0}
  body{display:flex;flex-direction:column;overflow:hidden;
       font:13px/1.6 -apple-system,"Segoe UI","PingFang SC",sans-serif}
  .bar{flex:0 0 auto;padding:8px 12px;background:#f6f7f9;border-bottom:1px solid #e3e6ea;
       display:flex;gap:8px;align-items:center;flex-wrap:wrap;font-size:12px;color:#58606e}
  .bar button{font:inherit;font-size:12px;padding:4px 10px;border-radius:4px;cursor:pointer;
       border:1px solid #ccd1d9;background:#fff;color:#16181d}
  .bar button:hover{background:#eef0f3}
  .bar button.on{background:#1f5fd0;border-color:#1f5fd0;color:#fff}
  .bar b{color:#16181d;font-weight:600;font-variant-numeric:tabular-nums}
  .bar .sep{width:1px;height:16px;background:#dfe3e9}
  #map{flex:1 1 auto;min-height:0;background:#edf0f4}
  #log{position:absolute;left:12px;bottom:12px;z-index:600;background:rgba(22,24,29,.86);
       color:#e9edf2;font:11px/1.7 Consolas,monospace;padding:6px 9px;border-radius:5px;
       max-width:280px;pointer-events:none}
</style>
</head>
<body>
<div class="bar">
  <button data-preset="off">无惯性</button>
  <button data-preset="default" class="on">默认</button>
  <button data-preset="far">强惯性</button>
  <button data-preset="short">短滑行</button>
  <span class="sep"></span>
  <span>减速 <b id="dec">3400</b> px/s² · 上限 <b id="max">∞</b></span>
</div>
<div id="map"></div>
<div id="log">按住地图快速甩动,松手后观察滑行距离</div>
<script src="https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
(function () {
  'use strict';

  var map = L.map('map', {
    center: [39.907359, 116.391263],
    zoom: 13,
    /* 这三项是 Map 的默认值,上限默认不设,即无穷大 */
    inertia: true,
    inertiaDeceleration: 3400,
    inertiaMaxSpeed: Infinity,
    easeLinearity: 0.2
  });

  L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {
    maxZoom: 19,
    attribution: 'Tiles © Esri'
  }).addTo(map);

  L.rectangle([[39.895, 116.370], [39.920, 116.415]], {
    color: '#1f5fd0',
    weight: 1,
    fillOpacity: 0.06,
    interactive: false
  }).addTo(map);

  var decEl = document.getElementById('dec');
  var maxEl = document.getElementById('max');
  var logEl = document.getElementById('log');

  var flungFrom = null;

  map.on('dragend', function () {
    /* dragend 在松手瞬间触发,惯性动画随后开始 */
    flungFrom = map.getCenter();
  });

  map.on('moveend', function () {
    if (!flungFrom) return;
    var dist = map.distance(flungFrom, map.getCenter());
    flungFrom = null;

    if (dist < 8) {
      logEl.textContent = '松手后没有滑行,地图立即停住';
    } else {
      logEl.textContent = '惯性滑行 ' + Math.round(dist) + ' 米(z' + map.getZoom() + ')';
    }
  });

  var PRESETS = {
    off:     { inertia: false, decel: 3400, maxSpeed: Infinity, ease: 0.2, label: '无惯性' },
    default: { inertia: true,  decel: 3400, maxSpeed: Infinity, ease: 0.2, label: '默认' },
    far:     { inertia: true,  decel: 900,  maxSpeed: 3200, ease: 0.25, label: '强惯性' },
    short:   { inertia: true,  decel: 6000, maxSpeed: 600,  ease: 0.1, label: '短滑行' }
  };

  function apply(name) {
    var p = PRESETS[name];
    if (!p) return;

    /* 惯性参数在每次松手时从 map.options 读取,运行时改立即生效 */
    map.options.inertia = p.inertia;
    map.options.inertiaDeceleration = p.decel;
    map.options.inertiaMaxSpeed = p.maxSpeed;
    map.options.easeLinearity = p.ease;

    decEl.textContent = p.decel;
    maxEl.textContent = p.maxSpeed === Infinity ? '∞' : p.maxSpeed;
    logEl.textContent = '已切换到「' + p.label + '」,甩动地图后看滑行距离';
  }

  Array.prototype.forEach.call(document.querySelectorAll('[data-preset]'), function (btn) {
    btn.addEventListener('click', function () {
      Array.prototype.forEach.call(document.querySelectorAll('[data-preset]'), function (b) {
        b.classList.remove('on');
      });
      btn.classList.add('on');
      apply(btn.getAttribute('data-preset'));
    });
  });
})();
</script>
</body>
</html>
Language: the code and this page are in English; the full tutorial and API notes for this example are in Chinese. The demo itself is the authoritative version — it runs exactly as shown.

More Leaflet examples

Leaflet · EXAMPLELayer Panel Leaflet · EXAMPLEMarker Cluster Leaflet · EXAMPLEMarker