Sobes.tech
Назад к вопросам
Middle+
3

Кейс: необходимо реализовать плавную анимацию отображения машины на карте. Телеметрия (широта, долгота, угол) приходит 2 раза в секунду, машина прыгает по координатам. Как бы ты это реализовал?

Компании, где спрашивали
EVACargo

Ответ от нейросети

sobes.tech AI

Для плавной анимации машины на карте при обновлении телеметрии 2 раза в секунду можно использовать интерполяцию между полученными координатами и углами.

Основная идея:

  1. При получении новых данных (широта, долгота, угол) сохраняем текущие и новые значения.
  2. Запускаем анимацию, которая плавно изменяет позицию и угол машины с текущих значений к новым за промежуток времени, например, 500 мс (поскольку данные приходят каждые 500 мс).
  3. Для интерполяции можно использовать линейную интерполяцию (LERP) для координат и угла.
  4. Анимацию можно реализовать с помощью requestAnimationFrame для плавности.

Пример на JavaScript (используя Leaflet или подобную библиотеку):

let currentPos = {lat: 0, lng: 0, angle: 0};
let targetPos = {lat: 0, lng: 0, angle: 0};
let animationStart = null;
const animationDuration = 500; // мс

function lerp(start, end, t) {
  return start + (end - start) * t;
}

function animate(timestamp) {
  if (!animationStart) animationStart = timestamp;
  const progress = Math.min((timestamp - animationStart) / animationDuration, 1);

  const lat = lerp(currentPos.lat, targetPos.lat, progress);
  const lng = lerp(currentPos.lng, targetPos.lng, progress);
  const angle = lerp(currentPos.angle, targetPos.angle, progress);

  // Обновляем позицию и угол машины на карте
  updateCarOnMap(lat, lng, angle);

  if (progress < 1) {
    requestAnimationFrame(animate);
  } else {
    currentPos = {...targetPos};
    animationStart = null;
  }
}

function onTelemetryReceived(newLat, newLng, newAngle) {
  targetPos = {lat: newLat, lng: newLng, angle: newAngle};
  animationStart = null;
  requestAnimationFrame(animate);
}

Таким образом, между обновлениями координат машина будет плавно перемещаться и поворачиваться, исключая «прыжки».