Minimap
Runnable Leaflet example: Minimap. Open the live demo, read the complete source, and copy the file into your project. No build step or API key.
single HTML file · CDN dependencies onlyinterface may contain Chinese labels
Source
<!--
示例:鹰眼图
要点:第二个 L.map 作为缩略图、主图视野矩形、双向联动、关闭缩略图交互
依赖:Leaflet 1.9.4 · jsDelivr CDN + Esri 瓦片
-->
<!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{overflow:hidden;font:13px/1.6 -apple-system,"Segoe UI","PingFang SC",sans-serif}
#wrap{position:absolute;inset:0}
#map{position:absolute;inset:0}
#mini{position:absolute;right:14px;bottom:14px;width:150px;height:110px;
z-index:700;border:2px solid #fff;border-radius:4px;
box-shadow:0 1px 8px rgba(0,0,0,.35);background:#eef0f3;cursor:pointer}
.mini-tag{position:absolute;left:0;top:0;z-index:701;padding:1px 6px;
font-size:10px;color:#fff;background:rgba(15,23,42,.65);
border-radius:3px 0 4px 0;pointer-events:none}
</style>
</head>
<body>
<div id="wrap">
<div id="map"></div>
<div id="mini"></div>
<span class="mini-tag">鹰眼</span>
</div>
<script src="https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
(function () {
'use strict';
var TILE = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}';
var map = L.map('map', {
center: [39.907, 116.391],
zoom: 13
});
L.tileLayer(TILE, {
maxZoom: 19,
attribution: 'Tiles © Esri'
}).addTo(map);
L.marker([39.907359, 116.391263], {
icon: L.divIcon({
className: '',
html: '<div style="width:14px;height:14px;border-radius:50%;background:#1f5fd0;' +
'border:2px solid #fff;box-shadow:0 0 0 1px rgba(0,0,0,.3)"></div>',
iconSize: [14, 14],
iconAnchor: [7, 7]
})
}).bindPopup('主图标记').addTo(map);
L.circle([39.907359, 116.391263], {
radius: 2000, color: '#1f5fd0', weight: 1, fillOpacity: 0.08
}).addTo(map);
/* 缩略图:关掉所有交互,只作为视图指示 */
var mini = L.map('mini', {
zoomControl: false,
attributionControl: false,
dragging: false,
scrollWheelZoom: false,
doubleClickZoom: false,
boxZoom: false,
keyboard: false,
touchZoom: false
});
mini.setView(map.getCenter(), Math.max(3, map.getZoom() - 4));
L.tileLayer(TILE, { maxZoom: 19 }).addTo(mini);
var box = L.rectangle(map.getBounds(), {
color: '#c2410c',
weight: 1.5,
fillColor: '#c2410c',
fillOpacity: 0.12,
interactive: false
}).addTo(mini);
var syncing = false;
function syncMini() {
if (syncing) return;
syncing = true;
mini.setView(map.getCenter(), Math.max(3, map.getZoom() - 4), { animate: false });
box.setBounds(map.getBounds());
syncing = false;
}
map.on('move', syncMini);
map.on('zoomend', syncMini);
/* 点击缩略图跳转主图,保留主图当前缩放 */
mini.on('click', function (e) {
map.setView(e.latlng, map.getZoom(), { animate: true });
});
/* 容器尺寸确定后再校正一次,避免首帧尺寸读到 0 */
setTimeout(function () {
mini.invalidateSize();
map.invalidateSize();
syncMini();
}, 80);
})();
</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.