2017-06-23 12 views
1

D3ドラッグイベントを使用してSVGコンテナに矩形を作成しました。D3 JS - SVG矩形を含むグループがドラッグにスムーズに変換されない

描画された矩形の親要素に2Dトランスフォームを適用して(translate(x、y)を使用して)矩形を移動させようとしました。

矩形を描画した後、矩形が含まれているコンテナの境界ボックスの値が取得されます。次に、(0,0)に(x、y)境界ボックスの座標を設定して、ビューポートの角。その後私は元の位置にそれを翻訳します。次に、矩形をドラッグしてマウスイベントの座標でそれを更新して、再度翻訳を適用します。

 d3.select('#rectangle').on('click', function(){ new Rectangle(); }); 

function Rectangle(){ 

    var rectData = []; //holds the diagonal point 1 and 2 coordinates of the rectangle 
    var rectContainer; // g element 
    var shape = {}; //will hold the rectangle's d3 selections 
    var start; //starting point 
    var edge; //ending point 
    var gData = {}; //holds translate values for g element 

// console.log(this); 

    var rectangleDrag = svgCanvas.call(d3.drag().on("start", initialPlod) 
     .on('drag', secondaryPlod) 
     .on('end', onStopDraw)); 

    //start rendering on drag start 
    function initialPlod(){ 
     start = d3.mouse(this); 
//  console.log(start); 
     rectData = [{x:start[0], y:start[1]}, {x:start[0], y:start[1]}]; 
     rectContainer = svgCanvas.append("g"); 
     shape.rectEl = rectContainer.append('rect').attr('class', 'rectangle'); 
     renderRectangle(); 
    } 

    //when continuing to drag from point 2 
    function secondaryPlod(){ 
     edge = d3.mouse(this); 
     rectData[1] = {x: edge[0], y: edge[1]}; 
     renderRectangle(); 
    } 

    //on stop drawing bind a drag event 
    function onStopDraw(){ 

     svgCanvas.call(d3.drag().on("start", null) 
      .on('drag', null) 
      .on('end', null)); 

     var bbox = shape.rectEl._groups[0][0].getBBox(); 
     console.log(this); 
     console.log(bbox); 

     //temporary variables that hold original position 
     var rectCords = { 
      x: bbox.x, 
      y: bbox.y 
     }; 

     //setting boundingbox to 0,0 coordinates 
     bbox.x = 0; 
     bbox.y = 0; 

//  console.log(bbox); 

     shape.rectEl.attr("x", bbox.x).attr("y", bbox.y); 

     gData.x = rectCords.x; 
     gData.y = rectCords.y; 

     rectContainer.attr("transform", "translate(" + gData.x + "," + gData.y + ")"); 

     shape.rectEl.call(d3.drag().on("drag", dragRect)); 
    } 

    //grab and drag rectangle 
    function dragRect() { 
     var move = d3.event; 
     rectContainer.attr("transform", "translate(" + (gData.x += move.dx) + "," + (gData.y += move.dy) + ")"); 
    } 

    /** 
    * 
    * Method takes the x,y coordinates from rectData object array 
    * which contains coordinates of point1 and point2 
    * and calculates the the height and width 
    * 
    */ 
    function renderRectangle(){ 
     //rectangle attributes 
     var xCoord = rectData[1].x - rectData[0].x > 0 ? rectData[0].x : rectData[1].x; 
     var yCoord = rectData[1].y - rectData[0].y > 0 ? rectData[0].y : rectData[1].y; 
     var width = Math.abs(rectData[1].x - rectData[0].x); 
     var height = Math.abs(rectData[1].y - rectData[0].y); 

     //render rectangle 
     shape.rectEl.attr("x",xCoord) 
      .attr("y", yCoord) 
      .attr("width",width) 
      .attr("height",height); 
    } 

} 

矩形は平行移動しますが、不安定です。しかし、私がSVGサークルに同じテクニックを適用すると、マウスのドラッグでうまく翻訳されます。両方のシェイプを同じビューポートに描画できます。

は、ここで私は、問題の原因を見つけることができたfiddle

答えて

1

です。

私はドラッグイベントを、g要素内の矩形要素にバインドしました。これは、矩形をドラッグしたときに不規則な平行移動を引き起こしたようです。長方形をドラッグするときにg要素を平行移動しているので、問題が発生している可能性があります。

ドラッグイベントを長方形のコンテナ(g要素)要素にバインドしました。これでドラッグ時に円滑に変換されます。

//on stop drawing bind a drag event 
    function onStopDraw(){ 

     svgCanvas.call(d3.drag().on("start", null) 
      .on('drag', null) 
      .on('end', null)); 

     var bbox = shape.rectEl._groups[0][0].getBBox(); 
     console.log(this); 
     console.log(bbox); 

     //temporary variables that hold original position 
     var rectCords = { 
      x: bbox.x, 
      y: bbox.y 
     }; 

     //setting boundingbox to 0,0 coordinates 
     bbox.x = 0; 
     bbox.y = 0; 

//  console.log(bbox); 

     shape.rectEl.attr("x", bbox.x).attr("y", bbox.y); 

     gData.x = rectCords.x; 
     gData.y = rectCords.y; 

     rectContainer.attr("transform", "translate(" + gData.x + "," + gData.y + ")"); 

//bound the drag event to the entire g element of the rectangle 
      rectContainer.call(d3.drag().on("drag", dragRect)); 
     } 

ここfiddle

です
関連する問題