2013-07-24 13 views
5

Oto kod: http://jsfiddle.net/fJAwW/prędkość Zmiana D3 animacji ścieżki

To co jestem zainteresowany:

path 
    .attr("stroke-dasharray", totalLength + " " + totalLength) 
    .attr("stroke-dashoffset", totalLength) 
    .transition() 
    .duration(2000) 
    .ease("linear") 
    .attr("stroke-dashoffset", 0); 

mam danych zmiennej Linedata, który dodaję do ścieżki z

.attr("d", line(lineData)) 

dla odcinka przejściowego:

.transition() 
    .duration(2000) 

chciałbym zrobić coś takiego

.transition() 
    .duration(function(d) { 
     return d.x; 
    }) 

gdzie D jest jednym z moich punktów danych.

Mam problemy ze zrozumieniem struktur danych i ich interakcji w pliku d3.js, więc każda pomoc będzie doceniana.

+0

to znaczy, że chcesz animacja poruszać się szybciej lub wolniej w różnych punktach wzdłuż linii, np na podstawie tego, czy idzie "pod górę", czy "z góry"? – explunit

+0

Tak, zasadniczo. Ostatecznie chciałbym mieć dane takie jak {x: 1, y: 2, prędkość: 50} i móc kontrolować przejście między punktami z atrybutem prędkości. –

Odpowiedz

2

Jedną z interesujących rzeczy o d3 jest to, że dane nie są przechowywane w atrybucie d, jest to atrybut __data__. Ścieżki są wyjątkowe w tym to nie jest tak naprawdę, gdzie przechowywane są dane o ścieżce. Chociaż można go obejść, zdecydowanie zaleca się używanie standardowego wzorca danych , z .data(), .enter() i .append().

Ponieważ nigdy nie wprowadzasz żadnych danych, __data__ jest puste, aw rezultacie d jest niezdefiniowane, jeśli używasz .duration(function(d) {}).

Ogólnie rzecz biorąc, po przejściu takiej funkcji sama zmienna nie ma znaczenia. Pierwsza zmienna jest zawsze przypisywana do __data__ dla wyboru, a druga jest zawsze indeksem.

Prawdopodobnie najlepszym przykładem wzoru aktualizacji jest this block autorstwa Mike'a Bostocka. Jest też kilka świetnych informacji w API, jeśli utkniesz, a także około dziesięciu miliardów samouczków o tym, jak utworzyć działkę rozproszoną, która mówi o tym samym.

Można użyć .data() umieścić niektóre dane na swojej drodze, a następnie uzyskać dostęp do jej funkcji w .duration(), tak:

path.data([{'duration':1000}]) 
    .transition() 
    .duration(function(d){return d.duration}) 
+0

Jeśli czytam poprawnie, to, co proponujesz, pozwala mu zmienić prędkość na ścieżkę, ale próbuje zmienić prędkość pomiędzy punktami na ścieżce. – explunit

+0

Prawidłowo! Raczej. Problem polega na tym, że dane wprowadzane do ścieżki są naprawdę dostępne tylko przez 'ścieżka [0] [0] .pathSegList.getItem (i)', która da ci określony segment ścieżki, który jest nieco niezrozumiały. Jeśli chcesz uzyskać dostęp do punktów na ścieżce, punkty te mogą być umieszczone w 'd', z' path.data ([lineData]) '(zauważ, że w nawiasach sans, tylko pierwszy punkt znajdzie się w danych.) Punkty te można następnie wykorzystać do ustawienia niestandardowej funkcji rozluźniania, która zmieniałaby się z prędkością na ścieżce za pomocą funkcji "(d) {}". W ten sposób nie jest się trudnym kodowaniem nazw danych w dowolnym miejscu. – ckersch

4

wierzę, trzeba będzie stworzyć zestaw przykuty przejść do zmiany wartość stroke-dashoffset w każdym punkcie linii. Jak zauważył @ckersch, ścieżka różni się od większości rzeczy w d3, ponieważ dane są zwinięte w jeden ciąg ścieżki, a nie reprezentowane jako pojedyncze wartości.

Możesz połączyć początkowe przejście ze zmiennej path, tak jak to zrobiliście, a następnie połączyć kolejne przejścia z poprzedniej. Coś takiego:

// Add the path 
    var path = svg.append('path') 
    .attr({d: line(lineData), stroke: "steelblue", 'stroke-width': 2, fill: 'none'}); 

    var totalLength = path.node().getTotalLength(); 

    // start with the line totally hidden 
    path.attr({'stroke-dasharray': totalLength + " " + totalLength, 'stroke-dashoffset': totalLength }); 

    // transition will be chained from either the original path or the last transition 
    var transitionFrom = path; 
    // start at 1 since no transition needed to first point 
    for (var i = 1; i < lineData.length; i++) { 
    transitionFrom = transitionFrom.transition() 
     .duration(lineData[i].speed) 
     .ease("linear") 
     .attr("stroke-dashoffset", lengthAt[i-1] || 0); 
    }; 

Skąd ten lengthAt tablica pochodzi? Tak, to jest brzydka część.Moje umiejętności w zakresie geometrii nie są wystarczająco dobre, aby wiedzieć od razu, jak to przybliżyć, aby dopasować "kardynalną" interpolację w funkcji generatora linii, ale w tym przykładzie zhackowałem sposób, aby to zrobić, rysując ukryte linie i odczytując je z powrotem. z SVG:

http://bl.ocks.org/explunit/6082362

+0

Dzięki za przykład. Czy kiedykolwiek zastanawiałeś się, czy istnieje jakiś sposób zdobycia podsekcji ścieżki zamiast tworzenia ukrytych linii? – TheComeOnMan

Powiązane problemy