LoginSignup
26
22

More than 5 years have passed since last update.

d3.jsでベジェ曲線をドラッグで変形するサンプル

Posted at

ソースとデモ

ソース: https://github.com/hnakamur/d3.js-drag-bezier-curves-example
デモ: http://hnakamur.github.io/d3.js-drag-bezier-curves-example/

メモ

d3.jsでのドラッグ

Drag Behavior · mbostock/d3 Wikiからリンクされているサンプルを真似しました。

以下のようにd3.behavior.drag()の結果に .origin() を呼んでdragイベントのハンドラを設定します。ハンドラ内では d3.event.x, d3.event.y でドラッグ中の座標が取得できます。

var drag = d3.behavior.drag()
    .origin(function(d) { return d; })
    .on("drag", dragmove);

function dragmove(d) {
  d3.select(this)
      .attr("cx", d.x = Math.max(radius, Math.min(width - radius, d3.event.x)))
      .attr("cy", d.y = Math.max(radius, Math.min(height - radius, d3.event.y)));
}

あとはこの dragcall(drag) で要素に適用すればOKです。SVGの2次ベジェ曲線の制御点をドラッグで動かすサンプル - Qiitaに比べると簡潔でd3.jsは素晴らしいです。

SVGのg要素でレイヤーを実現

SVG Rendering ModelにあるようにSVG 1.1ではDOMの順番に描画される方式になっています。

制御点の円の上にテキストが重なるとドラッグできなかったので、g要素でレイヤーを作って、一番上のレイヤーの中に制御点の円を作るようにしました。

こんな感じで複数のレイヤーを作りました。

var controlLineLayer = svg.append('g').attr('class', 'control-line-layer');
var mainLayer = svg.append('g').attr('class', 'main-layer');
var handleTextLayer = svg.append('g').attr('class', 'handle-text-layer');
var handleLayer = svg.append('g').attr('class', 'handle-layer');

レイヤーを指定して要素を追加するには、svg要素の代わりにレイヤーのg要素を使うのが違うだけで、d3.jsの基本パターンの selectAll().data(データ).enter.append(要素).attr(属性) というコードにしています。

    handleLayer.selectAll('circle.handle.path' + i)
      .data(d.points).enter().append('circle')

制御点に連動する要素選択用にCSSクラスを設定

このサンプルでは、1つの制御点をドラッグすると、制御点のIDと座標のテキストと制御点を結ぶ折れ線とベジェ曲線も連動します。対象の要素を selectAll() で選択しやすいように、ベジェ曲線毎のIDと制御点のIDを連番で発番して、path0p1 などのCSSクラスとして設定しました。

id属性ではなくCSSクラスにしたのは、1つのHTML内に複数のsvgを埋め込む場合にidが衝突する危険性があるからです。

webpack + gulpでビルド

RequireJS等はもう古い。WebPackとは?|1 pixel|サイバーエージェント公式クリエイターズブログ06-productionのgulpfile.jsをカスタマイズして使わせていただきました。ありがとうございます!

26
22
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
26
22