Рубрики
Без рубрики

D3-V3 анимитные пути и точки

Анимировать точку и путь

Автор оригинала: Robert Nicely.

1562726

Давайте рассмотрим некоторые способы оживить SVG в D3 с геоданными. Я сначала решите твердые первым, анимацию пути или вдоль пути. Я буду покрывать Pre-V4 и последнюю версию, поскольку синтаксис почти тот же пост v4.

Есть два общих метода для анимации пути в D3, это ли вы анимируете линию, точку или оба. Первый под названием Interpolation HINC-DASH и второй с именованной интерполяцией точек наряду, различия являются гранулированными. Часто вы можете использовать любой метод для достижения одного типа анимации в целом. Вкратце, разница в точечном пути, вы рассчитываете общую длину пути к анимированию, а в ход-приборной панели вы анимируете в пробелах (DART), выводят из инсульта (путь линии). Итак, вы могли бы подумать об инсуль-тире, как сродни по бокам пленки, с отверстиями, проколотыми во всем, за исключением того, что вы можете варьироваться в зависимости от длины отверстий (или тире), чтобы увеличить или уменьшить точность. Вы анимируете, построенные с одной панели до следующего. Точка в пути, сосредоточена на общей длине пути, в результате, вы делаете немного больше математики. Пункт на пути всегда был больше осенью для меня, поскольку он может анимировать в нескольких ситуациях, которые ход-тире не могут, например, с градиентами. Но различия действительно минуты. Некоторые чувствуют, что он лучше на холсте, WebGL и т. Д. На практике я не видел больших исполнительных различий в любой технике. Для D3.V3 вы загружаете свои запутанные данные, (обход механизма загрузки D3 очень выполняется, но вы должны получить ваши данные в приятный формат Geo-JSON, предыдущий впрыскивание), поскольку D3 дает много преимуществ для эффективности данных, которые он признает, Отказ Вещи, которые происходят на бэкэнде, что обычно облегчает вашу жизнь проще по дороге. Я буду охватывать, как обойти загрузчик и ввести свои собственные прокатные данные в другой статье. Пока что…

var Tiles = L.tileLayer('https://{s}.mapprovider/map/{z}/{x}/{y}', {
  attribution: 'Terms & Feedback'
    });
 var map = L.map('map')
 	.addLayer(Tiles)
    .setView([33.215125313, -110.523415], 14);
 var svg = d3.select(map.getPanes().overlayPane).append("svg");
 var g = svg.append("g").attr("class", "leaflet-zoom-hide");

Приведенное выше, устанавливает наш тилелайер или плитки на карте, карта добавляет слой, и SetView фокусируется на карте на области, добавленный номер, устанавливает уровень масштабирования. SVG добавляет слой D3 для рендеринга SVG на карту, а G обрабатывает теневую ошибку, если вы не включаете G, вы увидите стойкие трассы пути при увеличении или выходах. После загруженного, это обычная практика на карту, либо отфильтровать коллекцию ваших функций, какой-то метод лучше всего служить некоторому подмножению. Хорошее правило, используйте фильтр, чтобы обеспечить данные для каждой точки или точность точек (1E7 или сколько 0,000001, и т. Д.), Или, если у вас есть данные, ошибка дистанции, метод путешествия и т. Д.

d3.json("points.geojson", function(features) {
    //from this point forward, your entire program
    //should be within this function
var data = features.collection.filter(function(d) {
  if ( d.id === points ){
    return d.id;
    };
})

})

Мы загрузили данные и отфильтровали его. Весь следующий код расположен в функции нагрузки D3.JSON.

var transform = d3.geo.transform({ point: projectPoint });
//these are changed if using V4, to d3.geoPath, incase you're using 
//a newer version and wonder why yours doesn't work
var path = d3.geo.path().projection(transform);
function projectPoint(x, y) {
  var point = map.latLngToLayerPoint(new L.LatLng(y, x));
    this.stream.point(point.x, point.y);
}
var toLine = d3.svg.line()
  .interpolate('linear')
    .x(function(d) { return applyLatLngToLayer(d).x })
    .y(function(d) { return applyLatLngToLayer(d).y });
    
function applyLatLngToLayer(d) {
  var y = d.geometry.coordinates[1]
    var x = d.geometry.coordinates[0]
    return map.latLngToLayerPoint(new L.LatLng(y, x))
}

Путь и преобразование принимают регулярные координаты и превращают их в координаты SVG. Проект, применяет эти координаты обратно в слой карт листовки, используя текущий поток. Линия, интерполизирует наши координаты между точками, и последняя функция – это метод, который мы используем для применения координат геометрии к MapLayer.

//Line to animate, between coordinates
var linePath = g.selectAll(".linePaths")
  .data([data])
    .enter()
    .append("path")
    .attr("class", "linePaths");
    
//This is the point to animate
var marker = g.append('circle')
  .attr('r', 6)
    .attr('id', 'marker')
    .attr('class', 'animatedMarker');
    
//now we add all the points, so we can animate to them
var allPoints = g.selectAll('circle')
  .data(data)
    .enter()
    .append('circle')
    .attr('r', 2)
    .attr('class', d => "waypoints " + "c" + d.properties.time) //e6 shorthand
    .style('opacity', 0);

Так что многое здесь, но и много повторения. Вы заметите, что маркер не имеет пакета данных, это потому, что мы создаем маркер с нуля, поэтому нам не нужно прикрепить его к данным. Кроме того, он будет «объединяться» с другими точками данных, благодаря этому общему выбору круга. Но заметите, чтобы создать, состоит в том, чтобы добавить в этом случае, а в другом случае мы выбираем все точки, у нас нет фактической линейной патки, поэтому оно в существовании одинаковых данных, но мы создадим линии на Иди, как вы увидите.

//this just adjusts the paths and points whenever the view resets, so everything
//stays in relation
map.on("viewreset", reset);
//this draws on the map
reset();

//here is the actual reset function for user reposition of the map
function reset() {
  var bounds = path.bounds(features),
    	topLeft = bounds[0],
        bottomRight = bounds[1];
        
    svg.attr("width", bottomRight[0] - topLeft[0] + 120)
    	.attr("height", bottomRight[1] - topLeft[1] + 120)
        .style("left", topLeft[0] - 60 + "px")
        .style("top", topLeft[1] - 60 + "px");
        
    linePath.attr("d", toLine) //here is where we create the linePath
    g.attr("transform", "translate("+(-topLeft[0] + 60) + "," + (-topLeft[1] + 60) + ")");
}

Если ваш маркер/баллы/пути не поднимаются хорошо с вашей картой, это первое место для поиска виновника. Регулировка большего количества большего количества, увеличит просмотр «коробку» вокруг анимации, в то время как меньшие числа будут перемещать центрирующую точку на MapLayer. Я нашел, что в целом хранения чисел друг другу, это хорошее общее начало. Я Добримую на 30,40,50 и т. Д. Так, соответственно, это было бы 60,80,100 и 120,160,200. И это должно получить вам достаточно близко, чтобы сделать любые незначительные корректировки, которые вам могут понадобиться.

function transition(path) {
  linePath.transition()
    	.duration(d => d.dur)
        .attrTween("stroke-dasharray", tweenDash) //there it is, the method for stroke-dasharray interpolation
}
function tweenDash() {
  return function(t) {
    	var l = linePath.node().getTotalLength(); //and here is the second method, getting length
        interpolate = d3.interpolateString("0," + l, l + "," + l); //this is the interpolate for the stroke-dash
        var marker = d3.select('#marker');
        var p = linePath.node().getPointAtLength(t * l); //and the other measurement, to locate the point in path
        marker.attr("transform", "translate(" + p.x + "," + p.y + ")");
        return interpolate(t);
    }
}

И вот и это, вы получаете как линейную анимацию, так и точечную анимацию. В ближайшее время я охвачу V4 + и выделите изменения кода. По какой причине V3 все еще широко используется. Лично у меня нет предпочтений. У них обоих есть какой-то компромисс для удаления версии или оставаясь в V3. Кстати, мы не выходили из нагрузки JSON, поэтому убедитесь, что весь ваш код, находится в этой функции. Следующий пост, я покажу, как мы можем отойти от того, чтобы все было изолировано в этом звонке.