2013-05-09 9 views
5

do: wyjaśnienie. Wyobraź sobie okrąg. Zaczniemy rysować okrąg od określonej współrzędnej. Teraz narysuj okrąg zaczynając od innej współrzędnej.W d3 można dynamicznie zmieniać miejsce rozpoczęcia ścieżki do animacji?

Odtwarzam dane ścieżki uzyskane z glifów SVG, a następnie za pomocą animacji d3js animuję zmianę między ścieżkami.

Dla tego przykładu licząc od 1 -> 9,0, a następnie powtarzając.

http://jsfiddle.net/chrisloughnane/HL2ET/

Jak widać niektóre przejścia nie są tak ładne jak inni. Narysują linię zamykającą ścieżkę do następnej ścieżki. (Zgaduję, że tak) dzieje się, gdy początek i koniec ścieżki są bardzo daleko od siebie, kiedy dokonywane są obliczenia dla nowego kształtu. Kiedy działa, jest bardzo miły.

Czy ktoś może sugerować możliwe rozwiązanie brzydkich linii?

KOD bez danych ścieżek

svg.append("path") 
    .attr("transform", "translate(150,300)scale(.2,-.2)") 
    .style("stroke", "red") 
    .style("fill", "gray") 
    .style("stroke-width", "9") 
    .attr("d", d0) 
    .call(transition, digits[0], digits[position]); 

function transition(path, d0, d1) { 
    position++; 
    if(position==10) 
    { 
    position=0; 
    } 
    path.transition() 
     .duration(2000) 
     .attrTween("d", pathTween(d1, 4)) 
     .each("end", function() { d3.select(this).call(transition, d1, digits[position]); }); 
} 

function pathTween(d1, precision) { 
    return function() { 
    var path0 = this, 
     path1 = path0.cloneNode(), 
     n0 = path0.getTotalLength(), 
     n1 = (path1.setAttribute("d", d1), path1).getTotalLength(); 

    // Uniform sampling of distance based on specified precision. 
    var distances = [0], i = 0, dt = precision/Math.max(n0, n1); 
    while ((i += dt) < 1) distances.push(i); 
    distances.push(1); 

    // Compute point-interpolators at each distance. 
    var points = distances.map(function(t) { 
     var p0 = path0.getPointAtLength(t * n0), 
      p1 = path1.getPointAtLength(t * n1); 
     return d3.interpolate([p0.x, p0.y], [p1.x, p1.y]); 
    }); 

    return function(t) { 
     return t < 1 ? "M" + points.map(function(p) { return p(t); }).join("L") : d1; 
    }; 
    }; 
} 

Niestety to nie działa na chrome komórkowego zbyt gdzie jako http://bl.ocks.org/mbostock/3081153 działa dobrze.

Następnym krokiem jest zastosowanie tego efektu do zdań.

+0

Hmm ciekawy problem. Wygląda na to, że istnieje potrzeba lepszego algorytmu dopasowywania punktów p0 i p1 w interpolate. Być może chcesz wypróbować Gale-Shapley, aby dopasować punkty na podstawie odległości euklidesowej. Myślę, że najlepszym algorytmem byłby taki, który nadaje priorytet interpolacji między dwoma punktami, które nie powodują żadnych przecięć. Nie wiem, jak to zrobić. –

Odpowiedz

1

Różnica między twoim przykładem a tym w Bostocku polega na tym, że w jego przykładzie jest jedna ciągła ścieżka, którą przestawia na inną pojedynczą ciągłą ścieżkę.

Podczas gdy w twoim przykładzie cyfry takie jak 1, 2, 3, 5, 6, 7 można narysować za pomocą pojedynczej ciągłej ścieżki. Ale, aby narysować cyfry takie jak 4, 6, 9 i 0, potrzebujesz 2 ścieżek - jedna na drugiej. W przypadku cyfry 8 musisz mieć 2 ścieżki na zewnętrznej ścieżce.

Moja sugestia polegałaby na tym, aby zawsze mieć 2 ścieżki na szczycie zewnętrznej ścieżki, którą obecnie używasz, aby uzyskać odpowiednie wymiary za każdym razem, gdy wyświetlana jest jakaś osobliwa cyfra.

Patrz zdjęcie po więcej szczegółów: enter image description here

+0

srvikram Excellent :) Dziękuję. –

Powiązane problemy