Интернет,  Программирование

Добавление вращения иконки в mapbox

Проблема с transform: rotate

Привет друзья. Сегодня решил с вами поделиться небольшим мануалом по изменению вращения иконки в mapbox на определенный угол. Как мы знаем за это отвечает свойство в стилях transform: rotate(Ndeg), где N угол вращения.

Однако, я не нашел внятного объяснения решения данной задачи, поскольку в mapbox идет разъяснение как добавить обычное изображение : Add marker to the map

// add markers to map
geojson.features.forEach(function(marker) {

  // create a HTML element for each feature
  var el = document.createElement('div');
  el.className = 'marker';

  // make a marker for each feature and add to the map
  new mapboxgl.Marker(el)
    .setLngLat(marker.geometry.coordinates)
    .addTo(map);
});

Но как показала практика, проблема возникает на этапе обновления перерисовки карты при масштабировании или перетаскивании карты, так как в созданном HTML элементе <div> с классом marker уже присутствует стиль transform с некими свойствами и они меняются в зависимости от масштабирования или перетаскивания.

 

В попытках решения

Я попытался самостоятельно добавить в элемент el стиль transform со свойством rotate.

//Here code create marker
var el = document.createElement('div'); 
el.className = 'marker';
el.style.transform += ' rotate(50deg)'; // Here I added 50 deg for example

Но этого хватило только до первой отрисовки карты и маркеров. После каких либо манипуляций свойство rotate удалялось, так как переписывался полностью стиль.

Даже добавив код после добавления карты

//Here code create marker
var el = document.createElement('div');
el.className = 'marker';
// make a marker for each feature and add to the map new mapboxgl.Marker(el) .setLngLat(marker.geometry.coordinates) .addTo(map);
 
el.style.transform += ' rotate(50deg)'; // Here I added 50 deg for example

Этого хватило до первого масштабирования.

Я находил несколько статей про попытки решения проблемы, вот одна из них на StackoverFlow: Mapbox Custom Marker Rotation

В ней описывается подобная проблема и попытка решить ее в комментариях разработчиками:

Note that panto or any other form of map update will reset the rotation, make sure to update the rotation after those events.

// В общем здесь описывается, что после любых обновлениях или событиях, нужно обновлять свойство rotate

Т.е. по сути нужно отслеживать событий, каждый раз меняя значения. Однако на мой взгляд это накладывает некие проблемы в будущем, например когда иконок будет больше. Код соответственно становится больше от различных обработчиков.

Решение моей проблемы

Решение проблемы пришло спонтанно. Я решил создать создавать родительский div с изменяющимся свойством transform. В него вкладываем некий элемент и добавляем к нему стили классы. При этом, он не будет меняться при масштабировании или перетаскивании карты.

Вот как я решил эту задачу:

response.source.data.features.forEach(function(marker) {
    // create a HTML element for each feature
    var rotate = marker.properties.rotation; // Get property rotation
    var div = document.createElement('div');
    var el = div.appendChild(document.createElement('el'));
    el.className = 'marker mapboxgl-marker mapboxgl-marker-anchor-center';
    el.style.transform = "rotate(" + rotate + "deg)";
    el.style.margin = '-15px 0 0 -12px';
    var popup = new mapboxgl.Popup({ offset: 10 })
        .setHTML(marker.properties.description);
    new mapboxgl.Marker(div)
        .setLngLat(marker.geometry.coordinates)
        .setPopup(popup)
        .addTo(map);
});

Т.е. по сути я создаю родителя и потомка. Потомку добавляю классы имеющиеся у родителя + класс marker в котором описывается картинка. И вдобавок к потомку добавляю стиль transform:rotate(Ndeg) с необходимым мне углом поворота.

Вот как то так я решил данную задачу, буду рад комментариям и более изящному решению со стороны коллег.

Всем удачи!

Добавить комментарий

Войти с через: 

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Защита от роБота * Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.