Как нарисовать строку из последовательных точек массива в openlayers

Я пытаюсь рисовать LineString в открытых слоях с последовательными Points, чтобы придать ощущение анимации, как будто она рисуется от начала до конца.

Я пытался добиться этого, следуя этот пример. Все ссылки OL2 конвертируются в OpenLayers 5, но отрисовка все равно должна происходить одной точкой, а затем следующей для всего массива, а не сразу.

Найдите мой код с текущим выводом здесь — мой код.

[Для справки] Это я пытаюсь добиться Анимация змеи для листовки.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
2 659
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ваш цикл for

for(i=0;i<path.length;) {
    drawAnimatedLine(/*snip*/);
}

запускает анимацию для всех точек практически одновременно, не дожидаясь. Вам нужно будет подождать, пока анимация первой строки не закончится, прежде чем начинать следующий сегмент. Ваша функция drawAnimation имеет 6-й параметр fn, чтобы предоставить ей указатель на функцию, которую нужно вызвать после завершения рисования.

Вот короткая грязная версия, где я переписал ваш цикл for, чтобы продемонстрировать, что я имею в виду. https://jsbin.com/lanoxojugi/edit?js, вывод

Ответ принят как подходящий

Использование только вершин линии не дает плавной анимации. Вы можете видеть это в примере OpenLayers https://openlayers.org/en/v4.6.5/examples/feature-move-animation.html, где маркер перемещается намного быстрее по прямым участкам. Если вам нужно плавное движение по прямым линиям, как в примере OpenLayers 2, вам нужно использовать .getCoordinateAt(), чтобы вычислить, где на линии вы должны находиться в любой момент времени. Вот демонстрация, основанная на примере анимации маркера, но также вычисляющая позиции между вершинами, показывающая строку из примера со змеей. Вы также можете рисовать собственные прямые линии и наблюдать за их плавной анимацией.

var style = new ol.style.Style({
  stroke: new ol.style.Stroke({
width: 4,
color: 'red'
  })
});

var raster = new ol.layer.Tile({
  source:  new ol.source.OSM()
});

var vector = new ol.layer.Vector({
  source: new ol.source.Vector(),
  style: style
});

var map = new ol.Map({
  layers: [raster, vector],
  target: 'map',
  view: new ol.View()
});

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://raw.githubusercontent.com/IvanSanchez/Leaflet.Polyline.SnakeAnim/master/route.js');
xhr.onload = function() {
  // read the route coordinates
  eval(xhr.responseText);
  // reverse the route
  var geom = new ol.geom.LineString(route.reverse());
  // change Lat/Lon to Lon/Lat
  geom.applyTransform(function(c){ return c.reverse(); });
  geom.transform('EPSG:4326', map.getView().getProjection());
  map.getView().fit(geom.getExtent(), { size: map.getSize() });
  var snake = new ol.Feature();
  vector.getSource().addFeature(snake);
  animate_line(snake, geom, 30000);
}
xhr.send();

function animate_line(feature, linestring, duration) {

  var length = linestring.getLength();
  var length_shown = 0;

  var coords = linestring.getCoordinates();
  var coords_shown = [coords[0], coords[0]];
  var geom_shown = new ol.geom.LineString(coords_shown);
  feature.setGeometry(geom_shown);

  var coordcount = 1;
  var start = new Date().getTime();
  var listenerKey = map.on('postcompose', animate);

  function animate() {

var elapsed = new Date().getTime() - start;
var toAdd = length*elapsed/duration - length_shown;
var point = linestring.getCoordinateAt(Math.min(elapsed/duration, 1));

// restart from last intermediate point and remove it
var newPart = new ol.geom.LineString(coords_shown.slice(-1));
coords_shown.pop();

// add vertices until required length exceeded
while (coordcount < coords.length && newPart.getLength() <= toAdd) {
  newPart.appendCoordinate(coords[coordcount]);
  coords_shown.push(coords[coordcount]);
  coordcount++;
}

// replace overrun vertex with intermediate point
coords_shown.pop();
coordcount--;
coords_shown.push(point);

geom_shown.setCoordinates(coords_shown);
length_shown += toAdd;

if (elapsed > duration) {
  ol.Observable.unByKey(listenerKey);
}
map.render();

  }

}

draw = new ol.interaction.Draw({
  source: vector.getSource(),
  type: 'LineString'
});

draw.on('drawend',function(evt){
  geom = evt.feature.getGeometry();
  evt.feature.setGeometry(undefined);
  animate_line(evt.feature, geom, 6000);
});
map.addInteraction(draw);
html, body, .map {
    margin: 0;
    padding: 0;
    width: 100%;
    height: 100%;
}
<link href = "https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel = "stylesheet" />
<script src = "https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<div id = "map" class = "map"></div>

Запрос xhr возвращает только маршрут, тогда почему анимация не работает, если я предоставляю свою геометрию и функцию, оставляя комментарий к запросу xhr. Закомментируйте запрос xhr и посмотрите вывод здесь — [jsbin.com/tozenav/edit?js, вывод]

capnam 10.04.2019 11:29

Вам нужно инициализировать представление map.getView().fit(g); перед вызовом animate_line (или установить центр и масштаб при создании карты)

Mike 10.04.2019 11:55

Другие вопросы по теме