Анимация фильтрации маркеров в Yandex Maps API
Последняя версия API Яндекс-Карт всем хороша. Но нет предела совершенству. Захотелось, чтобы фильтрация объектов на карте происходила через fade.
Давайте разберемся, возможно ли это.
Задача состоит в том, чтобы при фильтрации одного или нескольких объектов на карте, сокрытие остальных происходило с эффектом. Например, с увеличением прозрачности.
Начинаем копать.
Доступ к DOM-элементам маркеров, как и остальных геообъектов, в API отсутствует. Что, в общем-то, и правильно. В зависимости от браузера и способа вывода геообъектов это может быть как несколько вложенных DOM-элементов, так и нарисованная на канвасе картинка.
Копаем глубже. Что у нас есть такого, откуда мы можем получить DOM-элемент, чтобы впоследствии задать ему css-класс с transition и opacity?
Вот оно — это свойство pane в options для геообъекта.
У каждого геообъекта есть слой (pane), на который он выводится.
Давайте посмотрим, какие бывают слои:
'ground': pane.MovablePane (zIndex: 100) — самый нижний пейн, предназначенный для размещения подложки карты;
'areas': pane.MovablePane (zIndex: 200) — пейн площадных объектов, таких как многоугольники;
'shadows': pane.MovablePane (zIndex: 300) — пейн теней объектов карты, находящихся выше;
'places': pane.MovablePane (zIndex: 400) — пейн точечных объектов, таких как метки;
'events': pane.EventsPane (zIndex: 500) — пейн, предназначенный для слушания событий карты;
'overlaps': pane.MovablePane (zIndex: 600) — пейн для объектов не требующих, использования активных областей для реализации своей интерактивности;
'balloon': pane.MovablePane (zIndex: 700) — пейн балуна;
'outerBalloon': pane.MovablePane (zIndex: 800) — внешний пейн балуна;
'controls': pane.StaticPane (zIndex: 900) — пейн элементов управления карты;
'copyrights': pane.StaticPane (zIndex: 1000) — пейн копирайтов;
'hint': pane.StaticPane (zIndex: 1100) — пейн хинта;
'outerHint': pane.StaticPane (zIndex: 1200) — внешний пейн хинта.
Сейчас нас интересует слой places
Есть еще слой shadows и areas. Так что, если у нас объекты с тенями или многоугольники — придется работать и с ними.
Но сейчас нас интересует сам принцип.
Каждый слой имеет свойство getElement (), которое и дает нам доступ к DOM-элементу.
Давайте добавим еще один слой на карту
var selectedPane = new ymaps.pane.MovablePane(myMap, { zIndex: 420}),
myMap.panes.append('selected', selectedPane);
Теперь, в стили добавим
.hiding ymaps {
transition: opacity 1s;
}
.hidden ymaps {
opacity: 0;
}
Теперь мы можем задать нашему основному слою, на который выводятся метки, css-класс
var placesPane = myMap.panes.get('places').getElement();
$(placesPane).addClass('hiding');
Отлично! Сейчас, если мы зададим нашему основному слою css-класс hiding и hidden — получим эффект затухания в 1 секунду!
Осталось только сделать так, чтобы выбранные (фильтрованные) маркеры не исчезли вместе в остальными.
И для этого у нас есть новый слой selectedPane!
Перемещаем наши метки на selectedPane
myPlaceMark.options.set('pane', 'selected');
И задаем слою с остальными метками css-класс hidden.
var placesPane = myMap.panes.get('places').getElement();
$(placesPane).addClass('hidden');
О, да! Все красиво затухает.
В фидле метки фильтруются по клику на метку и возвращаются обратно через секунду.
То же самое можно сделать с коллекциями, фильтрами и т.д.
Можно добавить другие эффекты.
Например, можно задать элементам transform (translate (@x, @y)) с рандомными координатами за пределами вьюпорта — тогда метки «разбегутся» при фильтрации. Простор для фантазии тут огромен.
Надеюсь, это было полезно.