Leaflet – Changing Label Position Based on Circle Marker Radius

labelingleafletmarkers

I have a circle marker var circle = L.circleMarker(latLngCoords, { radius: 5, weight: 1, color: 'black' }).addTo(map); that changes the radius based on the map zoom:

map.on('zoomend', function (e) {
     var newRadius = map.getZoom() > 6 ? map.getZoom() * 2 : 5;
     circle.setRadius(newRadius);
});

I've tried to add a small label on the side of the circle (next to the circle line)

var circleText = L.marker(latLngCoords, {
icon: L.divIcon({
    html: '<div class="txt">' + myText + '</div>',
    className: 'circle-with-txt',
    iconSize: [40, 40]
})
});

.circle-with-txt {
position: relative;
color: white;
font-size: 12px;
font-weight: bold;
width: 40px;
height: 40px;
}

.txt {
    margin: 0;
    position: absolute;
    top: 50%;
    left: 50%;
    -ms-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
    font-size: 16px;
}

but when the circle marker radius changes the labels remain in the same area.

Is there a way to keep the label position relative to the circle marker (close to the circle line), even if the circle changes its radius?

Edit: I'm trying to achieve something like

this

that keeps the small label position related to the circle even if the circle radius changes on map zoom.

Best Answer

Simple way of achieving what you want would be using permanent marker tooltip for marker label, with horizontal offset equal to marker radius. Upon zoomend marker tooltip is redefined with new offset.

To have plain label without tooltip style, custom style have to be used. To have label at 45 degrees, some Cartesian math have to be applied to offset.

Code could then look something like this (tested).

CSS

.marker-label {
  background-color: transparent;
  padding: 0px;
  border: none;
  box-shadow: none;
  margin-left: 0px !important;
}
.marker-label:before {
  border-right-color: transparent !important;
}

JS:

function markerRadius() {
  return(map.getZoom() > 15 ? 24 : 12);
}

function markerLabel(marker, txt) {
  var radius = marker.getRadius() + 4;
  var offset = Math.sqrt((radius**2)/2);
  marker.bindTooltip(txt, {
    direction: 'right',
    offset: L.point(offset, -offset),
    className: 'marker-label',
    permanent: true
  });
}

var circleMarker = L.circleMarker([-37.7612, 175.2856], {
  color: "#f00",
  radius: markerRadius()
}).addTo(map);
markerLabel(circleMarker, "Hello World!");

map.on('zoomend', function (e) {
  var newRadius = markerRadius();
  circleMarker.setRadius(newRadius);
  var txt = circleMarker.getTooltip().getContent();
  markerLabel(circleMarker, txt);
});