Tuesday 26 April 2016

leaflet - Zoom marker text when zooming map


I am trying to have multiple labels on a non-geographic map (image), but when I zoom in and out, I would like the text to grow and shrink in size corresponding to the zooming.


Here is what I have:


JS


 var mapExtent = [0.00000000, -16384.00000000, 16384.00000000, 0.00000000];
var mapMinZoom = 0;

var mapMaxZoom = 6;
var mapMaxResolution = 1.00000000;
var mapMinResolution = Math.pow(2, mapMaxZoom) * mapMaxResolution;;
var tileExtent = [0.00000000, -16384.00000000, 16384.00000000, 0.00000000];
var crs = L.CRS.Simple;
crs.transformation = new L.Transformation(1, -tileExtent[0], -1, tileExtent[3]);
crs.scale = function(zoom) {
return Math.pow(2, zoom) / mapMinResolution;
};
crs.zoom = function(scale) {

return Math.log(scale * mapMinResolution) / Math.LN2;
};
var layer;
var map = new L.Map('map', {
maxZoom: mapMaxZoom,
minZoom: mapMinZoom,
crs: crs
});



layer = L.tileLayer('{z}/{x}/{y}.png', {
minZoom: mapMinZoom,
maxZoom: mapMaxZoom,
noWrap: true,
tms: false,

}).addTo(map);
map.fitBounds([
crs.unproject(L.point(mapExtent[2], mapExtent[3])),
crs.unproject(L.point(mapExtent[0], mapExtent[1]))

]);
L.control.mousePosition().addTo(map)


var yx = L.latLng;
var xy = function(x, y) {
if (L.Util.isArray(x)) { // When doing xy([x, y]);
return yx(x[1], x[0]);
}
return yx(y, x); // When doing xy(x, y);

};


L.marker(xy(-5213, 57.0), {
icon: L.divIcon({
className: 'text-labels',
html: 'Testing a long sentence here'
}),
}).addTo(map);
L.marker(xy(-3213, 57.0), {

icon: L.divIcon({
className: 'text-labels',
html: 'Image 2'
}),
}).addTo(map);
L.marker(xy(-5213, -1057.0), {
icon: L.divIcon({
className: 'text-labels',
html: 'Image 3'
}),

}).addTo(map);
L.marker(xy(-10213, 3057.0), {
icon: L.divIcon({
className: 'text-labels',
html: 'Image 4'
}),
}).addTo(map);
L.marker(xy(10213, -5057.0), {
icon: L.divIcon({
className: 'text-labels',

html: 'Image 5'
}),
}).addTo(map);

CSS


html,
body {
width: 100%;
height: 100%;
margin: 0;

padding: 0;
}

#slider {
position: absolute;
top: 10px;
right: 10px;
z-index: 5;
}


#map {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
top: 0;
z-index: 0;
background: none;
}


.text-labels {
font-size: 1em;
font-weight: 700;
cursor: grab;
white-space: nowrap;
}

Here is a fiddle



Answer




One way to achieve this is to change font size of .text-labels CSS class dynamically at the end of each zoom.


To change font size of .text-labels CSS class relevant style is needed. I once found function getStyle on Stack Overflow (forgoten where) that does just that: gets style object for given CSS class. Probably overkill in this case, but it works.


From here on it's easy: just use map zoomend event to dynamically change font size at the end of each zoom. Relation between zoom and font size is then just matter of formula, which can be any.


Code (which goes to the end) then looks like this:


// Function to get style of select CSS class
function getStyle(ruleClass) {
for (var s = 0; s < document.styleSheets.length; s++) {
var sheet = document.styleSheets[s];
if (sheet.href == null) {
var rules = sheet.cssRules ? sheet.cssRules : sheet.rules;

if (rules == null) return null;
for (var i = 0; i < rules.length; i++) {
if (rules[i].selectorText == ruleClass) {
return rules[i].style;
}
}
}
}
return null;
}


var markerTextStyle = getStyle('.text-labels');

// Set font size for givem zoom
function setMarkerTextSize(zoom) {
markerTextStyle.fontSize = 12 + ((zoom - 1) * 4) + 'px';
}

// Set inital font size
setMarkerTextSize(map.getZoom());


map.on('zoomend', function(e) {
setMarkerTextSize(map.getZoom());
});

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...