雑食性雑感雑記

知識の整理場。ため込んだ知識をブログ記事として再構築します。

D3.js で連続 transition アニメーション

概要

  • D3.js で transition によるアニメーションを連続で行ってみる。
    • メソッドチェインで繋げて書けば良いけど。
    • 長すぎる場合に切りたい。そんな時はどうすれば…?

サンプル

  • jsdo.it 上に置きました。


D3.js の transition によるアニメーション

  • 「transition().duration(msec)」を利用すればOK。
    • msec は変化ミリ秒。
    • メソッドチェインで、変化パラメータを順に書けばよい。
    • 以下、circle を移動するサンプル。
var dataset = [5, 10 , 15, 20, 25];

var circles = svg.selectAll('circle')
                 .data(dataset).enter()
                 .append('circle')
                 .attr('cx', function(d) { return d; })
                 .attr('cy', function(d) { return d; })
                 .attr('r', 5);

circles.transition().duration(1000)
       .attr('cx', function(d) { return d * 2; })
       .attr('cy', function(d) { return d * 3; });

連続で書く (そのまま)

  • そのままメソッドチェインで「transition().duration(msec)」を繋げればOK。
    • ただし、連続で書くとどんどん長くなる…。
circles.transition().duration(1000)
       .attr('cx', function(d) { return d * 2; })
       .attr('cy', function(d) { return d * 3; })
       .transition().duration(1000)
       .attr('cx', function(d) { return d * Math.random(); })
       .attr('cy', function(d) { return d * Math.random(); })
       .transition().duration(1000)
       .attr('cx', function(d) { return d * 4; })
       .attr('cy', function(d) { return d * 2; });

連続で書く (callを使う ⇒ ×)

  • D3.js にある「call」を使ってみる。
function move(elm, msec, alpha, beta)
{
    elm.transition().duration(msec)
       .attr('cx', function(d) { return d * alpha; })
       .attr('cy', function(d) { return d * beta; });
}

circles.call(move, 1000, 2, 3)
       .call(move, 1000, Math.random(), Math.random())
       .call(move, 1000, 4, 2);

  • が、これだと一度にすべてにアニメーションが動いてしまう…orz。
    • 連続ではなく、一つのアニメーションなら普通に動くので、使いようはあるが。

連続で書く (JavaScript標準の call ⇒ ○)

  • JavaScript標準のcallを使うようにしたらできた!!ただし…
    • 一度、transition().duration(msec)の値を変数に保持。
    • そのうえで、アニメーションの処理を書く。
function move(msec, alpha, beta) {
    var circles = this.transition().duration(msec);
    circles.attr('cx', function(d) { return d * alpha; })
          .attr('cy', function(d) { return d * beta; });
    return circles;
}

circles = move.call(circles, 1000, 2, 3)
circles = move.call(circles, 1000, Math.random(), Math.random())
circles = move.call(circles, 1000, 4, 2);

まとめ

  • とりあえず、長~いアニメーション書いても区切れるようになったので、当初の問題は解決。
  • もう少し綺麗に書きたいところだが…。