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