2016-11-26 13 views
3

私は矩形の上にあるハンドラ(小さな円)を使ってサイズを変更して回転できる矩形を作成しようとしています。形状のサイズ変更と回転を可能にするほとんどの描画ツールと似ています。サイズ変更可能な回転可能な長方形D3?

私は、私の矩形の上に3つの円を追加しました。 1つの円は、長方形の幅のサイズを変更するためのものです(右側の円)。別の長方形は、バーの高さのサイズを変更するためのものです(上の円)。長方形のサイズを変更すると完全に機能します。 jsFiddleへ

margin = {top: 40, right: 20, bottom: 30, left: 70}, 
     width = 600 - margin.left - margin.right, 
     height = 400 - margin.top - margin.bottom; 

    var svg = d3.select('#canvas').attr("width",width).attr("height",height); 

    gContainer = svg.append('g') 
        .attr("class", "gContainer") 
        .attr("transform", function(d,i){ 
          return "translate("+300+","+200+")" 
        }) 

    gBars = gContainer.append('g').attr("class", "gBar"); 


    gBars.append("rect") 
     .attr("class", "Bar") 
     .attr("fill","black") 
     .attr("width", 40) 
     .attr("height", function(d) { return height - 200}) 
     .style("opacity", 0.5); 


    var handlerRadius = 3.5; 
    handlerPointsPosition=[]; 


    elementWidth = Number(d3.select(".Bar").attr("width")); 
    elementHeight = Number(d3.select(".Bar").attr("height")); 

    x0 = 0 + (elementWidth/2) ; 
    y0 = 0 ; 

    x1 = 0 + (elementWidth); 
    y1 = 0 +(elementHeight/2) ; 

    x2= 0 + (elementWidth/2) ; 
    y2= -20; 

    handlerPointsPosition = [[x0,y0],[x1,y1],[x2,y2]]; 


    var rectangleHandlers = d3.behavior.drag() 
       .origin(function(d) { return d; }) 
       .on("dragstart", dragstarted) 
       .on("drag", dragged) 




    gHandlerPoints= gContainer.selectAll("g.HandlerPoint") 
     .data(handlerPointsPosition) 
     .enter().append('g') 
     .attr("class", "gHandlerPoint") 
     .attr("id", function(d,i){return "gHandlerPoint_id_"+i;}) 
     .attr("transform", function(d,i){ 
     //console.log(d); 
      return "translate("+d[0]+","+d[1]+")" 
     }) 
     .call(rectangleHandlers); 

    gHandlerPoints.append("circle") 
       .attr("class", "handlerPoint") 
       .style("fill", "white") 
       .style("stroke", "blue") 
       .attr("stroke","") 
       .attr("r",function(d,i){return (i == 2 ? 4: 3.5);}) 
       .attr("id", function(d,i){return "HandlerPointId_"+i;}) 

    gContainer.append("line") 
       .attr("class","handlerLine") 
       .attr("x1", (elementWidth/2)) 
       .attr("y1", 0- handlerRadius) 
       .attr("x2", (elementWidth/2)) 
       .attr("y2", -20 + handlerRadius) 
       .attr("stroke-width", 1) 
       .attr("stroke", "blue"); 


    function updateHandlerPosition(id, dX, dY) 
    { 
     d3.select(id).attr("transform", function(d,i){ 
      return "translate(" + [ dX, dY] + ")" 
     }) 
    } 

    function dragstarted(d,i) { 
     dragIconX = d3.transform(d3.select(this).attr("transform")).translate[0]; 
     dragIconY = d3.transform(d3.select(this).attr("transform")).translate[1]; 

     barStartWidth = d3.select(".Bar").attr("width"); 
    } 

    function dragged(d,i) { 
     barHeight = d3.select(".Bar").attr("height"); 
     if(i == 0) // circle on the top edge of the bar 
     { 
     dragIconY = dragIconY + d3.mouse(this)[1]; 
     updateHandlerPosition("#gHandlerPoint_id_"+i, dragIconX, dragIconY); 
     updateHandlerPosition("#gHandlerPoint_id_1", (barStartWidth), (barHeight/2)); 

     var x = d3.transform(d3.select(".gContainer").attr("transform")).translate[0]; 
     var y = d3.transform(d3.select(".gContainer").attr("transform")).translate[1]; 

     d3.select(".gContainer").attr("transform", function(d,i){ 
       y = y + dragIconY; 
       return "translate(" + [ x , y] + ")" 
     }) 

     console.log(height, barHeight, barHeight - Number(dragIconY)); 
     d3.select(".Bar").attr("height", barHeight - Number(dragIconY)); 
     } 
     else if (i==1) // circle on the right side of the bar 
     { 
     oldMouseX = dragIconX; 
     dragIconX = d3.mouse(this)[0]+dragIconX; 
     barWidth = dragIconX; 
     updateHandlerPosition("#gHandlerPoint_id_"+i, dragIconX, dragIconY); 
     updateHandlerPosition("#gHandlerPoint_id_0", (barWidth/2), 0); 
     updateHandlerPosition("#gHandlerPoint_id_2", (barWidth/2), -20); 
     d3.select(".handlerLine").attr("x1",(barWidth/2)).attr("x2", (barWidth/2)); 
     d3.select(".Bar").attr("width", Math.abs(dragIconX)); 
     } 
     else if(i==3) //circle on very top 
     { 

      // code for rotation should come here. 

     } 
    } 

リンク:http://jsfiddle.net/Q5Jag/2103/

私は回転のために第三円(最上部の円)を置きます。しかし、どのように回転を修正するか分かりません。非常に上に円をドラッグすると、長方形が回転します。私はまた、それが回転されたときにそれに応じて円のサイズを変更できるようにしたい。

答えて

1

矩形の中心を基準に回転を計算できます。とv2のベクトルは、矩形の中心から回転ハンドルまでのベクトルとして、矩形の中心から回転ハンドルまでのベクトルとして、回転の後のベクトルとしてv1をベクトルとみなしてください。それの背後にある数学を知るにはhereを読んでください。

// old vector 
v1 = {}; 
v1.x = oldMouseX-gCenterX; 
v1.y = oldMouseY-gCenterY; 

// new vector 
v2 = {}; 
v2.x = dragHandleX-gCenterX; 
v2.y = dragHandleY-gCenterY; 

angle = Math.atan2(v2.y,v2.x) - Math.atan2(v1.y,v1.x); 

ここ

  • gCenterXgCenterY矩形の中心の座標は、
  • oldMouseXoldMouseYは、マウスポインタの座標でれる前回転
  • dragHandleXdragHandleYは後に、マウスポインタの座標でありますローテーション
ここ

完全なコードです: http://jsfiddle.net/Q5Jag/2109/ (しかし、あなたは回転とサイズ変更を混ぜた場合、それは失敗します)

関連する問題