[英]How to draw a circle that stays in the center of a leaflet.js map
如何绘制一个位于 leaflet.js map 中心的圆? 例如,圆的半径为 1 公里。 无论用户如何平移,我都希望绘制圆圈并保持在图像的中心。 如果用户缩放,圆圈应该相应地改变大小。
我想知道我是否必须在 leaflet 之外执行此操作并创建另一个 canvas 还是有简单的方法来完成此操作?
监听 map 上的move
事件。
var circle = L.circleMarker(mymap.getCenter(), {
radius: 50,
color: 'red',
fillOpacity: 0.2,
}).addTo(mymap);
mymap.on('move',function(e){
circle.setLatLng(mymap.getCenter());
mymap._renderer._update();
});
您也可以添加scrollWheelZoom: 'center'
以始终按圆圈缩放。
L.map('mapid',{scrollWheelZoom: 'center'})
Falke Design 接受的答案很好而且非常直接,但它使用 L.Map 私有方法(未记录)。
更通用的解决方案是:
这是一个示例: https://yafred.github.io/leaflet-tests/20200412-draw-circle-in-the-middle-of-the-map/
这是代码:
<!DOCTYPE html>
<html>
<head>
<title>Quick Start - Leaflet</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.2/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.0.2/dist/leaflet.js"></script>
<style>
#center {
visibility: hidden;
top: -215px;
left: 285px;
height: 30px;
width: 30px;
border-radius: 50%;
opacity: 0.4;
background-color: blue;
z-index: 650;
position: relative;
}
</style>
</head>
<body>
<div style="width: 600px; height: 400px; overflow: hidden">
<div id="map" style="width: 600px; height: 400px;"></div>
<div id="center"></div>
</div>
<p>Zoom in or out.</p>
<p>The circle is redrawn to have a 1km diameter.</p>
<div id="events">
</div>
<script>
var map = L.map('map').setView([48.858475, 2.338285], 13);
L.tileLayer('//a.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="//www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
L.control.scale().addTo(map);
// Map event handlers
function zoomEnd(e) {
var widthMeters = map.distance(map.getBounds().getNorthWest(), map.getBounds().getNorthEast());
var widthPixels = map.getSize().x;
var heightPixels = map.getSize().y;
var radiusPixels = Math.round(1000 * widthPixels / widthMeters);
// change style
document.getElementById('center').style.height = 2*radiusPixels + 'px';
document.getElementById('center').style.width = 2*radiusPixels + 'px';
document.getElementById('center').style.left = (Math.round(widthPixels/2) - radiusPixels) + 'px';
document.getElementById('center').style.top = '-' + (Math.round(heightPixels/2) + radiusPixels) + 'px';
document.getElementById('center').style.visibility = "visible";
// log
document.getElementById('events').innerHTML += 'zoom ' + map.getZoom() + '<br/>';
document.getElementById('events').innerHTML += 'width in meters ' + Math.round(widthMeters) + '<br/>';
document.getElementById('events').innerHTML += 'width in pixels ' + widthPixels + '<br/>';
document.getElementById('events').innerHTML += 'radiusPixels ' + radiusPixels + '<br/>';
document.getElementById('events').innerHTML += 'top ' + (0 - Math.round(heightPixels/2) + radiusPixels) + '<br/>';
}
function zoomStart(e) {
document.getElementById('events').innerHTML = '';
document.getElementById('center').style.visibility = "hidden";
}
map.on('zoomstart', zoomStart);
map.on('zoomend', zoomEnd);
centerEventDispatcher = function(e) {
new_e = new e.constructor(e.type, e);
document.getElementById("map").dispatchEvent(new_e);
}
document.getElementById("center").addEventListener("mousedown", centerEventDispatcher);
document.getElementById("center").addEventListener("mouseup", centerEventDispatcher);
document.getElementById("center").addEventListener("mousemove", centerEventDispatcher);
// initial circle
zoomEnd();
</script>
<!-- analytics -->
<script>
if(window.location.hostname != "localhost") {
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-21317761-7', 'auto');
ga('send', 'pageview');
}
</script>
</body>
</html>
YaFred 的方法很好,但是通过使用新的pointer-events: none;
圆圈上的 css 属性。
所以基本上:
.radius-circle {
border-radius: 50%;
opacity: 0.4;
background-color: blue;
z-index: 650;
position: relative;
height: 160px;
width: 158px;
left: 220px;
top: -280px;
pointer-events: none;
}
注意负上边距将其拉到 map 上方,并设置指针事件以使鼠标事件通过。
这基本上就是您需要做的所有事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.