2013-05-09 15 views
5

per: chiarire. Immagina un cerchio. Iniziamo a disegnare il cerchio da una particolare coordinata. Ora lascia disegnare il cerchio partendo da un'altra coordinata.In d3 è possibile cambiare dinamicamente dove inizia la posizione del percorso per il tweening?

Sto giocando con dati di percorso derivati ​​da glifi SVG e quindi utilizzando d3js interpolazione per animare il cambiamento tra i percorsi.

Per questo esempio, contare da 1 -> 9,0 e quindi ripetere.

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

Come potete vedere alcune delle transizioni non sono bello come gli altri. Disegnano una linea che chiude il percorso per il prossimo percorso. (Sto indovinando che) questo accade quando l'inizio e la fine del percorso sono molto distanti quando viene eseguito il calcolo per la nuova forma. Quando funziona è molto bello.

Qualcuno potrebbe suggerire una possibile soluzione alle brutte linee?

codice senza dati del percorso

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; 
    }; 
    }; 
} 

Purtroppo non riesce sul cellulare di cromo anche dove, come http://bl.ocks.org/mbostock/3081153 funziona bene.

Il passaggio successivo consiste nell'applicare questo effetto alle frasi.

+0

Hmm problema interessante. Sembra che sia necessario un algoritmo migliore per la corrispondenza dei punti p0 e p1 dell'interpolato. Forse vuoi provare Gale-Shapley per abbinare i punti in base alla distanza euclidea. Penso che il miglior algoritmo sia quello che dà la priorità all'interpolazione tra due punti che non causano alcuna intersezione. Non sono sicuro di come farlo però. –

risposta

1

La differenza tra il tuo esempio e quello di Bostock è che nel suo esempio c'è un singolo percorso continuo che esegue le interpolazioni in un altro singolo percorso continuo.

Considerando che, nel tuo esempio, è possibile disegnare cifre come 1, 2, 3, 5, 6, 7 utilizzando un singolo percorso continuo. Ma per disegnare cifre come 4, 6, 9 e 0 hai bisogno di 2 percorsi, uno sopra l'altro. E, per la cifra 8, devi avere 2 percorsi sulla cima di un percorso esterno.

Quindi, il mio suggerimento sarebbe quello di mantenere sempre 2 percorsi in cima al percorso esterno che si sta utilizzando al momento & dare loro le dimensioni appropriate ogni volta che qualsiasi cifra particolare deve essere mostrato.

immagine rimanda per maggiori dettagli: enter image description here

+0

srvikram Eccellente :) Grazie. –