D3.js animate rotation

Mam problem przy próbie poprawnego wykonania animacji rotacji przy użyciu D3.biblioteka js. Problem dotyczy punktu, w którym chcę obrócić element.

Oto skrzypce, które zrobiłem, aby pokazać, co mam na myśli (w zwolnionym tempie): http://jsfiddle.net/74mCb/

Wydaje się, że źródło problemu leży tutaj:

.attr("transform", "rotate(-60, 150,130)");

A potem obracam TAK:

.attr("transform", "rotate(40 150,130)");

Chciałbym, aby kolba igły pozostała w pozycji (być środek obrotu), czy ktoś mógłby wyjaśnić, co robię źle?

Dzięki!
Author: paxRoman, 2012-11-09

2 answers

Jest to trochę trudne do uchwycenia (sam nie do końca rozumiem), ale D3 potrzebuje pomocy, wiedząc, jak interpolować między dwoma ciągami, które reprezentują Twój obrót.

function turnNeedle()
{

    needle
      .transition()
      .duration(2000)
      .attrTween("transform", tween);

    function tween(d, i, a) {
      return d3.interpolateString("rotate(-60, 150, 130)", "rotate(60, 150, 130)");
    }

}

d jest punktem odniesienia, {[2] } jest indeksem, {[3] } jest atrybutem w przypadku, gdy chcesz, aby te dane były oparte na danych.

Http://jsfiddle.net/SHF2M/

 27
Author: Duopixel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-09 18:57:47

Oto co myślę się dzieje: per The SVG spec , the transform

rotate(40 150,130)

Jest równoważne:

translate(150,130) rotate(40) translate(-150, -130)

Wygląda na to, że D3 animuje zarówno tłumaczenie, jak i obrót - wewnętrzna d3.transform reprezentacja rotate(40 150,130) jest składnikiem rotate + składnikiem translacji, więc oba są włączone do przejścia.

Najłatwiej jest narysować igłę na początku, przetłumaczyć ją zewnętrznym elementem g na właściwą pozycję, a następnie obrócić it:

var needle = svg
  .append("g")
    .attr("class", "needle")
    .attr("transform", "translate(150 , 130)")
  .append("path")
    .attr("class", "tri")
    // your path may have been prettier
    .attr("d", "M-3 0 L0 -130 L3 0 S3 5 0 5 S-3 5 -3 0 Z")
    .attr("transform", "rotate(-60)");

Then

needle
    .transition()
    .duration(2000)
    .attr("transform", "rotate(40)");

Zobacz działające skrzypce: http://jsfiddle.net/nrabinowitz/74mCb/1/

 10
Author: nrabinowitz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-09 19:11:53