Ответ 1
Чтобы ответить на точный вопрос OP, то есть, как изменить положение часов при изменении размера окна браузера (возможно, размеры картографического контейнера могли быть изменены), следует, вероятно, просто пересчитать положение часов на карте "resize"
.
Однако неясно, помещало ли OP часы в качестве дочернего элемента контейнера карты или где-то еще на дереве DOM страницы.
Вероятно, гораздо проще разместить его как дочерний элемент карты, так что его положение всегда относительно контейнера карты.
Что первоначально запросил ОП?
Если я правильно понял исходный желаемый результат, OP хотел бы наложить часы (или любую другую информацию) поверх определенного географического положения (город Торонто в этом случае [UTC -5], согласно комментариям).
Однако информационный контейнер не должен лежать в фиксированной позиции базовой карты, то есть не в точном географически скоординированном пункте (например, маркером или всплывающим окном), а в верхней части контейнера карты, аналогично элементу управления (следовательно, iH8 оригинальный ответ).
За исключением того, что он не должен полностью фиксироваться в контейнере карты, но горизонтально перемещаться с городом (или любыми указанными географическими координатами). Следовательно, комментарий OP для ответа iH8.
Поэтому это похоже на нечто похожее на на этот сайт, за исключением интерактивной (навигационной) карты и заголовка "UTC-5" заменяется на часы (или любую другую информацию, поэтому контейнер HTML должен это делать) и горизонтально следуя за Торонто.
По-другому, часы должны сидеть на определенной вертикальной линии, то есть долготе/меридиане.
К сожалению, даже спустя 2 года после того, как вопрос отправлен, до сих пор нет плагина Leaflet, который обеспечивает такую функциональность (по крайней мере, в Страница плакатов лифтов).
Расширение прецедента к карте с большим увеличением...
При этом и учитывая тот факт, что пользователь может значительно увеличить масштаб города (OP не указала максимальный уровень масштабирования), это может быть не очень хороший пользовательский опыт, когда эти часы горизонтально следуют за точным долгота: например, он мог отслеживать центроид/мэрию Торонто/любое конкретное место, а когда пользователь был увеличен в другом районе города, часы больше не видны, тогда как он/она все еще просматривает часть города Торонто...
Чтобы расширить этот прецедент, часы, вероятно, должны быть видимы в любой области, в которой он применяется, т.е. как только порт отображения карты пересечет связанный часовой пояс.
Расширение прецедента на карте с большим увеличением...
Еще один пункт, не описанный OP, заключается в том, что делать, если в порт просмотра карты видны места разных часовых поясов? В вышеупомянутом сайте у нас есть один заголовок в видимый часовой пояс, который, кажется, наиболее полная информация, которую мы можем получить.
Но поскольку Leaflet позволяет уменьшить масштаб до уровня 0, где весь мир (т.е. по существу 24 часовых пояса /фактически 39 согласно Википедии, не включая потенциальный эффект перехода на летнее время - DST) представлена с шириной в 256 пикселей, для всех этих часов мало места, если каждый из них должен быть выровнен по вертикали с соответствующим часовым поясом.
Теперь предположим, что нам все равно, перекрываются ли часы.
Еще больше пользовательских случаев...
Но OP, возможно, пожелал отображать часы только для определенных мест, а не для всего мира. ОП даже не сказал, что часы будут разными (у нас могут быть часы для городов в одном и том же часовом поясе, хотя было бы интереснее, чтобы эти часы сидели рядом с их городом - даже наравне с их широтой, так что легче определить, с каким городом связаны часы, как в случае двух городов на одном и том же меридиане, но в этом случае маркера с L.divIcon
будет достаточно).
Следовательно, обычным случаем было бы не рассматривать официальные часовые пояса, а определенные разработчиком области.
Итак, мы забываем о широте и стараемся выровнять часы по вертикали над областью, пока она пересекает порт отображения карты.
Описание общего решения
Поэтому это похоже на то, что универсальное решение должно позволить разработчику приложения указать массив элементов HTML, каждый из которых связан с диапазоном долгот (также может быть областью/полигоном).
Случай с часовыми поясами будет тогда конкретным случаем, когда указанные области - это просто те из часовых поясов.
Затем каждый элемент должен быть видимым тогда и только тогда, когда его связанная область пересекает порт представления (поэтому мы вводим возможность скрыть его, когда диапазон широты выходит из поля зрения).
Что касается позиционирования, то выберите:
- В верхней части контейнера карты (аналогично элементу управления), как указано OP.
- Горизонтально центрируется в пределах пересечения порта представления и связанной области.
HTML:
<div id="map"></div>
<div id="clockToronto" class="clock leaflet-control">Clock here for Toronto</div>
<div id="clockBurlington" class="clock leaflet-control">Clock here for Burlington</div>
CSS
.clock {
width: 150px;
text-align: center;
position: absolute;
border: 1px solid black;
}
#clockToronto {
background-color: yellow;
}
#clockBurlington {
background-color: orange;
}
JavaScript:
var map = L.map("map").setView([43.7, -79.4], 10);
// Application specific.
var clockTorontoElement = L.DomUtil.get("clockToronto"),
clockBurlingtonElement = L.DomUtil.get("clockBurlington"),
zones = [
{
element: clockTorontoElement, // Using the HTML Element for now.
width: parseInt(window.getComputedStyle(clockTorontoElement, null).getPropertyValue("width"), 10),
area: L.latLngBounds([43.58, -79.64], [43.86, -79.10]) // Using L.latLngBounds for now.
},
{
element: clockBurlingtonElement, // Using the HTML Element for now.
width: parseInt(window.getComputedStyle(clockBurlingtonElement, null).getPropertyValue("width"), 10),
area: L.latLngBounds([43.28, -79.96], [43.48, -79.71]) // Using L.latLngBounds for now.
}
];
// Initialization
var controlsContainer = map._container.getElementsByClassName("leaflet-control-container")[0],
firstCorner = controlsContainer.firstChild,
mapContainerWidth;
map.on("resize", setMapContainerWidth);
setMapContainerWidth();
// Applying the zones.
for (var i = 0; i < zones.length; i += 1) {
setZone(zones[i]);
}
function setZone(zoneData) {
// Visualize the area.
L.rectangle(zoneData.area).addTo(map);
console.log("width: " + zoneData.width);
controlsContainer.insertBefore(zoneData.element, firstCorner);
map.on("move resize", function () {
updateZone(zoneData);
});
updateZone(zoneData);
}
function updateZone(zoneData) {
var mapBounds = map.getBounds(),
zoneArea = zoneData.area,
style = zoneData.element.style;
if (mapBounds.intersects(zoneArea)) {
style.display = "block";
var hcenterLng = getIntersectionHorizontalCenter(mapBounds, zoneArea),
hcenter = isNaN(hcenterLng) ? 0 : map.latLngToContainerPoint([0, hcenterLng]).x;
// Update Element position.
// Could be refined to keep the entire Element visible, rather than cropping it.
style.left = (hcenter - (zoneData.width / 2)) + "px";
} else {
style.display = "none";
}
}
function getIntersectionHorizontalCenter(bounds1, bounds2) {
var west1 = bounds1.getWest(),
west2 = bounds2.getWest(),
westIn = west1 < west2 ? west2 : west1,
east1 = bounds1.getEast(),
east2 = bounds2.getEast(),
eastIn = east1 < east2 ? east1 : east2;
return (westIn + eastIn) / 2;
}
function setMapContainerWidth() {
mapContainerWidth = map.getSize().x;
}
Live demo: http://plnkr.co/edit/V2pvcva5S9OZ2N7LlI8r?p=preview