LoginSignup
3
1

More than 5 years have passed since last update.

d3.jsでParticleをSVGのPath上で動かす

Posted at

version

d3.jsのversionは4.1.0です。

Code

今回使用した全コード

demo

スクリーンショット 2016-07-15 22.36.36.png

demo: "d3jsはこういうこともできるっぽいw 使い道はわからない😇

・参考
これをversion4の書き方にして、いろいろいじってみました。
Point-Along-Path Interpolation - bl.ocks.org

ランダムの座標

SVG全体の大きさを定義

this.margin = {top: 10, right: 10, bottom: 0, left: 0};

this.width = window.innerWidth - this.margin.left - this.margin.right,
this.height = window.innerHeight - this.margin.top - this.margin.bottom;

range

const vertexLength = 4;
const posX = d3.range(vertexLength)
.map(d3.randomUniform(0, this.width));

const posY = d3.range(vertexLength)
.map(d3.randomUniform(this.height));

rangeを使って配列を作ります。

d3-array/README.md at master · d3/d3-array

zip

d3.zip([1, 2], [3, 4]); // returns [[1, 3], [2, 4]]

二つの配列を上のように操作できます。

const particles = d3.zip(posX, posY);

d3-array/README.md at master · d3/d3-array

Pathを描画

curveCardinalClosed

this.path = this.svg.append("path")
.data([particles])
.attr("class", "myPath")
.attr("d", d3.line().curve(d3.curveCardinalClosed.tension(0.5)));

curveCardinalClosedを使って閉じた曲線を描きます。

d3/d3-shape: Graphical primitives for visualization, such as lines and areas.

Particleを描画

this.circle = this.svg.selectAll(".point")
.data(d3.range(particleLength))
.enter().append("circle")
.attr("r", 3)
.attr("class", "particle")
.attr("transform", (d, i) => {
  return "translate(" + particles[0][0] + ")";
});

始めの位置はすべて同じにしたかったので、particles[0][0]にしてます。

Transition

attrTween

transition() {
    this.circle.transition()
    .duration(10000)
    .delay(function(d, i) { return i * 50; })
    .attrTween("transform", this.translateAlong(this.path.node()))
    .on("end", () => {
      this.transition();
    });

}
  • delay
    • delayすることで微妙に開始時間を遅らせて、particleそれぞれが順々に動くようにしている
  • attrTween
    • interpolaterというのを使って値の補完をしてる

d3-transition/README.md at master · d3/d3-transition


translateAlong(path) {
    var l = path.getTotalLength();
    return function(d, i, a) {
      return function(t) {
        var p = path.getPointAtLength(t * l);
        return "translate(" + p.x + "," + p.y + ")";
      };
    };
}
  • i
    • index
  • a
    • ここではcircle
  • t
    • 0~1までの値
    • 割合がわかる

SVGPathElement - Web API インターフェイス | MDN

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1