Клуб API Карт

Анимация меток

Пост в архиве.

Доброго времени суток. Хотелось бы реализовать анимацию метки. То есть чтобы метка постепенно перемещалась из точки А в точку Б (просто по прямой линии)

Делаю так (весь листинг приводить не буду, только самое необходимое):

// Функция расчета расстояния от одной точки до другой
function calcDis(point1, point2) {
  return Math.sqrt((point2.x-point1.x)*(point2.x-point1.x) + 
  (point2.y-point1.y)*(point2.y-point1.y));				
}
// Функция расчета приращения по x
function calcDx(dis, point1, point2){
  return ((point2.x-point1.x)/(dis-1));
}
// Функция расчета приращения по y
function calcDy(dis, point1, point2){
  return ((point2.y-point1.y)/(dis-1));
}
// Точка a и точка b
var a = new YMaps.GeoPoint(104.15734, 52.34662);
var b = new YMaps.GeoPoint(104.262344, 52.262659);
// конвертируем координаты точки в пиксельные
var convert_a = map.converter.coordinatesToMapPixels(a);
var convert_b = map.converter.coordinatesToMapPixels(b);
// функция createIcon создает метку в указанных координатах 
var icon1 = createIcon(a);
// добавляем на карту
map.addOverlay(icon1);
// рассчитываем расстояние м/у точками и приращения
var dis = calcDis(convert_a, convert_b);
var dx = calcDx(dis, convert_a, convert_b);
var dy = calcDy(dis, convert_a, convert_b);

// это таймер на основе одного из плагинов для jQuery
$("#YMapsID").everyTime(200,'timer1', function() {
// прибавляем к точке приращения по x и y
convert_a.x += dx;
convert_a.y += dy;
// устанавливаем новые координаты для метки предварительно 
// конвертировав их
icon1.setCoordPoint(map.converter.clientPixelsToCoordinates(convert_a));
});

Этот код работает, но есть одна проблема: при скролинге страницы метка тоже перемещается вверх или вниз. Думаю это связанно с неправильным выбором метода преобразования координат. (При увеличении масштаба и перемещении карты тоже что-то подобное происходит)

Вообщем прощу подсказать какой метод преобразования здесь наиболее правильно применить. И вообще в правильном ли направлении z движусь? Не изобретаю ли я велосипед таким способом? Может быть в API уже есть функции для подобных вещей. Или есть уже подобная реализация (пример)?

5 комментариев
Александр Новиков
28 января 2016, 07:48
Не совсем понятно зачем вы преобразуете координаты несколько раз. Думаю что будет достаточно считать смещение в географических координатах и выводить по ним точку. Пропадут проблемы со скроллингом. И надо смотреть на логику того что вы хотите сделать - можно будет либо вводить коэффициент учета уровня zoom. А может и это учитывать не надо.

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

Для 2 заданных точек смещения получились:

-0.12131398233940825 - для широты
0.09700243106167301 - для долготы

Соответственно если прибавлять их к изначальной точке, она будет делать большие скачки... Попробовал делить смещения на 1000, получилось более менее. Но я подумал что это не правильно и нужно все таки конвертировать координаты...

Каким образом считать смещения именно для географических координат?

в начале coordinatesToMapPixels

в конце clientPixelsToCoordinates(учитывает скоролл страницы)

если не хотите проблем с зумом - считайте либо в координатах, либо делайте полный перерасчет при смене зума

По моему я именно так и делаю:

в начале coordinatesToMapPixels

в конце clientPixelsToCoordinates

Однако проблемы со скролом присутствуют.

clientPixelsToCoordinates(учитывает скоролл страницы) - это координаты текущего окна.
тоесть от начала документа+скролинг

coordinatesToMapPixels - это даже не Container\Div pixels, а координаты "где-то" на карте.
Используйте симетричные функции, на это я намекал